From 352100e49c3e0119ec4db893f37f505bc52a9b70 Mon Sep 17 00:00:00 2001 From: Teswa Date: Thu, 30 Mar 2023 13:41:34 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 198 ++++--- dist/april-fools.js | 50 +- dist/april-fools.min.js | 2 +- package-lock.json | 1 + package.json | 1 + settings.compact.js | 296 +++++------ settings.example.js | 839 +++++++++++++++--------------- src/common.ts | 14 + src/data/stupid_title_variants.ts | 57 ++ src/html.d.ts | 6 +- src/html/button.html | 2 +- src/html/styles.html | 54 +- src/html/window.html | 30 +- src/joke.ts | 128 +++-- src/joker.ts | 467 +++++++++-------- src/jokes/carnival.ts | 89 ++-- src/jokes/crazy_letters.ts | 46 +- src/jokes/cursor.ts | 502 +++++++++--------- src/jokes/humanitarian_hell.ts | 49 +- src/jokes/letter_chaos.ts | 95 ++-- src/jokes/mirror.ts | 36 +- src/jokes/shake.ts | 122 ++--- src/jokes/stupid_title.ts | 494 +++++++++--------- src/main.ts | 30 +- src/ui.ts | 88 ++-- tsconfig.json | 9 +- webpack.config.js | 28 +- 27 files changed, 1997 insertions(+), 1736 deletions(-) create mode 100644 src/common.ts create mode 100644 src/data/stupid_title_variants.ts diff --git a/README.md b/README.md index 7ac2ee3..dcd1655 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,81 @@ # Бибилотека первоапрельских розыгрышей для форумов MyBB Базовое использование: + ```html ``` --- + ## Полный список шуток -* `shake` — **Форумо-трясение**. Страница форума начинает трястись. -* `mirror` — **Зеркало**. Элементы форума отражаются... По крайней мере, пытаются. -* `carnival` — **Карнавал**. Аватарки приобретают интересные цвета. -* `humanitarian_hell` — **Ад гуманитария**. Все "тся" заменяются на "ться", а все "ться" на "тся". -* `crazy_letters` — **Мама, Я сОшЛа С уМа!** иМеНа ЗаБоРчИкОм -* `letter_chaos` — **Буквенный хаос**. Все буквы в словах, кроме первой и последней, перемешены. -* `cursor` — **Красивые курсоры**. Эффекты, следующие за курсором. +- `shake` — **Форумо-трясение**. Страница форума начинает трястись. +- `mirror` — **Зеркало**. Элементы форума отражаются... По крайней мере, пытаются. +- `carnival` — **Карнавал**. Аватарки приобретают интересные цвета. +- `humanitarian_hell` — **Ад гуманитария**. Все "тся" заменяются на "ться", а все "ться" на "тся". +- `crazy_letters` — **Мама, Я сОшЛа С уМа!** иМеНа ЗаБоРчИкОм +- `letter_chaos` — **Буквенный хаос**. Все буквы в словах, кроме первой и последней, перемешены. +- `cursor` — **Красивые курсоры**. Эффекты, следующие за курсором. +- `stupid_title` — **Глупые статусы**. Каждому пользователю даётся новый глупый статус. --- + +## Тестирование шуток + +Что бы проверить работу системы, вы можете включить "режим тестера". Для этого добавьте свой `UserID` в настройку `core.testers`: + +```js +window.AprilJokes.settings = { + // ... + core: { + testers: [ 2, 3, 1186 ], + }, + // ... +}; +``` + +--- + ## Настройка шуток Настройка шуток происходит при присвоении объекта `window.AprilJokes.settings`. Это присвоедние должно произойти **после** загрузки скрипта. Для всех шуток определны 2 общих поля: + ```js window.AprilJokes.settings = { - // ... - example: { - /** - * Активность шутки. - * Установите это значение `false`, что бы отключить шутку. - * Если `true`, то шутка будет обработана как обычно. - */ - enabled: true, + // ... + example: { + /** + * Активность шутки. + * Установите это значение `false`, что бы отключить шутку. + * Если `true`, то шутка будет обработана как обычно. + */ + enabled: true, - /** - * Вероятность срабатывания в процентах. - * Если установлено значение `100`, шутка будет срабатывать всегда. - * Если установлено значение `0`, шутка никогда не сработает. - * Лучше отключать шутку, используя enabled = false! - */ - chance: 20, - }, - // ... + /** + * Вероятность срабатывания в процентах. + * Если установлено значение `100`, шутка будет срабатывать всегда. + * Если установлено значение `0`, шутка никогда не сработает. + * Лучше отключать шутку, используя enabled = false! + */ + chance: 20, + }, + // ... }; ``` -Полный список настроек с объяснениями вы можете посмотреть в файле [`settings.example.js`](./settings.example.js). Также представлен файл [`settings.compact.js`](./settings.compact.js), который также содержит все настройки, но без коментариев. +Полный список настроек с объяснениями вы можете посмотреть в файле [`settings.example.js`](./settings.example.js). Также представлен файл [`settings.compact.js`](./settings.compact.js), который также содержит все настройки, но без коментариев. При этом, объективно, вставлять весь этот код в HTML-начало может быть "немного" неудобно, поэтому вы можете скачать код (кнопка "Raw" над файлом), изменить его, и загрузить в файлы форума, подключив скрипт таким образом: @@ -65,7 +86,7 @@ window.AprilJokes.settings = { ``` -Заметьте, что во всех примерах приведены значения настроек по умолчанию. Вы *можете* удалять строки, значения по умолчанию которых вас устраивают. +Заметьте, что во всех примерах приведены значения настроек по умолчанию. Вы _можете_ удалять строки, значения по умолчанию которых вас устраивают. Если вас интерсует только несколько шуток, вы можете использовать метод `disableAll()`, что бы выключить выполнение всех шуток, а потом включать отдельные шутки через установку настройки `enabled`: @@ -73,20 +94,21 @@ window.AprilJokes.settings = { window.AprilJokes.disableAll(); window.AprilJokes.settings = { + // ... + example: { + enabled: true, // ... - example: { - enabled: true, - // ... - }, - // ... + }, + // ... }; ``` -Обратите внимание, что метод `disableAll()` должен быть вызван *до* установки настроек `settings`, иначе заданные значения `enabled` будут сброшены. +Обратите внимание, что метод `disableAll()` должен быть вызван _до_ установки настроек `settings`, иначе заданные значения `enabled` будут сброшены. Так же есть метод `window.AprilJokes.enableAll()`, который включает все шутки, в том числе отключённые по умолчанию. --- + ### Настройка `shake` (Форумо-трясение) Тряска элементов происходит путём изменения перечисленных направлений `margin` на значение ±`force` от стандартного значения. @@ -94,61 +116,117 @@ window.AprilJokes.settings = { > **Важно**: эта шутка может вызвать дискомфорт у пользователей. Настоятельно рекомендуется оставить вероятность срабатывания шутки (`chance`) очень низкой, что бы у пользователей была возможность избавиться от шутки простым обновлением страницы! Вариант отключить шутку (`enabled: false`) тоже вариант. --- + ### Настройка `mirror` (Зеркало) -Элементы форума отражаются по весьма специфичному алгоритму... И из-за этого, шутка может работать *очень* плохо на некоторых дизайнах, поэтому данная шутка по умолчанию **отключена** + +Элементы форума отражаются по весьма специфичному алгоритму... И из-за этого, шутка может работать _очень_ плохо на некоторых дизайнах, поэтому данная шутка по умолчанию **отключена** Для того, что бы попробовать, сработает ли шутка для вашего дизайна, используйте в консоли разработчика: + ```js window.AprilJokes.start("mirror", true); ``` -Так же можете [посмотреть](./src/jokes/mirror.ts#L16) на метод `MirrorJoke.start`, что бы узнать как именно проиходит отражение. +Так же можете [посмотреть](./src/jokes/mirror.ts#L16) на метод `MirrorJoke.start`, что бы узнать как именно проиходит отражение. --- + ### Настройка `cursor` (Красивые курсоры) + Используются курсоры, предложенные в библотеке `tholman/cursor-effects` от Tim Holman ([Github](https://github.com/tholman/cursor-effects), [сайт](https://tholman.com/cursor-effects/)). Код предусматривает, что одновременно активировано не более 1 курсора из этой библиотеки. Так же для каждого курсора установлен свой шанс срабатывания, однако из-за необходимости активации строго одного эффекта, предусмотрено использование весового коэффициента `weight`: если говорить просто, то чем больше это значение, то тем больше шанс срабатывания эффекта относительно других эффектов. Так же для каждого эффекта определена настройка `enabled`, позволяющая отключить эффекты, и метод `disableAll` для отключения эффектов: + ```js window.AprilJokes.jokes.cursor.disableAll(); ``` --- + +### Настройка `stupid_title` (Глупые статусы) + +> **Важно**: этот блок может быть чрезвычайно капризым из-за особенностей хранения данных, особенно блок `variants`. Изменяя его, строго следуйте этой инструкции, иначе скрипт может перестать работать ожидаемым образом. + +Данная шутка генерирет статус из случайных слов. За счёт использования псевдослучайного генератора, хеширования и привязки к времени UTC, ожидается что все пользователи одновременно будут видеть один и тот же статус для каждого пользователя, при этом он меняется каждые `change_frequency` минут. Установите это значение равным `0`, что бы статус генерировался при каждом обновлении страницы. + +Для настройки списка слов используется функция `BuildStupdiTitleVariant`, которая преобразует список слов во внутренний формат скрипта. Настоятельно рекомендуется использовать именно её, а не записывать параметры напрямую: + +```js +window.AprilJokes.settings = { + // ... + stupid_title: { + // ... + variants: { + adj: { + ...window.AprilJokes.settings.stupid_title.variants.adj, + ...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"), + ...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"), + }, + noun: { ...window.AprilJokes.settings.stupid_title.variants.noun }, + verb: { ...window.AprilJokes.settings.stupid_title.variants.verb }, + place: { ...window.AprilJokes.settings.stupid_title.variants.place }, + adv: { ...window.AprilJokes.settings.stupid_title.variants.adv }, + p: { ...window.AprilJokes.settings.stupid_title.variants.p }, + }, + // ... + }, + // ... +}; +``` + +Обратите внимание на конструкции вида `{ ...something }` — эта конструкция позволяет перенести все поля нескольких старых объектов в один новый. При этом, если в двух объединяемых объектах есть совпадающие значения, то будет сохранено последнее. + +Говоря проще: добовляйте ваши настройки _после_ строки вида `...window.AprilJokes.settings.stupid_title.variants.adj`, что бы ваши настройки не были перезаписаны. + +Метод `BuildStupdiTitleVariant` принимает 2 аргумента: + +- `gender` — определённый род для генерации. Используйте `true` для мужского рода, `false` для женского и `null`, если добавляемые варианты могут использоваться в обоих случаях. +- `words` — строка, со списоком вариантов через запятую. В качестве вариантов могут быть слова из русских или английских букв, пробелов или дефисов, то есть можно использовать `"..., почему-то и зачем-то , ..."` и `почему-то и зачем-то` будет воспринят как один вариант. Также варианты можно модифицировать, добавив один или несколько модификаторов: + - `!` отключает использование слова. Этим модификатором можно отключать слова из списка по умолчанию (см `!грубый` в примере выше). + - `%` помечает слово как редкое. Шанс его использования понижается в 2 раза. + - `^` помечает слово как частое. Шанс его использования повышается в 2 раза. + - `$` помечает слово как грубое. Такие слова не будут отображаться, если в настройках отключена соответсвующая настройка `rude`. + +Полный список слов по умолчанию вы можете посмотреть [в Google Таблице](https://docs.google.com/spreadsheets/d/1MJIfENqy7a9DczRj38c34t27ZQtEmBSi/edit?usp=sharing&ouid=112152128398997742033&rtpof=true&sd=true) или [в исходном файле](./src/data/stupid_title_variants.ts). + +--- + ## Разработка дополнений Использование для тестирования: + ```html ``` diff --git a/dist/april-fools.js b/dist/april-fools.js index d806ee1..9de4c59 100644 --- a/dist/april-fools.js +++ b/dist/april-fools.js @@ -16,7 +16,7 @@ \******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/button.html?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"\\n\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/button.html?"); /***/ }), @@ -26,7 +26,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/styles.html?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"\\n\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/styles.html?"); /***/ }), @@ -36,7 +36,27 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"
\\n
\\n\\n \\n
\\n\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/window.html?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n// Module\nvar code = \"
\\n
\\n\\n \\n
\\n\\n\";\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (code);\n\n//# sourceURL=webpack://mybb-april-fools/./src/html/window.html?"); + +/***/ }), + +/***/ "./src/common.ts": +/*!***********************!*\ + !*** ./src/common.ts ***! + \***********************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getTextNodes\": () => (/* binding */ getTextNodes)\n/* harmony export */ });\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);\n\n/**\n * Получение всех элементов, являющимися TextNode.\n * Используется некоторыми шутками для уменьшения влияния на существующее DOM-дерево.\n */\nfunction getTextNodes(root) {\n return jquery__WEBPACK_IMPORTED_MODULE_0___default()(root)\n .find(\"*\")\n .contents()\n .filter((_, node) => node.nodeType === Node.TEXT_NODE);\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/common.ts?"); + +/***/ }), + +/***/ "./src/data/stupid_title_variants.ts": +/*!*******************************************!*\ + !*** ./src/data/stupid_title_variants.ts ***! + \*******************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"StupidTitleDefaultVariants\": () => (/* binding */ StupidTitleDefaultVariants)\n/* harmony export */ });\n/* harmony import */ var _jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../jokes/stupid_title */ \"./src/jokes/stupid_title.ts\");\n\nfunction StupidTitleDefaultVariants(vars) {\n vars.adj = Object.assign(Object.assign(Object.assign({}, (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(true, \"адекватный,$адский,активный,алчный,%ангельский,банальный,безнадёжный,$бесполезный,былой,верный,виртуальный,вкусный,воспитанный,выгодный,выходной,гигантский,$глупый,гордый,грамотный,громадный,грубый,далекий,двуличный,деятельный,доброжелательный,$жалкий,жёсткий,жестокий,$жирный,заинтересованный,запасной,застенчивый,знакомый,иностранный,истинный,конструктивный,креативный,ласковый,любимый,мелочный,^мирный,мстительный,небесный,невозможный,независимый,низкий,нужный,объективный,обыкновенный,опрятный,^оригинальный,особенный,острый,откровенный,открытый,пестрый,повседневный,подземный,пожилой,показательный,последний,посторонний,провинциальный,пышный,робкий,родной,самовлюблённый,северный,седой,семейный,серьёзный,сногсшибательный,^солнечный,спокойный,суровый,терпеливый,уверенный в себе,ударный,^удачливый,формальный,хладнокровный,целый,чистый,чрезвычайный,чужой,южный\")), (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(false, \"адекватная,$адская,активная,алчная,%ангельская,банальная,безнадёжная,$бесполезная,былая,верная,виртуальная,вкусная,воспитанная,выгодная,выходная,гигантская,$глупая,гордая,грамотная,громадная,грубая,далекая,двуличная,деятельная,доброжелательная,$жалкая,жёсткая,жестокая,$жирная,заинтересованная,запасная,застенчивая,знакомая,иностранная,истинная,конструктивная,креативная,ласковая,любимая,мелочная,^мирная,мстительная,небесная,невозможная,независимая,низкая,нужная,объективная,обыкновенная,опрятная,^оригинальная,особенная,острая,откровенная,открытая,пестрая,повседневная,подземная,пожилая,показательная,последняя,посторонняя,провинциальная,пышная,робкая,родная,самовлюблённая,северная,седая,семейная,серьезная,сногсшибательная,^солнечная,спокаяная,суровая,терпеливая,уверенная в себе,ударная,^удачливая,формальная,хладнокровная,целая,чистая,чрезвычайная,чужая,южная\")), vars.adj);\n vars.noun = Object.assign(Object.assign(Object.assign({}, (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(true, \"актёр,$балбес,бард,басурманин,борец,бродяга,бруталище,волк,дворф,%дед,%дедушка,джентльмен,диван,динозавр,дракон,ёж,%ёжик,жук,зайц,$злоумышленник,зомби,карасик,кентавр,кит,кот,кролик,кулак,лев,ледник,лесоруб,%мальчег,мальчик,манекен,массажист,мачо,монах,монстр,наследник,ниндзя,носорог,одиночка,организм,орёл,отец,принц,проказник,пузырь,$раб,рыцарь,спортсмен,сурикат,сын,%сынок,тигр,товарищ,хоббит,эльф\")), (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(false, \"актриса,акула,$бабка,бабочка,%бабушка,бактерия,белочка,бусинка,валькирия,$ведьма,волторна,волчица,горгулья,дворфиха,девочка,деревяшка,детка,%деффачка,%дочка,дочь,заноза,$злоумышленница,знаменитость,каруселька,килька,конфетка,косточка,кошка,красотка,крышка,леди,$личинка,львица,мать,машина,милашка,монашка,мышь,наследница,орлица,панда,пиранья,принцесса,простуда,$рабыня,русалочка,рыбка,рыбка,скамеечка,спортсменка,тигрица,травка,черепашка,чертовка,эльфийка\")), vars.noun);\n vars.verb = Object.assign(Object.assign(Object.assign(Object.assign({}, (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(null, \"бежит,берёт и делает,болеет,встаёт,говорит,думает,забывает,замирает,заходит,идёт,%имеет план и придерживается его,ловит,меняется,молчит,нарушает,оглядывается,орёт,освобождает,отвечает,отказаться куда-то идти,отказывается,отказывается вставать,отказывается что-то делать,оформляет,плывёт,поглядывает,поздравляет,поздравляет,получает,прибывает,приказывает,просыпается,прощает,работает,радуется,скрывается,снимает,снимает,снимается в сериале,снимается в фильме,собирается,соединяет,спрашивает,тянет,указывает,учит,читает,что-то скрывает,чувствует опасность,шепчет\")), (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(true, \"взял и сделал,додумался,женился,женится,заработался,не спал,не успел,обиделся,познал дзен,присел,проснулся,скрылся,смог,успел\")), (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(false, \"взяла и сделала,выходит замуж,вышла замуж,додумалась,заработалась,не спала,не успела,обиделась,познала дзен,присела,проснулась,скрылась,смогла,успела\")), vars.verb);\n vars.place = Object.assign(Object.assign({}, (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(null, \"в джунглях,в квартире,в космосе,в лесу,в очереди,в пустыне,в театре,%в тёплой и уютной квартире,в филармонии,где-то,на заснеженной вершине,на конференции,на пляже,на форуме,под водой,под дождём,%под проливным дождём\")), vars.place);\n vars.adv = Object.assign(Object.assign({}, (0,_jokes_stupid_title__WEBPACK_IMPORTED_MODULE_0__.BuildStupdiTitleVariant)(null, \"безрассудно,быстро,внезапно,вновь,$грубо,грустно,медленно,%молниеносно,немедленно,опять,осмысленно,позже,предсказуемо,расчётливо,регулярно,счастливо,уже,уныло\")), vars.adv);\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/data/stupid_title_variants.ts?"); /***/ }), @@ -46,7 +66,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Joke\": () => (/* binding */ Joke),\n/* harmony export */ \"StopableJoke\": () => (/* binding */ StopableJoke)\n/* harmony export */ });\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * Объект, описывающий шутку\n */\nvar Joke = /** @class */ (function () {\n function Joke() {\n }\n /**\n * Проверка вероятности\n *\n * @param {number} chance Вероятность срабатывания\n * @returns {boolean} Флаг срабатывания (true - сработало)\n */\n Joke.prototype.check = function (chance) {\n return Math.random() < 0.01 * chance;\n };\n /**\n * Разблокировать шутку\n */\n Joke.prototype.enable = function () {\n this.settings.enabled = true;\n };\n /**\n * Заблокировать шутку\n */\n Joke.prototype.disable = function () {\n this.settings.enabled = false;\n };\n /**\n * Переключить блокировку шутки\n * @param value Новое значение\n */\n Joke.prototype.toggle = function (value) {\n if (value === void 0) { value = null; }\n this.settings.enabled = (value === null) ? !this.settings.enabled : value;\n };\n return Joke;\n}());\n\n/**\n * Объект, описывающий шутку, которая может быть остановлена\n */\nvar StopableJoke = /** @class */ (function (_super) {\n __extends(StopableJoke, _super);\n function StopableJoke() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return StopableJoke;\n}(Joke));\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/joke.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Joke\": () => (/* binding */ Joke),\n/* harmony export */ \"StopableJoke\": () => (/* binding */ StopableJoke)\n/* harmony export */ });\n/**\n * Объект, описывающий шутку\n */\nclass Joke {\n /**\n * Проверка вероятности\n *\n * @param {number} chance Вероятность срабатывания\n * @returns {boolean} Флаг срабатывания (true - сработало)\n */\n check(chance) {\n return Math.random() < 0.01 * chance;\n }\n /**\n * Разблокировать шутку\n */\n enable() {\n this.settings.enabled = true;\n }\n /**\n * Заблокировать шутку\n */\n disable() {\n this.settings.enabled = false;\n }\n /**\n * Переключить блокировку шутки\n * @param value Новое значение\n */\n toggle(value = null) {\n this.settings.enabled = value === null ? !this.settings.enabled : value;\n }\n}\n/**\n * Объект, описывающий шутку, которая может быть остановлена\n */\nclass StopableJoke extends Joke {\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/joke.ts?"); /***/ }), @@ -56,7 +76,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \**********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JokerClass\": () => (/* binding */ JokerClass)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./joke */ \"./src/joke.ts\");\n/* harmony import */ var _ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ui */ \"./src/ui.ts\");\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\n\n\n/**\n * Блок обработки перво-апрельских шуток\n *\n * @author Kozhilya\n */\nvar JokerClass = /** @class */ (function () {\n function JokerClass() {\n this.ui = new _ui__WEBPACK_IMPORTED_MODULE_1__.JokerUI(this);\n /**\n * Общие настройки системы\n */\n this.core_settings = new CoreSettings;\n /**\n * Перечисление всех шуток\n */\n this.jokes = {};\n }\n /**\n * Проверка вероятности\n *\n * @param {number} chance Вероятность срабатывания\n * @returns {boolean} Флаг срабатывания (true - сработало)\n */\n JokerClass.prototype.check = function (chance) {\n return Math.random() < 0.01 * chance;\n };\n /**\n * Добавление шутки\n *\n * @param joke Объект шутки\n */\n JokerClass.prototype.add = function (joke) {\n this.jokes[joke.id] = joke;\n };\n /**\n * Регистрация новой шутки\n *\n * @param id Идентификатор шутки\n * @param handler Метод, выполняющий шутку\n * @param settings Объект настроек шутки\n */\n JokerClass.prototype.addCustom = function (id, handler, settings) {\n if (settings === void 0) { settings = null; }\n var joke = new /** @class */ (function (_super) {\n __extends(class_1, _super);\n function class_1() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = id;\n _this.title = 'Пользовательская шутка';\n _this.description = 'Для шутки не определено описание';\n _this.settings = { chance: 10, enabled: true };\n return _this;\n }\n class_1.prototype.start = function () {\n handler.call(this, this.settings);\n };\n return class_1;\n }(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n Object.assign(joke.settings, settings !== null && settings !== void 0 ? settings : {});\n this.add(joke);\n return joke;\n };\n Object.defineProperty(JokerClass.prototype, \"settings\", {\n /**\n * Получение полного списка настроек\n */\n get: function () {\n var result = {};\n result['core'] = this.core_settings;\n for (var _i = 0, _a = Object.entries(this.jokes); _i < _a.length; _i++) {\n var entries = _a[_i];\n var id = entries[0];\n var joke = entries[1];\n result[id] = joke.settings;\n }\n return result;\n },\n /**\n * Запись новых настроек\n *\n * @param settings\n */\n set: function (settings) {\n for (var _i = 0, _a = Object.entries(settings); _i < _a.length; _i++) {\n var entry = _a[_i];\n var id = entry[0];\n var jokeSettings = entry[1];\n var targetSettings = (id === 'core') ? this.core_settings : this.jokes[id].settings;\n Object.assign(targetSettings, jokeSettings);\n }\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Разблокировать систему\n */\n JokerClass.prototype.enable = function () {\n this.core_settings.enabled = true;\n };\n /**\n * Заблокировать систему\n */\n JokerClass.prototype.disable = function () {\n this.core_settings.enabled = false;\n };\n /**\n * Разблокировать все шутки\n */\n JokerClass.prototype.enableAll = function () {\n for (var _i = 0, _a = Object.keys(this.jokes); _i < _a.length; _i++) {\n var key = _a[_i];\n this.jokes[key].enable();\n }\n };\n /**\n * Заблокировать все шутки\n */\n JokerClass.prototype.disableAll = function () {\n for (var _i = 0, _a = Object.keys(this.jokes); _i < _a.length; _i++) {\n var key = _a[_i];\n this.jokes[key].disable();\n }\n };\n /**\n * Переключение шутки\n */\n JokerClass.prototype.toggleJoke = function (joke_id, state) {\n var joke = this.jokes[joke_id];\n joke.settings.enabled = state;\n if (joke instanceof _joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke && !state) {\n joke.stop();\n }\n this.saveUserStates();\n };\n /**\n * Сохранение пользовательских настроек\n */\n JokerClass.prototype.saveUserStates = function () {\n var states = {};\n for (var _i = 0, _a = Object.keys(this.jokes); _i < _a.length; _i++) {\n var key = _a[_i];\n states[key] = this.jokes[key].settings.enabled;\n }\n fetch('/api.php?' + $.param({\n method: 'storage.set',\n user_id: window.UserID,\n key: 'april-fools',\n token: window.ForumAPITicket,\n value: JSON.stringify(states),\n timer: 24 * 60\n }));\n };\n /**\n * Загрузка пользовательских настроек\n */\n JokerClass.prototype.loadUserStates = function () {\n return __awaiter(this, void 0, void 0, function () {\n var response, json, data, _i, _a, key;\n return __generator(this, function (_b) {\n switch (_b.label) {\n case 0: return [4 /*yield*/, fetch('/api.php?' + $.param({\n method: 'storage.get',\n user_id: window.UserID,\n key: 'april-fools',\n }))];\n case 1:\n response = _b.sent();\n return [4 /*yield*/, response.json()];\n case 2:\n json = _b.sent();\n if (json.error) {\n return [2 /*return*/];\n }\n data = JSON.parse(json.response.storage.data['april-fools']);\n for (_i = 0, _a = Object.keys(this.jokes); _i < _a.length; _i++) {\n key = _a[_i];\n this.jokes[key].settings.enabled = data[key];\n }\n return [2 /*return*/];\n }\n });\n });\n };\n JokerClass.prototype.clearUserStates = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fetch('/api.php?' + $.param({\n method: 'storage.delete',\n user_id: window.UserID,\n key: 'april-fools',\n token: window.ForumAPITicket,\n }))];\n case 1:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n /**\n * Запуск шутки\n *\n * @param id\n * @param {boolean} forced\n */\n JokerClass.prototype.start = function (id, forced) {\n if (forced === void 0) { forced = false; }\n if (!(id in this.jokes))\n return;\n var joke = this.jokes[id];\n if (!forced && (!joke.settings.enabled || !this.check(joke.settings.chance))) {\n return;\n }\n joke.start();\n };\n /**\n * Запуск всех шуток\n */\n JokerClass.prototype.startAll = function (forced) {\n if (forced === void 0) { forced = false; }\n for (var _i = 0, _a = Object.keys(this.jokes); _i < _a.length; _i++) {\n var key = _a[_i];\n this.start(key, forced);\n }\n };\n JokerClass.prototype.regularCheck = function () {\n if (!this.core_settings.enabled) {\n return false;\n }\n if (this.core_settings.testers.indexOf(window.UserID) >= 0) {\n return true;\n }\n var today = new Date();\n var month = today.getMonth() + 1;\n var day = today.getDate();\n if (month !== 4 || day !== 1) {\n return false;\n }\n return this.check(this.core_settings.chance);\n };\n JokerClass.prototype.regularStart = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (!this.regularCheck()) {\n return [2 /*return*/];\n }\n return [4 /*yield*/, this.loadUserStates()];\n case 1:\n _a.sent();\n this.ui.show();\n this.startAll();\n return [2 /*return*/];\n }\n });\n });\n };\n return JokerClass;\n}());\n\nvar CoreSettings = /** @class */ (function () {\n function CoreSettings() {\n this.chance = 100;\n this.enabled = true;\n this.testers = [];\n }\n return CoreSettings;\n}());\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/joker.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JokerClass\": () => (/* binding */ JokerClass)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./joke */ \"./src/joke.ts\");\n/* harmony import */ var _ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ui */ \"./src/ui.ts\");\n\n\n/**\n * Блок обработки перво-апрельских шуток\n *\n * @author Kozhilya\n */\nclass JokerClass {\n constructor() {\n this.ui = new _ui__WEBPACK_IMPORTED_MODULE_1__.JokerUI(this);\n /**\n * Общие настройки системы\n */\n this.core_settings = new CoreSettings();\n /**\n * Перечисление всех шуток\n */\n this.jokes = {};\n }\n /**\n * Проверка вероятности\n *\n * @param {number} chance Вероятность срабатывания\n * @returns {boolean} Флаг срабатывания (true - сработало)\n */\n check(chance) {\n return Math.random() < 0.01 * chance;\n }\n /**\n * Добавление шутки\n *\n * @param joke Объект шутки\n */\n add(joke) {\n this.jokes[joke.id] = joke;\n }\n /**\n * Регистрация новой шутки\n *\n * @param id Идентификатор шутки\n * @param handler Метод, выполняющий шутку\n * @param settings Объект настроек шутки\n */\n addCustom(id, handler, settings = null) {\n const joke = new (class extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = id;\n this.title = \"Пользовательская шутка\";\n this.description = \"Для шутки не определено описание\";\n this.settings = { chance: 10, enabled: true };\n }\n start() {\n handler.call(this, this.settings);\n }\n })();\n Object.assign(joke.settings, settings !== null && settings !== void 0 ? settings : {});\n this.add(joke);\n return joke;\n }\n /**\n * Получение полного списка настроек\n */\n get settings() {\n const result = {};\n result[\"core\"] = this.core_settings;\n for (const entries of Object.entries(this.jokes)) {\n const id = entries[0];\n const joke = entries[1];\n result[id] = joke.settings;\n }\n return result;\n }\n /**\n * Запись новых настроек\n *\n * @param settings\n */\n set settings(settings) {\n for (const entry of Object.entries(settings)) {\n const id = entry[0];\n const jokeSettings = entry[1];\n const targetSettings = id === \"core\" ? this.core_settings : this.jokes[id].settings;\n Object.assign(targetSettings, jokeSettings);\n }\n }\n /**\n * Разблокировать систему\n */\n enable() {\n this.core_settings.enabled = true;\n }\n /**\n * Заблокировать систему\n */\n disable() {\n this.core_settings.enabled = false;\n }\n /**\n * Разблокировать все шутки\n */\n enableAll() {\n for (const key of Object.keys(this.jokes)) {\n this.jokes[key].enable();\n }\n }\n /**\n * Заблокировать все шутки\n */\n disableAll() {\n for (const key of Object.keys(this.jokes)) {\n this.jokes[key].disable();\n }\n }\n /**\n * Переключение шутки\n */\n toggleJoke(joke_id, state) {\n const joke = this.jokes[joke_id];\n joke.settings.enabled = state;\n if (joke instanceof _joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke && !state) {\n joke.stop();\n }\n this.saveUserStates();\n }\n /**\n * Сохранение пользовательских настроек\n */\n saveUserStates() {\n const states = {};\n for (const key of Object.keys(this.jokes)) {\n states[key] = this.jokes[key].settings.enabled;\n }\n fetch(\"/api.php?\" +\n $.param({\n method: \"storage.set\",\n user_id: window.UserID,\n key: \"april-fools\",\n token: window.ForumAPITicket,\n value: JSON.stringify(states),\n timer: 24 * 60,\n }));\n }\n /**\n * Загрузка пользовательских настроек\n */\n async loadUserStates() {\n const response = await fetch(\"/api.php?\" +\n $.param({\n method: \"storage.get\",\n user_id: window.UserID,\n key: \"april-fools\",\n }));\n const json = await response.json();\n if (json.error) {\n return;\n }\n const data = JSON.parse(json.response.storage.data[\"april-fools\"]);\n for (const key of Object.keys(this.jokes)) {\n this.jokes[key].settings.enabled = data[key];\n }\n }\n async clearUserStates() {\n await fetch(\"/api.php?\" +\n $.param({\n method: \"storage.delete\",\n user_id: window.UserID,\n key: \"april-fools\",\n token: window.ForumAPITicket,\n }));\n return;\n }\n /**\n * Запуск шутки\n *\n * @param id\n * @param {boolean} forced\n */\n start(id, forced = false) {\n if (!(id in this.jokes))\n return;\n const joke = this.jokes[id];\n if (!forced &&\n (!joke.settings.enabled || !this.check(joke.settings.chance))) {\n return;\n }\n joke.start();\n }\n /**\n * Запуск всех шуток\n */\n startAll(forced = false) {\n for (const key of Object.keys(this.jokes)) {\n this.start(key, forced);\n }\n }\n regularCheck() {\n if (!this.core_settings.enabled) {\n return false;\n }\n if (this.core_settings.testers.indexOf(window.UserID) >= 0) {\n return true;\n }\n const today = new Date();\n const month = today.getMonth() + 1;\n const day = today.getDate();\n if (month !== 4 || day !== 1) {\n return false;\n }\n return this.check(this.core_settings.chance);\n }\n async regularStart() {\n if (!this.regularCheck()) {\n return;\n }\n await this.loadUserStates();\n this.ui.show();\n this.startAll();\n }\n}\nclass CoreSettings {\n constructor() {\n this.chance = 100;\n this.enabled = true;\n this.testers = [];\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/joker.ts?"); /***/ }), @@ -66,7 +86,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*******************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CarnivalJoke\": () => (/* binding */ CarnivalJoke),\n/* harmony export */ \"CarnivalJokeSettings\": () => (/* binding */ CarnivalJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n/**\n * **Карнавал**\n *\n * Аватарки приобретают интересные цвета\n *\n * @author Kozhilya\n */\nvar CarnivalJoke = /** @class */ (function (_super) {\n __extends(CarnivalJoke, _super);\n function CarnivalJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'carnival';\n _this.title = 'Карнавал';\n _this.description = 'Аватарки приобретают интересные цвета';\n _this.settings = new CarnivalJokeSettings;\n return _this;\n }\n CarnivalJoke.prototype.start = function () {\n var _this = this;\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).each(function (_, elem) {\n var filters = [];\n for (var _i = 0, _a = Object.entries(_this.settings.variants); _i < _a.length; _i++) {\n var entry = _a[_i];\n if (!_this.check(_this.settings.variant_chance)) {\n continue;\n }\n filters.push(entry[0].replace('{0}', Math.round(Math.random() * entry[1]).toString()));\n }\n if (filters.length > 0) {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css({ 'filter': filters.join(' ') });\n }\n });\n };\n return CarnivalJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar CarnivalJokeSettings = /** @class */ (function () {\n function CarnivalJokeSettings() {\n this.enabled = true;\n this.chance = 30;\n /**\n * Селектор всех элементов, которые будут перекрашены\n */\n this.selector = 'img[src*=\"/avatars/\"]';\n /**\n * Вероятность применения некоторого фильтра\n */\n this.variant_chance = 20;\n /**\n * Список фильтров и диапозона случайных параметров\n */\n this.variants = {\n 'sepia({0}%)': 100,\n 'saturate({0}%)': 100,\n 'hue-rotate({0}deg)': 360,\n 'invert({0}%)': 100,\n };\n }\n return CarnivalJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/carnival.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CarnivalJoke\": () => (/* binding */ CarnivalJoke),\n/* harmony export */ \"CarnivalJokeSettings\": () => (/* binding */ CarnivalJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n\n\n/**\n * **Карнавал**\n *\n * Аватарки приобретают интересные цвета\n *\n * @author Kozhilya\n */\nclass CarnivalJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"carnival\";\n this.title = \"Карнавал\";\n this.description = \"Аватарки приобретают интересные цвета\";\n this.settings = new CarnivalJokeSettings();\n }\n start() {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).each((_, elem) => {\n const filters = [];\n for (const entry of Object.entries(this.settings.variants)) {\n if (!this.check(this.settings.variant_chance)) {\n continue;\n }\n filters.push(entry[0].replace(\"{0}\", Math.round(Math.random() * entry[1]).toString()));\n }\n if (filters.length > 0) {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css({ filter: filters.join(\" \") });\n }\n });\n }\n}\nclass CarnivalJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 30;\n /**\n * Селектор всех элементов, которые будут перекрашены\n */\n this.selector = 'img[src*=\"/avatars/\"]';\n /**\n * Вероятность применения некоторого фильтра\n */\n this.variant_chance = 20;\n /**\n * Список фильтров и диапозона случайных параметров\n */\n this.variants = {\n \"sepia({0}%)\": 100,\n \"saturate({0}%)\": 100,\n \"hue-rotate({0}deg)\": 360,\n \"invert({0}%)\": 100,\n };\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/carnival.ts?"); /***/ }), @@ -76,7 +96,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CrazyLettersJoke\": () => (/* binding */ CrazyLettersJoke),\n/* harmony export */ \"CrazyLettersJokeSettings\": () => (/* binding */ CrazyLettersJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n/**\n * **Мама, Я сОшЛа С уМа!**\n *\n * иМеНа ЗаБоРчИкОм\n *\n * @author Kozhilya\n */\nvar CrazyLettersJoke = /** @class */ (function (_super) {\n __extends(CrazyLettersJoke, _super);\n function CrazyLettersJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'crazy_letters';\n _this.title = 'Мама, Я сОшЛа С уМа!';\n _this.description = 'иМеНа ЗаБоРчИкОм';\n _this.settings = new CrazyLettersJokeSettings;\n return _this;\n }\n CrazyLettersJoke.prototype.start = function () {\n var _this = this;\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).each(function (_, elem) {\n var text = jquery__WEBPACK_IMPORTED_MODULE_1___default()(_this).text();\n var result = '';\n for (var i = 0; i < text.length; i++) {\n result += text[i][(i % 2) ? 'toLowerCase' : 'toUpperCase']();\n }\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(_this).text(result);\n });\n };\n return CrazyLettersJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar CrazyLettersJokeSettings = /** @class */ (function () {\n function CrazyLettersJokeSettings() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = '.pa-author a';\n }\n return CrazyLettersJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/crazy_letters.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CrazyLettersJoke\": () => (/* binding */ CrazyLettersJoke),\n/* harmony export */ \"CrazyLettersJokeSettings\": () => (/* binding */ CrazyLettersJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n\n\n/**\n * **Мама, Я сОшЛа С уМа!**\n *\n * иМеНа ЗаБоРчИкОм\n *\n * @author Kozhilya\n */\nclass CrazyLettersJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"crazy_letters\";\n this.title = \"Мама, Я сОшЛа С уМа!\";\n this.description = \"иМеНа ЗаБоРчИкОм\";\n this.settings = new CrazyLettersJokeSettings();\n }\n start() {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).each((_, elem) => {\n let text = jquery__WEBPACK_IMPORTED_MODULE_1___default()(this).text();\n let result = \"\";\n for (let i = 0; i < text.length; i++) {\n result += text[i][i % 2 ? \"toLowerCase\" : \"toUpperCase\"]();\n }\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this).text(result);\n });\n }\n}\nclass CrazyLettersJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = \".pa-author a\";\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/crazy_letters.ts?"); /***/ }), @@ -86,7 +106,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CursorEffectsJoke\": () => (/* binding */ CursorEffectsJoke),\n/* harmony export */ \"CursorEffectsJokeSettings\": () => (/* binding */ CursorEffectsJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n// import * as cursor_effects from \"cursor-effects\";\nvar cursor_effects = __webpack_require__(/*! cursor-effects */ \"./node_modules/cursor-effects/dist/cjs.cjs\");\n/**\n * **Красивый курсор**\n *\n * Эффекты, следующие за курсором\n *\n * @author Tim Holman\n * @link https://tholman.com/cursor-effects/\n */\nvar CursorEffectsJoke = /** @class */ (function (_super) {\n __extends(CursorEffectsJoke, _super);\n function CursorEffectsJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'cursor_effects';\n _this.title = 'Красивый курсор';\n _this.description = 'Эффекты, следующие за курсором';\n _this.settings = new CursorEffectsJokeSettings;\n return _this;\n }\n /**\n * Разблокировать все варианты курсоров\n */\n CursorEffectsJoke.prototype.enableAll = function () {\n for (var _i = 0, _a = Object.keys(this.settings.effects); _i < _a.length; _i++) {\n var key = _a[_i];\n this.settings.effects[key].enabled = true;\n }\n };\n /**\n * Заблокировать все варианты курсоров\n */\n CursorEffectsJoke.prototype.disableAll = function () {\n for (var _i = 0, _a = Object.keys(this.settings.effects); _i < _a.length; _i++) {\n var key = _a[_i];\n this.settings.effects[key].enabled = false;\n }\n };\n CursorEffectsJoke.prototype.weight = function (effect) {\n var s = this.settings.effects[effect];\n return s.enabled ? s.weight : 0;\n };\n CursorEffectsJoke.prototype.getRandomEffect = function () {\n var _this = this;\n var elements = Object.values(CursorEffectsEnum).map(function (e) { return e; });\n var totalWeight = elements.reduce(function (sum, element) { return sum + _this.weight(element); }, 0);\n var randomWeight = Math.random() * totalWeight;\n var currentWeight = 0;\n for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {\n var element = elements_1[_i];\n currentWeight += this.weight(element);\n if (randomWeight <= currentWeight) {\n return element;\n }\n }\n throw new Error(\"Тебя быть тут не должно...\");\n };\n CursorEffectsJoke.prototype.start = function () {\n var effect = this.getRandomEffect();\n var settings = this.settings.effects[effect];\n this.active_cursor_effect = resolveCursorEffectsEnum(effect, settings);\n };\n CursorEffectsJoke.prototype.stop = function () {\n this.active_cursor_effect.destroy();\n };\n return CursorEffectsJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke));\n\nvar CursorEffectsEnum;\n(function (CursorEffectsEnum) {\n CursorEffectsEnum[\"Rainbow\"] = \"rainbow\";\n CursorEffectsEnum[\"FairyDust\"] = \"fairy_dust\";\n CursorEffectsEnum[\"SpringyEmoji\"] = \"springy_emoji\";\n CursorEffectsEnum[\"Emoji\"] = \"emoji\";\n CursorEffectsEnum[\"Ghost\"] = \"ghost\";\n CursorEffectsEnum[\"Trailing\"] = \"trailing\";\n CursorEffectsEnum[\"TextFlag\"] = \"text_flag\";\n CursorEffectsEnum[\"FollowingDot\"] = \"following_dot\";\n CursorEffectsEnum[\"Bubbles\"] = \"bubbles\";\n CursorEffectsEnum[\"Snowflake\"] = \"snowflake\";\n CursorEffectsEnum[\"Clock\"] = \"clock\";\n})(CursorEffectsEnum || (CursorEffectsEnum = {}));\nfunction resolveCursorEffectsEnum(effect, options) {\n switch (effect) {\n case CursorEffectsEnum.Rainbow:\n return cursor_effects.rainbowCursor(options);\n case CursorEffectsEnum.FairyDust:\n return cursor_effects.fairyDustCursor(options);\n case CursorEffectsEnum.SpringyEmoji:\n return cursor_effects.springyEmojiCursor(options);\n case CursorEffectsEnum.Emoji:\n return cursor_effects.emojiCursor(options);\n case CursorEffectsEnum.Ghost:\n return cursor_effects.ghostCursor(options);\n case CursorEffectsEnum.Trailing:\n return cursor_effects.trailingCursor(options);\n case CursorEffectsEnum.TextFlag:\n return cursor_effects.textFlag(options);\n case CursorEffectsEnum.FollowingDot:\n return cursor_effects.followingDotCursor(options);\n case CursorEffectsEnum.Bubbles:\n return cursor_effects.bubbleCursor(options);\n case CursorEffectsEnum.Snowflake:\n return cursor_effects.snowflakeCursor(options);\n case CursorEffectsEnum.Clock:\n return cursor_effects.clockCursor(options);\n }\n}\nvar CursorEffectsJokeSettings = /** @class */ (function () {\n function CursorEffectsJokeSettings() {\n var _a;\n this.enabled = true;\n this.chance = 100;\n this.effects = (_a = {},\n /**\n * Радужный след за курсором\n */\n _a[CursorEffectsEnum.Rainbow] = new /** @class */ (function (_super) {\n __extends(class_1, _super);\n function class_1() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Длина полосы\n */\n _this.length = 20;\n /**\n * Ширина полосы\n */\n _this.size = 3;\n /**\n * Цвета полос (сверху вниз)\n */\n _this.colors = [\n \"#9400D3\",\n \"#4B0082\",\n \"#0000FF\",\n \"#00FF00\",\n \"#FFFF00\",\n \"#FF7F00\",\n \"#FF0000\"\n ];\n return _this;\n }\n return class_1;\n }(DefaultCursorEffectsSetting)),\n /**\n * Цепочка из эмодзи \"на резинке\" под курсором\n */\n _a[CursorEffectsEnum.SpringyEmoji] = new /** @class */ (function (_super) {\n __extends(class_2, _super);\n function class_2() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Висящий эмодзи\n */\n _this.emoji = \"🤪\";\n return _this;\n }\n return class_2;\n }(DefaultCursorEffectsSetting)),\n /**\n * Падающие от курсора эмодзи\n */\n _a[CursorEffectsEnum.Emoji] = new /** @class */ (function (_super) {\n __extends(class_3, _super);\n function class_3() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Падающие эмодзи\n */\n _this.emoji = [\"🔥\", \"🐬\", \"🦆\"];\n return _this;\n }\n return class_3;\n }(DefaultCursorEffectsSetting)),\n /**\n * Падающие от курсора пылинки\n */\n _a[CursorEffectsEnum.FairyDust] = new /** @class */ (function (_super) {\n __extends(class_4, _super);\n function class_4() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Цвет пылинок\n */\n _this.colors = [\"#ff0000\", \"#00ff00\", \"#0000ff\"];\n return _this;\n }\n return class_4;\n }(DefaultCursorEffectsSetting)),\n /**\n * След \"зависших\" курсоров\n */\n _a[CursorEffectsEnum.Ghost] = new DefaultCursorEffectsSetting,\n /**\n * След курсоров \"на резинке\"\n */\n _a[CursorEffectsEnum.Trailing] = new /** @class */ (function (_super) {\n __extends(class_5, _super);\n function class_5() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Количество элементов\n */\n _this.particles = 15;\n /**\n * Скорость частиц\n */\n _this.rate = 0.4;\n /**\n * Ссылка на картинку с курсором\n * Используйте `null`, что бы использовать картинку курсора по умолчанию\n */\n _this.baseImageSrc = null;\n return _this;\n }\n return class_5;\n }(DefaultCursorEffectsSetting)),\n /**\n * Текст, развивающийся флагом от курсора\n */\n _a[CursorEffectsEnum.TextFlag] = new /** @class */ (function (_super) {\n __extends(class_6, _super);\n function class_6() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Отображаемый текст\n */\n _this.text = \"С днём смеха!\";\n /**\n * Цвет текста\n */\n _this.color = \"#000000\";\n /**\n * Шрифт текста\n */\n _this.font = \"monospace\";\n /**\n * Размер текста\n */\n _this.textSize = 12;\n /**\n * Растояние между бквами\n */\n _this.gap = 14;\n /**\n * Размер... чего-то.\n */\n _this.size = 3;\n return _this;\n }\n return class_6;\n }(DefaultCursorEffectsSetting)),\n /**\n * Точка, преследующая курсор\n */\n _a[CursorEffectsEnum.FollowingDot] = new /** @class */ (function (_super) {\n __extends(class_7, _super);\n function class_7() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Цвет догоняющей точки\n */\n _this.color = \"#323232a6\";\n return _this;\n }\n return class_7;\n }(DefaultCursorEffectsSetting)),\n /**\n * Пузырьки от курсора\n */\n _a[CursorEffectsEnum.Bubbles] = new DefaultCursorEffectsSetting,\n /**\n * Снежинки, летящие от курсора\n *\n * Отключено, потому что сейчас не зима :D\n */\n _a[CursorEffectsEnum.Snowflake] = new /** @class */ (function (_super) {\n __extends(class_8, _super);\n function class_8() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.weight = 0;\n return _this;\n }\n return class_8;\n }(DefaultCursorEffectsSetting)),\n /**\n * Циферблат вокруг курсора\n */\n _a[CursorEffectsEnum.Clock] = new /** @class */ (function (_super) {\n __extends(class_9, _super);\n function class_9() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Цвет даты\n */\n _this.dateColor = \"blue\";\n /**\n * Цвет циферблата\n */\n _this.faceColor = \"black\";\n /**\n * Цвет секундной стрелки\n */\n _this.secondsColor = \"red\";\n /**\n * Цвет минутной стрелки\n */\n _this.minutesColor = \"black\";\n /**\n * Цвет часовой стрелки\n */\n _this.hoursColor = \"black\";\n return _this;\n }\n return class_9;\n }(DefaultCursorEffectsSetting)),\n _a);\n }\n return CursorEffectsJokeSettings;\n}());\n\nvar DefaultCursorEffectsSetting = /** @class */ (function () {\n function DefaultCursorEffectsSetting() {\n /**\n * Флаг возможности срабатывания\n */\n this.enabled = true;\n /**\n * Весовой коэффициент вероятности курсора\n */\n this.weight = 50;\n }\n return DefaultCursorEffectsSetting;\n}());\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/cursor.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CursorEffectsJoke\": () => (/* binding */ CursorEffectsJoke),\n/* harmony export */ \"CursorEffectsJokeSettings\": () => (/* binding */ CursorEffectsJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n\n// import * as cursor_effects from \"cursor-effects\";\nconst cursor_effects = __webpack_require__(/*! cursor-effects */ \"./node_modules/cursor-effects/dist/cjs.cjs\");\n/**\n * **Красивый курсор**\n *\n * Эффекты, следующие за курсором\n *\n * @author Tim Holman\n * @link https://tholman.com/cursor-effects/\n */\nclass CursorEffectsJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke {\n constructor() {\n super(...arguments);\n this.id = \"cursor_effects\";\n this.title = \"Красивый курсор\";\n this.description = \"Эффекты, следующие за курсором\";\n this.settings = new CursorEffectsJokeSettings();\n }\n /**\n * Разблокировать все варианты курсоров\n */\n enableAll() {\n for (const key of Object.keys(this.settings.effects)) {\n this.settings.effects[key].enabled = true;\n }\n }\n /**\n * Заблокировать все варианты курсоров\n */\n disableAll() {\n for (const key of Object.keys(this.settings.effects)) {\n this.settings.effects[key].enabled = false;\n }\n }\n weight(effect) {\n const s = this.settings.effects[effect];\n return s.enabled ? s.weight : 0;\n }\n getRandomEffect() {\n const elements = Object.values(CursorEffectsEnum).map((e) => e);\n const totalWeight = elements.reduce((sum, element) => sum + this.weight(element), 0);\n const randomWeight = Math.random() * totalWeight;\n let currentWeight = 0;\n for (const element of elements) {\n currentWeight += this.weight(element);\n if (randomWeight <= currentWeight) {\n return element;\n }\n }\n throw new Error(\"Тебя быть тут не должно...\");\n }\n start() {\n const effect = this.getRandomEffect();\n const settings = this.settings.effects[effect];\n this.active_cursor_effect = resolveCursorEffectsEnum(effect, settings);\n }\n stop() {\n this.active_cursor_effect.destroy();\n }\n}\nvar CursorEffectsEnum;\n(function (CursorEffectsEnum) {\n CursorEffectsEnum[\"Rainbow\"] = \"rainbow\";\n CursorEffectsEnum[\"FairyDust\"] = \"fairy_dust\";\n CursorEffectsEnum[\"SpringyEmoji\"] = \"springy_emoji\";\n CursorEffectsEnum[\"Emoji\"] = \"emoji\";\n CursorEffectsEnum[\"Ghost\"] = \"ghost\";\n CursorEffectsEnum[\"Trailing\"] = \"trailing\";\n CursorEffectsEnum[\"TextFlag\"] = \"text_flag\";\n CursorEffectsEnum[\"FollowingDot\"] = \"following_dot\";\n CursorEffectsEnum[\"Bubbles\"] = \"bubbles\";\n CursorEffectsEnum[\"Snowflake\"] = \"snowflake\";\n CursorEffectsEnum[\"Clock\"] = \"clock\";\n})(CursorEffectsEnum || (CursorEffectsEnum = {}));\nfunction resolveCursorEffectsEnum(effect, options) {\n switch (effect) {\n case CursorEffectsEnum.Rainbow:\n return cursor_effects.rainbowCursor(options);\n case CursorEffectsEnum.FairyDust:\n return cursor_effects.fairyDustCursor(options);\n case CursorEffectsEnum.SpringyEmoji:\n return cursor_effects.springyEmojiCursor(options);\n case CursorEffectsEnum.Emoji:\n return cursor_effects.emojiCursor(options);\n case CursorEffectsEnum.Ghost:\n return cursor_effects.ghostCursor(options);\n case CursorEffectsEnum.Trailing:\n return cursor_effects.trailingCursor(options);\n case CursorEffectsEnum.TextFlag:\n return cursor_effects.textFlag(options);\n case CursorEffectsEnum.FollowingDot:\n return cursor_effects.followingDotCursor(options);\n case CursorEffectsEnum.Bubbles:\n return cursor_effects.bubbleCursor(options);\n case CursorEffectsEnum.Snowflake:\n return cursor_effects.snowflakeCursor(options);\n case CursorEffectsEnum.Clock:\n return cursor_effects.clockCursor(options);\n }\n}\nclass CursorEffectsJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 100;\n this.effects = {\n /**\n * Радужный след за курсором\n */\n [CursorEffectsEnum.Rainbow]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Длина полосы\n */\n this.length = 20;\n /**\n * Ширина полосы\n */\n this.size = 3;\n /**\n * Цвета полос (сверху вниз)\n */\n this.colors = [\n \"#9400D3\",\n \"#4B0082\",\n \"#0000FF\",\n \"#00FF00\",\n \"#FFFF00\",\n \"#FF7F00\",\n \"#FF0000\",\n ];\n }\n })(),\n /**\n * Цепочка из эмодзи \"на резинке\" под курсором\n */\n [CursorEffectsEnum.SpringyEmoji]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Висящий эмодзи\n */\n this.emoji = \"🤪\";\n }\n })(),\n /**\n * Падающие от курсора эмодзи\n */\n [CursorEffectsEnum.Emoji]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Падающие эмодзи\n */\n this.emoji = [\"🔥\", \"🐬\", \"🦆\"];\n }\n })(),\n /**\n * Падающие от курсора пылинки\n */\n [CursorEffectsEnum.FairyDust]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Цвет пылинок\n */\n this.colors = [\"#ff0000\", \"#00ff00\", \"#0000ff\"];\n }\n })(),\n /**\n * След \"зависших\" курсоров\n */\n [CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting(),\n /**\n * След курсоров \"на резинке\"\n */\n [CursorEffectsEnum.Trailing]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Количество элементов\n */\n this.particles = 15;\n /**\n * Скорость частиц\n */\n this.rate = 0.4;\n /**\n * Ссылка на картинку с курсором\n * Используйте `null`, что бы использовать картинку курсора по умолчанию\n */\n this.baseImageSrc = null;\n }\n })(),\n /**\n * Текст, развивающийся флагом от курсора\n */\n [CursorEffectsEnum.TextFlag]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Отображаемый текст\n */\n this.text = \"С днём смеха!\";\n /**\n * Цвет текста\n */\n this.color = \"#000000\";\n /**\n * Шрифт текста\n */\n this.font = \"monospace\";\n /**\n * Размер текста\n */\n this.textSize = 12;\n /**\n * Растояние между бквами\n */\n this.gap = 14;\n /**\n * Размер... чего-то.\n */\n this.size = 3;\n }\n })(),\n /**\n * Точка, преследующая курсор\n */\n [CursorEffectsEnum.FollowingDot]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Цвет догоняющей точки\n */\n this.color = \"#323232a6\";\n }\n })(),\n /**\n * Пузырьки от курсора\n */\n [CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting(),\n /**\n * Снежинки, летящие от курсора\n *\n * Отключено, потому что сейчас не зима :D\n */\n [CursorEffectsEnum.Snowflake]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n this.weight = 0;\n }\n })(),\n /**\n * Циферблат вокруг курсора\n */\n [CursorEffectsEnum.Clock]: new (class extends DefaultCursorEffectsSetting {\n constructor() {\n super(...arguments);\n /**\n * Цвет даты\n */\n this.dateColor = \"blue\";\n /**\n * Цвет циферблата\n */\n this.faceColor = \"black\";\n /**\n * Цвет секундной стрелки\n */\n this.secondsColor = \"red\";\n /**\n * Цвет минутной стрелки\n */\n this.minutesColor = \"black\";\n /**\n * Цвет часовой стрелки\n */\n this.hoursColor = \"black\";\n }\n })(),\n };\n }\n}\nclass DefaultCursorEffectsSetting {\n constructor() {\n /**\n * Флаг возможности срабатывания\n */\n this.enabled = true;\n /**\n * Весовой коэффициент вероятности курсора\n */\n this.weight = 50;\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/cursor.ts?"); /***/ }), @@ -96,7 +116,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \****************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"HumanitarianHellJoke\": () => (/* binding */ HumanitarianHellJoke),\n/* harmony export */ \"HumanitarianHellJokeSettings\": () => (/* binding */ HumanitarianHellJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n/**\n * **Ад гуманитария**\n *\n * Все \"тся\" заменяются на \"ться\", а все \"ться\" на \"тся\"\n *\n * @author Kozhilya\n */\nvar HumanitarianHellJoke = /** @class */ (function (_super) {\n __extends(HumanitarianHellJoke, _super);\n function HumanitarianHellJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'humanitarian_hell';\n _this.title = 'Ад гуманитария';\n _this.description = 'Все \"тся\" заменяются на \"ться\", а все \"ться\" на \"тся\"';\n _this.settings = new HumanitarianHellJokeSettings;\n return _this;\n }\n HumanitarianHellJoke.prototype.start = function () {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).each(function () {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(this).html(jquery__WEBPACK_IMPORTED_MODULE_1___default()(this).html().replace(/(ть?ся)/g, function (fnd) {\n return (fnd.indexOf('ь') > 0) ? 'тся' : 'ться';\n }));\n });\n };\n return HumanitarianHellJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar HumanitarianHellJokeSettings = /** @class */ (function () {\n function HumanitarianHellJokeSettings() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = '.post-content';\n }\n return HumanitarianHellJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/humanitarian_hell.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"HumanitarianHellJoke\": () => (/* binding */ HumanitarianHellJoke),\n/* harmony export */ \"HumanitarianHellJokeSettings\": () => (/* binding */ HumanitarianHellJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common */ \"./src/common.ts\");\n\n\n/**\n * **Ад гуманитария**\n *\n * Все \"тся\" заменяются на \"ться\", а все \"ться\" на \"тся\"\n *\n * @author Kozhilya\n */\nclass HumanitarianHellJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"humanitarian_hell\";\n this.title = \"Ад гуманитария\";\n this.description = 'Все \"тся\" заменяются на \"ться\", а все \"ться\" на \"тся\"';\n this.settings = new HumanitarianHellJokeSettings();\n }\n processText(text) {\n return text.replace(/(ть?ся)/g, function (fnd) {\n return fnd.indexOf(\"ь\") > 0 ? \"тся\" : \"ться\";\n });\n }\n start() {\n const textNodes = (0,_common__WEBPACK_IMPORTED_MODULE_1__.getTextNodes)(this.settings.selector);\n textNodes.each((_, elem) => {\n elem.textContent = this.processText(elem.textContent);\n });\n }\n}\nclass HumanitarianHellJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = \".post-content\";\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/humanitarian_hell.ts?"); /***/ }), @@ -106,7 +126,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \***********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"LetterChaosJoke\": () => (/* binding */ LetterChaosJoke),\n/* harmony export */ \"LetterChaosJokeSettings\": () => (/* binding */ LetterChaosJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\n\n\n/**\n * **Буквенный хаос**\n *\n * Все буквы в словах, кроме первой и последней, перемешены.\n *\n * @author Kozhilya\n */\nvar LetterChaosJoke = /** @class */ (function (_super) {\n __extends(LetterChaosJoke, _super);\n function LetterChaosJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'letter_chaos';\n _this.title = 'Буквенный хаос';\n _this.description = 'Все буквы в словах, кроме первой и последней, перемешены.';\n _this.settings = new LetterChaosJokeSettings;\n _this.punctuationSymbols = null;\n return _this;\n }\n LetterChaosJoke.prototype.shuffleLetters = function (word) {\n var _a;\n // Check if the word has two or more letters\n if ((word.length < 3) || !this.check(this.settings.shuffle_chance)) {\n return word;\n }\n // Split the word into an array of characters\n var characters = word.split(\"\");\n // Shuffle the characters between the first and last letters\n var middleCharacters = characters.slice(1, -1);\n for (var i = middleCharacters.length - 1; i > 0; i--) {\n var j = Math.floor(Math.random() * (i + 1));\n _a = [middleCharacters[j], middleCharacters[i]], middleCharacters[i] = _a[0], middleCharacters[j] = _a[1];\n }\n // Join the shuffled characters back into a word\n return __spreadArray(__spreadArray([characters[0]], middleCharacters, true), [characters[characters.length - 1]], false).join(\"\");\n };\n LetterChaosJoke.prototype.processNode = function (node) {\n var _a;\n node.textContent = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.replace(/([А-Яа-яA-Za-z]+)/gm, this.shuffleLetters);\n };\n LetterChaosJoke.prototype.start = function () {\n var _this = this;\n var items = jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector).find('*').contents().filter(function (_, node) { return node.nodeType === Node.TEXT_NODE; });\n items.each(function (_, node) { return _this.processNode(node); });\n };\n return LetterChaosJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar LetterChaosJokeSettings = /** @class */ (function () {\n function LetterChaosJokeSettings() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = '.post-content';\n /**\n * Вероятность того, что буквы будут перемешаны\n */\n this.shuffle_chance = 50;\n }\n return LetterChaosJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/letter_chaos.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"LetterChaosJoke\": () => (/* binding */ LetterChaosJoke),\n/* harmony export */ \"LetterChaosJokeSettings\": () => (/* binding */ LetterChaosJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var _common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../common */ \"./src/common.ts\");\n\n\n/**\n * **Буквенный хаос**\n *\n * Все буквы в словах, кроме первой и последней, перемешены\n *\n * @author Kozhilya\n */\nclass LetterChaosJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"letter_chaos\";\n this.title = \"Буквенный хаос\";\n this.description = \"Все буквы в словах, кроме первой и последней, перемешены\";\n this.settings = new LetterChaosJokeSettings();\n this.punctuationSymbols = null;\n }\n shuffleLetters(word) {\n // Check if the word has two or more letters\n if (word.length < 3 || !this.check(this.settings.shuffle_chance)) {\n return word;\n }\n // Split the word into an array of characters\n const characters = word.split(\"\");\n // Shuffle the characters between the first and last letters\n const middleCharacters = characters.slice(1, -1);\n for (let i = middleCharacters.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [middleCharacters[i], middleCharacters[j]] = [\n middleCharacters[j],\n middleCharacters[i],\n ];\n }\n // Join the shuffled characters back into a word\n return [\n characters[0],\n ...middleCharacters,\n characters[characters.length - 1],\n ].join(\"\");\n }\n processNode(node) {\n var _a;\n node.textContent = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.replace(/([А-Яа-яA-Za-z]+)/gm, this.shuffleLetters);\n }\n start() {\n const textNodes = (0,_common__WEBPACK_IMPORTED_MODULE_1__.getTextNodes)(this.settings.selector);\n textNodes.each((_, node) => this.processNode(node));\n }\n}\nclass LetterChaosJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 20;\n /**\n * Селектор всех элементов, которые будут затронуты\n */\n this.selector = \".post-content\";\n /**\n * Вероятность того, что буквы будут перемешаны\n */\n this.shuffle_chance = 50;\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/letter_chaos.ts?"); /***/ }), @@ -116,7 +136,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MirrorJoke\": () => (/* binding */ MirrorJoke),\n/* harmony export */ \"MirrorJokeSettings\": () => (/* binding */ MirrorJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n/**\n * **Зеркало**\n *\n * Элементы форума отражаются (по крайней мере, пытаются)\n *\n * @author Kozhilya\n */\nvar MirrorJoke = /** @class */ (function (_super) {\n __extends(MirrorJoke, _super);\n function MirrorJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'mirror';\n _this.title = 'Зеркало';\n _this.description = 'Элементы форума отражаются (по крайней мере, пытаются)';\n _this.settings = new MirrorJokeSettings;\n return _this;\n }\n MirrorJoke.prototype.start = function () {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()('.post, .post h3, .post-links, .post-author, .post-content')\n .css('transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('filter', 'FlipH').css('-ms-filter', '\"FlipH\"');\n jquery__WEBPACK_IMPORTED_MODULE_1___default()('.post-links, .post-links ul, .post h3 span').css('margin-left', '0');\n jquery__WEBPACK_IMPORTED_MODULE_1___default()('.post h3 span').css('margin-right', '25em');\n };\n return MirrorJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar MirrorJokeSettings = /** @class */ (function () {\n function MirrorJokeSettings() {\n this.enabled = false;\n this.chance = 30;\n }\n return MirrorJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/mirror.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MirrorJoke\": () => (/* binding */ MirrorJoke),\n/* harmony export */ \"MirrorJokeSettings\": () => (/* binding */ MirrorJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n\n\n/**\n * **Зеркало**\n *\n * Элементы форума отражаются (по крайней мере, пытаются)\n *\n * @author Kozhilya\n */\nclass MirrorJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"mirror\";\n this.title = \"Зеркало\";\n this.description = \"Элементы форума отражаются (по крайней мере, пытаются)\";\n this.settings = new MirrorJokeSettings();\n }\n start() {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".post, .post h3, .post-links, .post-author, .post-content\")\n .css(\"transform\", \"scaleX(-1)\")\n .css(\"-moz-transform\", \"scaleX(-1)\")\n .css(\"-moz-transform\", \"scaleX(-1)\")\n .css(\"filter\", \"FlipH\")\n .css(\"-ms-filter\", '\"FlipH\"');\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".post-links, .post-links ul, .post h3 span\").css(\"margin-left\", \"0\");\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".post h3 span\").css(\"margin-right\", \"25em\");\n }\n}\nclass MirrorJokeSettings {\n constructor() {\n this.enabled = false;\n this.chance = 30;\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/mirror.ts?"); /***/ }), @@ -126,7 +146,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShakeJoke\": () => (/* binding */ ShakeJoke),\n/* harmony export */ \"ShakeJokeSettings\": () => (/* binding */ ShakeJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n/**\n * **Форумо-трясение**\n *\n * Страница форума начинает трястись\n *\n * @author Kozhilya\n */\nvar ShakeJoke = /** @class */ (function (_super) {\n __extends(ShakeJoke, _super);\n function ShakeJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'shake';\n _this.title = 'Форумо-трясение';\n _this.description = 'Страница форума начинает трястись';\n _this.settings = new ShakeJokeSettings;\n _this.data_name = 'april-fools-shake';\n return _this;\n }\n ShakeJoke.prototype.rand = function (a) {\n return a + this.settings.force * (Math.random() * 2 - 1);\n };\n ShakeJoke.prototype.start = function () {\n var _this = this;\n this.items = jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector);\n this.items.each(function (_, elem) {\n var data = {};\n _this.settings.directions.forEach(function (d) {\n data[d] = parseInt(jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css('margin-' + d));\n });\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(_this.data_name, data);\n });\n this.interval_id = setInterval(function () {\n _this.items.each(function (_, elem) {\n var data = jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(_this.data_name);\n for (var _i = 0, _a = Object.entries(data); _i < _a.length; _i++) {\n var entry = _a[_i];\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css('margin-' + entry[0], _this.rand(entry[1]));\n }\n });\n }, this.settings.interval);\n };\n ShakeJoke.prototype.stop = function () {\n var _this = this;\n clearInterval(this.interval_id);\n this.items.each(function (_, elem) {\n var data = {};\n _this.settings.directions.forEach(function (d) {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css('margin-' + d, data[d]);\n });\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(_this.data_name, data);\n });\n };\n return ShakeJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke));\n\nvar ShakeJokeSettings = /** @class */ (function () {\n function ShakeJokeSettings() {\n this.enabled = false;\n this.chance = 1;\n /**\n * Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения)\n */\n this.directions = ['top', 'left', 'bottom', 'left'];\n /**\n * Сила тряски - насколько отклоняется элемент от стандартного значения\n */\n this.force = 0.5;\n /**\n * Селектор всех элементов, которые будут трястись\n */\n this.selector = '[id^=pun]';\n /**\n * Частота тряски\n */\n this.interval = 100;\n }\n return ShakeJokeSettings;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/shake.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ShakeJoke\": () => (/* binding */ ShakeJoke),\n/* harmony export */ \"ShakeJokeSettings\": () => (/* binding */ ShakeJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n\n\n/**\n * **Форумо-трясение**\n *\n * Страница форума начинает трястись\n *\n * @author Kozhilya\n */\nclass ShakeJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.StopableJoke {\n constructor() {\n super(...arguments);\n this.id = \"shake\";\n this.title = \"Форумо-трясение\";\n this.description = \"Страница форума начинает трястись\";\n this.settings = new ShakeJokeSettings();\n this.data_name = \"april-fools-shake\";\n }\n rand(a) {\n return a + this.settings.force * (Math.random() * 2 - 1);\n }\n start() {\n this.items = jquery__WEBPACK_IMPORTED_MODULE_1___default()(this.settings.selector);\n this.items.each((_, elem) => {\n let data = {};\n this.settings.directions.forEach((d) => {\n data[d] = parseInt(jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css(\"margin-\" + d));\n });\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(this.data_name, data);\n });\n this.interval_id = setInterval(() => {\n this.items.each((_, elem) => {\n const data = jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(this.data_name);\n for (const entry of Object.entries(data)) {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css(\"margin-\" + entry[0], this.rand(entry[1]));\n }\n });\n }, this.settings.interval);\n }\n stop() {\n clearInterval(this.interval_id);\n this.items.each((_, elem) => {\n let data = {};\n this.settings.directions.forEach((d) => {\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).css(\"margin-\" + d, data[d]);\n });\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(elem).data(this.data_name, data);\n });\n }\n}\nclass ShakeJokeSettings {\n constructor() {\n this.enabled = false;\n this.chance = 1;\n /**\n * Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения)\n */\n this.directions = [\"top\", \"left\", \"bottom\", \"left\"];\n /**\n * Сила тряски - насколько отклоняется элемент от стандартного значения\n */\n this.force = 0.5;\n /**\n * Селектор всех элементов, которые будут трястись\n */\n this.selector = \"[id^=pun]\";\n /**\n * Частота тряски\n */\n this.interval = 100;\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/shake.ts?"); /***/ }), @@ -136,7 +156,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \***********************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"StupidTitleJoke\": () => (/* binding */ StupidTitleJoke),\n/* harmony export */ \"StupidTitleJokeSettings\": () => (/* binding */ StupidTitleJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __assign = (undefined && undefined.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\n\n\n/**\n * **Глупые статусы**\n *\n * Каждому пользователю даётся новый глупый статус.\n *\n * @author Kozhilya\n */\nvar StupidTitleJoke = /** @class */ (function (_super) {\n __extends(StupidTitleJoke, _super);\n function StupidTitleJoke() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.id = 'stupid_title';\n _this.title = 'Глупые статусы';\n _this.description = 'Каждому пользователю даётся новый глупый статус.';\n _this.settings = new StupidTitleJokeSettings;\n _this.loadedGenders = null;\n _this.seed = 0;\n return _this;\n }\n StupidTitleJoke.prototype.loadGenders = function () {\n return __awaiter(this, void 0, void 0, function () {\n var names, url, response, json;\n var _this = this;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n names = jquery__WEBPACK_IMPORTED_MODULE_1___default()('.pa-author a')\n .map(function (_, elem) { return elem.innerText; }).toArray()\n .reduce(function (arr, name) {\n if (arr.indexOf(name) < 0) {\n arr.push(name);\n }\n return arr;\n }, []);\n url = '/api.php?' + jquery__WEBPACK_IMPORTED_MODULE_1___default().param({ method: 'users.get', fields: 'username,sex', username: names });\n return [4 /*yield*/, fetch(url)];\n case 1:\n response = _a.sent();\n return [4 /*yield*/, response.json()];\n case 2:\n json = _a.sent();\n this.loadedGenders = {};\n if (json.error) {\n return [2 /*return*/];\n }\n json.response.users.forEach(function (element) {\n if (element.sex === '0') {\n return;\n }\n _this.loadedGenders[element.username] = element.sex === '1';\n });\n return [2 /*return*/];\n }\n });\n });\n };\n StupidTitleJoke.prototype.resolveGender = function (name) {\n if (this.settings.gender_resolver !== null) {\n return !!this.settings.gender_resolver.call(this, name);\n }\n if (name in this.loadedGenders) {\n return !!this.loadedGenders[name];\n }\n this.resetSeed();\n return this.selectRandom(name, { 'm': 1, 'f': 1 }) === 'm';\n };\n StupidTitleJoke.prototype.start = function () {\n return __awaiter(this, void 0, void 0, function () {\n var cache;\n var _this = this;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.loadGenders()];\n case 1:\n _a.sent();\n cache = {};\n jquery__WEBPACK_IMPORTED_MODULE_1___default()('.post-author').each(function (_, root) {\n var name = jquery__WEBPACK_IMPORTED_MODULE_1___default()('.pa-author a', root).text();\n if (!name) {\n return;\n }\n if (!(name in cache)) {\n _this.resetSeed();\n cache[name] = _this.generatePhrase(name);\n }\n jquery__WEBPACK_IMPORTED_MODULE_1___default()('.pa-title', root).text(cache[name]);\n });\n return [2 /*return*/];\n }\n });\n });\n };\n StupidTitleJoke.prototype.prng = function (name, seed, limit) {\n /*\n https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js\n\n cyrb53 (c) 2018 bryc (github.com/bryc)\n A fast and simple hash function with decent collision resistance.\n Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.\n Public domain. Attribution appreciated.\n */\n var h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;\n for (var i = 0, ch = void 0; i < name.length; i++) {\n ch = name.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n var value = 4294967296 * (2097151 & h2) + (h1 >>> 0);\n return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit;\n };\n StupidTitleJoke.prototype.resetSeed = function () {\n var date = new Date();\n var time = new Date().getUTCHours() * 60 + new Date().getUTCMinutes();\n this.seed = Math.floor(time / this.settings.change_frequency);\n console.log('Seed reset:', time, this.seed);\n };\n StupidTitleJoke.prototype.selectRandom = function (name, variants) {\n var elements = Object.keys(variants);\n var totalWeight = elements.reduce(function (sum, element) { return sum + variants[element]; }, 0);\n var randomWeight = this.prng(name, this.seed++, totalWeight);\n var currentWeight = 0;\n for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {\n var element = elements_1[_i];\n currentWeight += variants[element];\n if (randomWeight <= currentWeight) {\n return element;\n }\n }\n throw new Error(\"Тебя быть тут не должно...\");\n };\n StupidTitleJoke.prototype.buildVariants = function (type, gender) {\n var result = {};\n var variants = this.settings.variants[type];\n for (var _i = 0, _a = Object.entries(variants); _i < _a.length; _i++) {\n var iterator = _a[_i];\n var word = iterator[0];\n var wordSettings = iterator[1];\n if (!wordSettings.enabled || (wordSettings.gender === !gender)) {\n continue;\n }\n if (!this.settings.rude && wordSettings.rude) {\n continue;\n }\n result[word] = wordSettings.weight;\n }\n return result;\n };\n StupidTitleJoke.prototype.capitalizeFirst = function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n };\n StupidTitleJoke.prototype.generatePhrase = function (name) {\n var _this = this;\n var gender = this.resolveGender(name);\n var prhase = this.selectRandom(name, this.settings.schemas);\n return this.capitalizeFirst(prhase.replace(/\\{(.+?)\\}/g, function (_, type) {\n var variants = _this.buildVariants(type, gender);\n return _this.selectRandom(name, variants);\n }));\n };\n return StupidTitleJoke;\n}(_joke__WEBPACK_IMPORTED_MODULE_0__.Joke));\n\nvar StupidTitleJokeSettings = /** @class */ (function () {\n function StupidTitleJokeSettings() {\n this.enabled = true;\n this.chance = 100;\n /**\n * Определение пола по имени.\n * По умолчанию род устанавливается случайным образом\n *\n * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом.\n *\n * @param name Имя персонажа\n * @returns true, если мужской род; false, если женский род\n */\n this.gender_resolver = null;\n /**\n * Разрешить возможно оскорбительные варианты\n */\n this.rude = false;\n /**\n * Частота смены статусов (в минутах)\n */\n this.change_frequency = 5;\n /**\n * Разрешённые схемы формирования статусов\n *\n * {adj} - прилагательное\n * {noun} - имя существительно\n * {verb} - глагол\n * {adv} - наречие\n * {place} - дополнение места\n * {p} - знак препинания\n */\n this.schemas = {\n '{adj} {noun}{p}': 10,\n '{noun} {adj}{p}': 3,\n '{adj}, {adj} {noun}{p}': 10,\n '{adj} и очень {adj} {noun}{p}': 10,\n '{adj} {noun} {verb}{p}': 10,\n '{adj} {noun} {adv} {verb}{p}': 5,\n '{adj} {noun} {verb} {place}{p}': 5,\n '{adj} {noun} {adv} {verb} {place}{p}': 5,\n };\n /**\n * Вариант слов\n * Смотрите раздел описания скрипта, что бы настроить это поле\n */\n this.variants = {\n adj: __assign(__assign({}, buildVariant(true, 'жесткий,^удачливый,низкий,знакомый,откровенный,^мирный,грамотный,вкусный,виртуальный,пышный,провинциальный,$жирный,заинтересованный,объективный,^оригинальный,пожилой,чистый,особенный,выгодный,громадный,обыкновенный,чужой,ударный,^солнечный,истинный,посторонний,южный,седой,$бесполезный,острый,пестрый,формальный,повседневный,невозможный,$жалкий,целый,$глупый,последний,выходной,серьезный,подземный,небесный,любимый,былой,семейный,далекий,северный,суровый,гигантский,иностранный,родной,конструктивный,показательный,нужный,чрезвычайный,гордый,банальный,открытый,независимый,запасной,мстительный,грубый,алчный,мелочный,хладнокровный,спокойный,терпеливый,креативный,активный,адекватный,застенчивый,опрятный,безнадёжный,уверенный в себе,доброжелательный,ласковый,робкий,воспитанный,самовлюблённый,деятельный,двуличный,верный')), buildVariant(false, 'жесткая,^удачливая,низкая,знакомая,откровенная,^мирная,грамотная,вкусная,виртуальная,пышная,провинциальная,$жирная,заинтересованная,объективная,^оригинальная,пожилая,чистая,особенная,выгодная,громадная,обыкновенная,чужая,ударная,^солнечная,истинная,посторонняя,южная,седая,$бесполезная,острая,пестрая,формальная,повседневная,невозможная,$жалкая,целая,$глупая,последняя,выходная,серьезная,подземная,небесная,любимая,былая,семейная,далекая,северная,суровая,гигантская,иностранная,родная,конструктивная,показательная,нужная,чрезвычайная,гордая,банальная,открытая,независимая,запасная,мстительная,грубая,алчная,мелочная,хладнокровная,спокаяная,терпеливая,креативная,активная,адекватная,застенчивая,опрятная,безнадёжная,уверенная в себе,доброжелательная,ласковая,робкая,воспитанная,самовлюблённая,деятельная,двуличная,верная')),\n noun: __assign(__assign(__assign({}, buildVariant(null, '')), buildVariant(true, 'орёл, ниндзя, манекен, пузырь, бродяга, рыцарь, кентавр, зайц, диван, наследник, сын, джентльмен, басурманин, карасик, $злоумышленник, $раб, хоббит, одиночка, отец, кролик, бруталище, дворф, актёр, %дед, спортсмен, $балбес, %мальчег, лев, ёж, организм, монах, хоббит, борец, тигр, монстр, массажист, мачо, эльф, ледник, жук, кот, зомби, проказник, дракон, носорог, волк, лесоруб, кит, %дедушка, динозавр, бард, кулак, принц, %сынок, мальчик, товарищ, ёжик, сурикат')), buildVariant(false, 'заноза, волторна, $личинка, детка, %бабушка, простуда, черепашка, мышь, волчица, деревяшка, пиранья, каруселька, красотка, леди, %дочка, орлица, принцесса, $ведьма, травка, актриса, наследница, %деффачка, горгулья, белочка, акула, машинка, конфетка, знаменитость, косточка, спортсменка, панда, мать, львица, эльфийка, $злоумышленница, чертовка, дворфиха, кошка, $рабыня, скамеечка, дочь, монашка, бактерия, рыбка, бусинка, $бабка, девочка, валькирия, килька, бабочка, милашка, крышка, тигрица, рыбка, русалочка')),\n verb: __assign(__assign(__assign({}, buildVariant(null, 'встаёт, снимает, приказывает, указывает, собирается, чувствует опасность, орёт, болеет, поздравляет, освобождает, поздравляет, бежит, берёт и делает, молчит, радуется, прощает, читает, снимает, снимается в фильме, что-то скрывает, думает, имеет план и придерживается его, тянет, работает, меняется, ловит, отказаться куда-то идти, заходит, замирает, оформляет, нарушает, отказывается что-то делать, шепчет, снимается в сериале, скрывается, учит, спрашивает, идёт, отказывается вставать, прибывает, отказывается, забывает, получает, плывёт, отвечает, поглядывает, говорит, просыпается, соединяет, оглядывается')), buildVariant(true, 'женится, женился, успел, не успел, смог, скрылся, заработался, познал дзен, присел, обиделся, проснулся, взял и сделал, додумался, не спал')), buildVariant(false, 'выходит замуж, вышла замуж, успела, не успела, смогла, скрылась, заработалась, познала дзен, присела, обиделась, проснулась, взяла и сделала, додумалась, не спала')),\n place: __assign({}, buildVariant(null, 'где-то, в пустыне, на пляже, под дождём, %под проливным дождём, в квартире, %в тёплой и уютной квартире, в космосе, в театре, в филармонии, на заснеженной вершине, на конференции, на форуме, в очереди, в лесу, в джунглях, под водой')),\n adv: __assign({}, buildVariant(null, 'счастливо, уныло, грустно, позже, немедленно, регулярно, вновь, опять, уже, внезапно, предсказуемо, медленно, быстро, %молниеносно, $грубо, безрассудно, осмысленно, расчётливо')),\n p: {\n '': new StupidTitleSetting({ weight: 10 }),\n '.': new StupidTitleSetting({ weight: 10 }),\n '...': new StupidTitleSetting({ weight: 5 }),\n '!': new StupidTitleSetting({ weight: 5 }),\n '!!!': new StupidTitleSetting({ weight: 2 }),\n '?': new StupidTitleSetting({ weight: 2 }),\n '?!': new StupidTitleSetting({ weight: 1 }),\n },\n };\n }\n return StupidTitleJokeSettings;\n}());\n\nvar StupidTitleSetting = /** @class */ (function () {\n function StupidTitleSetting(options) {\n if (options === void 0) { options = new Object; }\n this.weight = 10;\n this.enabled = true;\n this.rude = false;\n this.gender = null;\n for (var _i = 0, _a = Object.entries(options); _i < _a.length; _i++) {\n var iterator = _a[_i];\n if (iterator[0] in this) {\n this[iterator[0]] = iterator[1];\n }\n }\n }\n return StupidTitleSetting;\n}());\nfunction buildVariant(gender, input) {\n var result = {};\n var words = input.split(',').map(function (word) { return word.trim(); });\n words.forEach(function (word) {\n var clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\\- ]/g, '');\n if (clean_word === '') {\n return;\n }\n result[clean_word] = new StupidTitleSetting({\n gender: gender,\n rude: word.indexOf('$') >= 0,\n enabled: word.indexOf('!') < 0,\n weight: 10 * ((word.indexOf('$') >= 0) ? 0.5 : 1) * ((word.indexOf('%') >= 0) ? 0.5 : 1) * ((word.indexOf('^') >= 0) ? 2 : 1)\n });\n });\n return result;\n}\nwindow.BuildStupdiTitleVariant = buildVariant;\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/stupid_title.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BuildStupdiTitleVariant\": () => (/* binding */ BuildStupdiTitleVariant),\n/* harmony export */ \"StupidTitleJoke\": () => (/* binding */ StupidTitleJoke),\n/* harmony export */ \"StupidTitleJokeSettings\": () => (/* binding */ StupidTitleJokeSettings)\n/* harmony export */ });\n/* harmony import */ var _joke__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../joke */ \"./src/joke.ts\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _data_stupid_title_variants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../data/stupid_title_variants */ \"./src/data/stupid_title_variants.ts\");\n\n\n\n/**\n * **Глупые статусы**\n *\n * Каждому пользователю даётся новый глупый статус\n *\n * @author Kozhilya\n */\nclass StupidTitleJoke extends _joke__WEBPACK_IMPORTED_MODULE_0__.Joke {\n constructor() {\n super(...arguments);\n this.id = \"stupid_title\";\n this.title = \"Глупые статусы\";\n this.description = \"Каждому пользователю даётся новый глупый статус\";\n this.settings = new StupidTitleJokeSettings();\n this.loadedGenders = null;\n this.variantsGenerated = false;\n this.seed = 0;\n }\n async loadGenders() {\n const names = jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".pa-author a\")\n .map((_, elem) => elem.innerText)\n .toArray()\n .reduce((arr, name) => {\n if (arr.indexOf(name) < 0) {\n arr.push(name);\n }\n return arr;\n }, []);\n const url = \"/api.php?\" +\n jquery__WEBPACK_IMPORTED_MODULE_1___default().param({ method: \"users.get\", fields: \"username,sex\", username: names });\n const response = await fetch(url);\n const json = await response.json();\n this.loadedGenders = {};\n if (json.error) {\n return;\n }\n json.response.users.forEach((element) => {\n if (element.sex === \"0\") {\n return;\n }\n this.loadedGenders[element.username] = element.sex === \"1\";\n });\n }\n resolveGender(name) {\n if (this.settings.gender_resolver !== null) {\n return !!this.settings.gender_resolver.call(this, name);\n }\n if (name in this.loadedGenders) {\n return !!this.loadedGenders[name];\n }\n this.resetSeed();\n return this.selectRandom(name, { m: 1, f: 1 }) === \"m\";\n }\n async start() {\n if (!this.variantsGenerated) {\n (0,_data_stupid_title_variants__WEBPACK_IMPORTED_MODULE_2__.StupidTitleDefaultVariants)(this.settings.variants);\n this.variantsGenerated = true;\n }\n await this.loadGenders();\n const cache = {};\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".post-author\").each((_, root) => {\n const name = jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".pa-author a\", root).text();\n if (!name) {\n return;\n }\n if (!(name in cache)) {\n this.resetSeed();\n cache[name] = this.generatePhrase(name);\n }\n jquery__WEBPACK_IMPORTED_MODULE_1___default()(\".pa-title\", root).text(cache[name]);\n });\n }\n prng(name, seed, limit) {\n /*\n https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js\n \n cyrb53 (c) 2018 bryc (github.com/bryc)\n A fast and simple hash function with decent collision resistance.\n Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.\n Public domain. Attribution appreciated.\n */\n let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;\n for (let i = 0, ch; i < name.length; i++) {\n ch = name.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 =\n Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^\n Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 =\n Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^\n Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n const value = 4294967296 * (2097151 & h2) + (h1 >>> 0);\n return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit;\n }\n resetSeed() {\n const date = new Date();\n const time = date.getUTCHours() * 60 + date.getUTCMinutes();\n if (this.settings.change_frequency === 0) {\n this.seed = time * 60 + date.getUTCSeconds();\n return;\n }\n this.seed = Math.floor(time / this.settings.change_frequency);\n }\n selectRandom(name, variants) {\n const elements = Object.keys(variants);\n const totalWeight = elements.reduce((sum, element) => sum + variants[element], 0);\n const randomWeight = this.prng(name, this.seed++, totalWeight);\n let currentWeight = 0;\n for (const element of elements) {\n currentWeight += variants[element];\n if (randomWeight <= currentWeight) {\n return element;\n }\n }\n throw new Error(\"Тебя быть тут не должно...\");\n }\n buildVariants(type, gender) {\n const result = {};\n const variants = this.settings.variants[type];\n for (const iterator of Object.entries(variants)) {\n const word = iterator[0];\n const wordSettings = iterator[1];\n if (!wordSettings.enabled || wordSettings.gender === !gender) {\n continue;\n }\n if (!this.settings.rude && wordSettings.rude) {\n continue;\n }\n result[word] = wordSettings.weight;\n }\n return result;\n }\n capitalizeFirst(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n generatePhrase(name) {\n const gender = this.resolveGender(name);\n const prhase = this.selectRandom(name, this.settings.schemas);\n return this.capitalizeFirst(prhase.replace(/\\{(.+?)\\}/g, (_, type) => {\n const variants = this.buildVariants(type, gender);\n return this.selectRandom(name, variants);\n }));\n }\n}\nclass StupidTitleJokeSettings {\n constructor() {\n this.enabled = true;\n this.chance = 100;\n /**\n * Определение пола по имени.\n * По умолчанию род устанавливается случайным образом\n *\n * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом.\n *\n * @param name Имя персонажа\n * @returns true, если мужской род; false, если женский род\n */\n this.gender_resolver = null;\n /**\n * Разрешить возможно оскорбительные варианты\n */\n this.rude = false;\n /**\n * Частота смены статусов (в минутах)\n * Установите значение 0, что бы обновление происходило при каждом обновлении страницы\n */\n this.change_frequency = 5;\n /**\n * Разрешённые схемы формирования статусов\n *\n * {adj} - прилагательное\n * {noun} - имя существительно\n * {verb} - глагол\n * {adv} - наречие\n * {place} - дополнение места\n * {p} - знак препинания\n */\n this.schemas = {\n \"{adj} {noun}{p}\": 10,\n \"{noun} {adj}{p}\": 3,\n \"{adj}, {adj} {noun}{p}\": 10,\n \"{adj} и очень {adj} {noun}{p}\": 10,\n \"{adj} {noun} {verb}{p}\": 10,\n \"{adj} {noun} {adv} {verb}{p}\": 5,\n \"{adj} {noun} {verb} {place}{p}\": 5,\n \"{adj} {noun} {adv} {verb} {place}{p}\": 5,\n };\n /**\n * Вариант слов\n * Смотрите раздел описания скрипта, что бы настроить это поле\n */\n this.variants = {\n adj: {},\n noun: {},\n verb: {},\n place: {},\n adv: {},\n p: {\n \"\": new StupidTitleSetting({ weight: 10 }),\n \".\": new StupidTitleSetting({ weight: 10 }),\n \"...\": new StupidTitleSetting({ weight: 5 }),\n \"!\": new StupidTitleSetting({ weight: 5 }),\n \"!!!\": new StupidTitleSetting({ weight: 2 }),\n \"?\": new StupidTitleSetting({ weight: 2 }),\n \"?!\": new StupidTitleSetting({ weight: 1 }),\n },\n };\n }\n}\nclass StupidTitleSetting {\n constructor(options = new Object()) {\n this.weight = 10;\n this.enabled = true;\n this.rude = false;\n this.gender = null;\n for (const iterator of Object.entries(options)) {\n if (iterator[0] in this) {\n this[iterator[0]] = iterator[1];\n }\n }\n }\n}\nfunction BuildStupdiTitleVariant(gender, input) {\n const result = {};\n const words = input.split(\",\").map((word) => word.trim());\n words.forEach((word) => {\n const clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\\- ]/g, \"\");\n if (clean_word === \"\") {\n return;\n }\n result[clean_word] = new StupidTitleSetting({\n gender,\n rude: word.indexOf(\"$\") >= 0,\n enabled: word.indexOf(\"!\") < 0,\n weight: 10 *\n (word.indexOf(\"$\") >= 0 ? 0.5 : 1) *\n (word.indexOf(\"%\") >= 0 ? 0.5 : 1) *\n (word.indexOf(\"^\") >= 0 ? 2 : 1),\n });\n });\n return result;\n}\nwindow.BuildStupdiTitleVariant = BuildStupdiTitleVariant;\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/jokes/stupid_title.ts?"); /***/ }), @@ -146,7 +166,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _joker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./joker */ \"./src/joker.ts\");\n/* harmony import */ var _jokes_shake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./jokes/shake */ \"./src/jokes/shake.ts\");\n/* harmony import */ var _jokes_humanitarian_hell__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./jokes/humanitarian_hell */ \"./src/jokes/humanitarian_hell.ts\");\n/* harmony import */ var _jokes_mirror__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./jokes/mirror */ \"./src/jokes/mirror.ts\");\n/* harmony import */ var _jokes_carnival__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./jokes/carnival */ \"./src/jokes/carnival.ts\");\n/* harmony import */ var _jokes_crazy_letters__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./jokes/crazy_letters */ \"./src/jokes/crazy_letters.ts\");\n/* harmony import */ var _jokes_letter_chaos__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./jokes/letter_chaos */ \"./src/jokes/letter_chaos.ts\");\n/* harmony import */ var _jokes_cursor__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./jokes/cursor */ \"./src/jokes/cursor.ts\");\n/* harmony import */ var _jokes_stupid_title__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./jokes/stupid_title */ \"./src/jokes/stupid_title.ts\");\n\n\n\n\n\n\n\n\n\nwindow.AprilJokes = (function (jokes) {\n var cl = new _joker__WEBPACK_IMPORTED_MODULE_0__.JokerClass();\n jokes.forEach(function (joke) {\n cl.add(new joke());\n });\n $(function () { return cl.regularStart(); });\n return cl;\n})([\n _jokes_shake__WEBPACK_IMPORTED_MODULE_1__.ShakeJoke,\n _jokes_humanitarian_hell__WEBPACK_IMPORTED_MODULE_2__.HumanitarianHellJoke,\n _jokes_mirror__WEBPACK_IMPORTED_MODULE_3__.MirrorJoke,\n _jokes_carnival__WEBPACK_IMPORTED_MODULE_4__.CarnivalJoke,\n _jokes_crazy_letters__WEBPACK_IMPORTED_MODULE_5__.CrazyLettersJoke,\n _jokes_letter_chaos__WEBPACK_IMPORTED_MODULE_6__.LetterChaosJoke,\n _jokes_cursor__WEBPACK_IMPORTED_MODULE_7__.CursorEffectsJoke,\n _jokes_stupid_title__WEBPACK_IMPORTED_MODULE_8__.StupidTitleJoke,\n]);\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/main.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _joker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./joker */ \"./src/joker.ts\");\n/* harmony import */ var _jokes_shake__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./jokes/shake */ \"./src/jokes/shake.ts\");\n/* harmony import */ var _jokes_humanitarian_hell__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./jokes/humanitarian_hell */ \"./src/jokes/humanitarian_hell.ts\");\n/* harmony import */ var _jokes_mirror__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./jokes/mirror */ \"./src/jokes/mirror.ts\");\n/* harmony import */ var _jokes_carnival__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./jokes/carnival */ \"./src/jokes/carnival.ts\");\n/* harmony import */ var _jokes_crazy_letters__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./jokes/crazy_letters */ \"./src/jokes/crazy_letters.ts\");\n/* harmony import */ var _jokes_letter_chaos__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./jokes/letter_chaos */ \"./src/jokes/letter_chaos.ts\");\n/* harmony import */ var _jokes_cursor__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./jokes/cursor */ \"./src/jokes/cursor.ts\");\n/* harmony import */ var _jokes_stupid_title__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./jokes/stupid_title */ \"./src/jokes/stupid_title.ts\");\n\n\n\n\n\n\n\n\n\nwindow.AprilJokes = ((jokes) => {\n const cl = new _joker__WEBPACK_IMPORTED_MODULE_0__.JokerClass();\n jokes.forEach((joke) => {\n cl.add(new joke());\n });\n $(() => cl.regularStart());\n return cl;\n})([\n _jokes_shake__WEBPACK_IMPORTED_MODULE_1__.ShakeJoke,\n _jokes_humanitarian_hell__WEBPACK_IMPORTED_MODULE_2__.HumanitarianHellJoke,\n _jokes_mirror__WEBPACK_IMPORTED_MODULE_3__.MirrorJoke,\n _jokes_carnival__WEBPACK_IMPORTED_MODULE_4__.CarnivalJoke,\n _jokes_crazy_letters__WEBPACK_IMPORTED_MODULE_5__.CrazyLettersJoke,\n _jokes_letter_chaos__WEBPACK_IMPORTED_MODULE_6__.LetterChaosJoke,\n _jokes_cursor__WEBPACK_IMPORTED_MODULE_7__.CursorEffectsJoke,\n _jokes_stupid_title__WEBPACK_IMPORTED_MODULE_8__.StupidTitleJoke,\n]);\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/main.ts?"); /***/ }), @@ -156,7 +176,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _jok \*******************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JokerUI\": () => (/* binding */ JokerUI)\n/* harmony export */ });\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _html_button_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./html/button.html */ \"./src/html/button.html\");\n/* harmony import */ var _html_styles_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./html/styles.html */ \"./src/html/styles.html\");\n/* harmony import */ var _html_window_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./html/window.html */ \"./src/html/window.html\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (undefined && undefined.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\n\n\n\n\nvar JokerUI = /** @class */ (function () {\n function JokerUI(joker) {\n var _this = this;\n this.joker = joker;\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('link[rel=\"stylesheet\"]').eq(0).before(_html_styles_html__WEBPACK_IMPORTED_MODULE_2__[\"default\"]);\n var button = this.button;\n button.hide();\n button.mybbModal({\n title: \"Настройки первоапрельских шуток\",\n content: function () { return _this.render(); },\n closer: true,\n noscroll: true,\n escClose: true,\n });\n }\n Object.defineProperty(JokerUI.prototype, \"button\", {\n get: function () {\n var button = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.april-fools__button');\n if (button.length === 0) {\n button = jquery__WEBPACK_IMPORTED_MODULE_0___default()(_html_button_html__WEBPACK_IMPORTED_MODULE_1__[\"default\"]).appendTo('body');\n }\n return button;\n },\n enumerable: false,\n configurable: true\n });\n JokerUI.prototype.show = function () {\n this.button.show();\n };\n JokerUI.prototype.render = function () {\n var _this = this;\n var result = jquery__WEBPACK_IMPORTED_MODULE_0___default()('
').html(_html_window_html__WEBPACK_IMPORTED_MODULE_3__[\"default\"]);\n var row_template = jquery__WEBPACK_IMPORTED_MODULE_0___default()('#april-fools__window-row', result).html();\n var joke_container = jquery__WEBPACK_IMPORTED_MODULE_0___default()('.april-fools__jokes', result);\n var _loop_1 = function (joke) {\n var row = jquery__WEBPACK_IMPORTED_MODULE_0___default()(eval('`' + row_template + '`'));\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('input[type=\"checkbox\"]', row).prop('checked', joke.settings.enabled)\n .on('click', function (e) { return _this.joker.toggleJoke(joke.id, e.currentTarget.checked); });\n joke_container.append(row);\n };\n for (var _i = 0, _a = Object.values(this.joker.jokes); _i < _a.length; _i++) {\n var joke = _a[_i];\n _loop_1(joke);\n }\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('button', result).on('click', function () { return __awaiter(_this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.joker.clearUserStates()];\n case 1:\n _a.sent();\n window.location.reload();\n return [2 /*return*/];\n }\n });\n }); });\n return jquery__WEBPACK_IMPORTED_MODULE_0___default()('.april-fools__content', result);\n };\n return JokerUI;\n}());\n\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/ui.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JokerUI\": () => (/* binding */ JokerUI)\n/* harmony export */ });\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ \"jquery\");\n/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _html_button_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./html/button.html */ \"./src/html/button.html\");\n/* harmony import */ var _html_styles_html__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./html/styles.html */ \"./src/html/styles.html\");\n/* harmony import */ var _html_window_html__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./html/window.html */ \"./src/html/window.html\");\n\n\n\n\nclass JokerUI {\n constructor(joker) {\n this.joker = joker;\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('link[rel=\"stylesheet\"]').eq(0).before(_html_styles_html__WEBPACK_IMPORTED_MODULE_2__[\"default\"]);\n const button = this.button;\n button.hide();\n button.mybbModal({\n title: \"Настройки первоапрельских шуток\",\n content: () => this.render(),\n closer: true,\n noscroll: true,\n escClose: true,\n });\n }\n get button() {\n let button = jquery__WEBPACK_IMPORTED_MODULE_0___default()(\".april-fools__button\");\n if (button.length === 0) {\n button = jquery__WEBPACK_IMPORTED_MODULE_0___default()(_html_button_html__WEBPACK_IMPORTED_MODULE_1__[\"default\"]).appendTo(\"body\");\n }\n return button;\n }\n show() {\n this.button.show();\n }\n render() {\n const result = jquery__WEBPACK_IMPORTED_MODULE_0___default()(\"
\").html(_html_window_html__WEBPACK_IMPORTED_MODULE_3__[\"default\"]);\n const row_template = jquery__WEBPACK_IMPORTED_MODULE_0___default()(\"#april-fools__window-row\", result).html();\n const joke_container = jquery__WEBPACK_IMPORTED_MODULE_0___default()(\".april-fools__jokes\", result);\n for (const joke of Object.values(this.joker.jokes)) {\n const row = jquery__WEBPACK_IMPORTED_MODULE_0___default()(eval(\"`\" + row_template + \"`\"));\n jquery__WEBPACK_IMPORTED_MODULE_0___default()('input[type=\"checkbox\"]', row)\n .prop(\"checked\", joke.settings.enabled)\n .on(\"click\", (e) => this.joker.toggleJoke(joke.id, e.currentTarget.checked));\n joke_container.append(row);\n }\n jquery__WEBPACK_IMPORTED_MODULE_0___default()(\"button\", result).on(\"click\", async () => {\n await this.joker.clearUserStates();\n window.location.reload();\n });\n return jquery__WEBPACK_IMPORTED_MODULE_0___default()(\".april-fools__content\", result);\n }\n}\n\n\n//# sourceURL=webpack://mybb-april-fools/./src/ui.ts?"); /***/ }), diff --git a/dist/april-fools.min.js b/dist/april-fools.min.js index b56a28e..8496e16 100644 --- a/dist/april-fools.min.js +++ b/dist/april-fools.min.js @@ -1 +1 @@ -(()=>{"use strict";var __webpack_modules__={525:(t,e,n)=>{n.d(e,{Z:()=>i});const i=''},554:(t,e,n)=>{n.d(e,{Z:()=>i});const i=''},95:(t,e,n)=>{n.d(e,{Z:()=>i});const i='
'},562:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.d(__webpack_exports__,{d:()=>JokerUI});var jquery__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(311),jquery__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__),_html_button_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(525),_html_styles_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(554),_html_window_html__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(95),JokerUI=function(){function JokerUI(t){var e=this;this.joker=t,jquery__WEBPACK_IMPORTED_MODULE_0___default()('link[rel="stylesheet"]').eq(0).before(_html_styles_html__WEBPACK_IMPORTED_MODULE_1__.Z);var n=this.button;n.hide(),n.mybbModal({title:"Настройки первоапрельских шуток",content:function(){return e.render()},closer:!0,noscroll:!0,escClose:!0})}return Object.defineProperty(JokerUI.prototype,"button",{get:function(){var t=jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__button");return 0===t.length&&(t=jquery__WEBPACK_IMPORTED_MODULE_0___default()(_html_button_html__WEBPACK_IMPORTED_MODULE_2__.Z).appendTo("body")),t},enumerable:!1,configurable:!0}),JokerUI.prototype.show=function(){this.button.show()},JokerUI.prototype.render=function(){for(var result=jquery__WEBPACK_IMPORTED_MODULE_0___default()("
").html(_html_window_html__WEBPACK_IMPORTED_MODULE_3__.Z),row_template=jquery__WEBPACK_IMPORTED_MODULE_0___default()("#april-fools__window-row",result).html(),joke_container=jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__jokes",result),_i=0,_a=Object.values(this.joker.jokes);_i<_a.length;_i++){var joke=_a[_i],row=jquery__WEBPACK_IMPORTED_MODULE_0___default()(eval("`"+row_template+"`"));jquery__WEBPACK_IMPORTED_MODULE_0___default()('input[type="checkbox"]',row).prop("checked",joke.settings.enabled),joke_container.append(row)}return jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__content",result)},JokerUI}()},311:t=>{t.exports=jQuery},442:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.bubbleCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=window.innerWidth,c=window.innerHeight,a={x:s/2,y:s/2},l=[],h=[];const u=window.matchMedia("(prefers-reduced-motion: reduce)");function d(){if(u.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=s,e.height=c),r.addEventListener("mousemove",g),r.addEventListener("touchmove",f,{passive:!0}),r.addEventListener("touchstart",f,{passive:!0}),window.addEventListener("resize",p),A()}function p(t){s=window.innerWidth,c=window.innerHeight,o?(e.width=r.clientWidth,e.height=r.clientHeight):(e.width=s,e.height=c)}function f(t){if(t.touches.length>0)for(let e=0;e=0;t--)l[t].lifeSpan<0&&l.splice(t,1);0==l.length&&n.clearRect(0,0,s,c)}}(),i=requestAnimationFrame(A)}function m(){e.remove(),cancelAnimationFrame(i),r.removeEventListener("mousemove",g),r.removeEventListener("touchmove",f),r.removeEventListener("touchstart",f),window.addEventListener("resize",p)}function w(t,e,n){const i=Math.floor(60*Math.random()+60);this.initialLifeSpan=i,this.lifeSpan=i,this.velocity={x:(Math.random()<.5?-1:1)*(Math.random()/10),y:-1*Math.random()-.4},this.position={x:t,y:e},this.canv=n,this.baseDimension=4,this.update=function(t){this.position.x+=this.velocity.x,this.position.y+=this.velocity.y,this.velocity.x+=2*(Math.random()<.5?-1:1)/75,this.velocity.y-=Math.random()/600,this.lifeSpan--;const e=.2+(this.initialLifeSpan-this.lifeSpan)/this.initialLifeSpan;t.fillStyle="#e6f1f7",t.strokeStyle="#3a92c5",t.beginPath(),t.arc(this.position.x-this.baseDimension/2*e,this.position.y-this.baseDimension/2,this.baseDimension*e,0,2*Math.PI),t.stroke(),t.fill(),t.closePath()}}return u.onchange=()=>{u.matches?m():d()},d(),{destroy:m}},e.clockCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=window.innerWidth,c=window.innerHeight,a={x:s/2,y:s/2};const l=t&&t.dateColor||"blue",h=t&&t.faceColor||"black",u=t&&t.secondsColor||"red",d=t&&t.minutesColor||"black",p=t&&t.hoursColor||"black",f=.4;let g=new Date,y=g.getDate(),A=g.getYear()+1900;const m=(" "+["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"][g.getDay()]+" "+y+" "+["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"][g.getMonth()]+" "+A).split(""),w=["3","4","5","6","7","8","9","10","11","12","1","2"],v=w.length,_=["•","•","•"],x=["•","•","•","•"],b=["•","•","•","•","•"],E=360/v,C=360/m.length,M=45/6.5,O=[],j=[],L=[],k=[],B=[],R=[],S=[],D=[],T=[];var P=parseInt(m.length+v+_.length+x.length+b.length)+1;const I=window.matchMedia("(prefers-reduced-motion: reduce)");function W(){if(I.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=s,e.height=c),n.font="10px sans-serif",n.textAlign="center",n.textBaseline="middle";for(let t=0;t0)if(o){const e=r.getBoundingClientRect();a.x=t.touches[0].clientX-e.left,a.y=t.touches[0].clientY-e.top}else a.x=t.touches[0].clientX,a.y=t.touches[0].clientY}function F(t){if(o){const e=r.getBoundingClientRect();a.x=t.clientX-e.left,a.y=t.clientY-e.top}else a.x=t.clientX,a.y=t.clientY}function X(){!function(){L[0]=Math.round(O[0]+=(a.y-O[0])*f),k[0]=Math.round(j[0]+=(a.x-j[0])*f);for(let t=1;t=c-80&&(O[t-1]=c-80),j[t-1]>=s-80&&(j[t-1]=s-80)}(),function(){n.clearRect(0,0,s,c);const t=new Date,e=t.getSeconds(),i=Math.PI*(e-15)/30,o=t.getMinutes(),r=Math.PI*(o-15)/30,a=t.getHours(),l=Math.PI*(a-3)/6+Math.PI*parseInt(t.getMinutes())/360;for(let t=0;t{I.matches?U():W()},W(),{destroy:U}},e.emojiCursor=function(t){const e=t&&t.emoji||["😀","😂","😆","😊"];let n=t&&t.element,i=n||document.body,o=window.innerWidth,r=window.innerHeight;const s={x:o/2,y:o/2},c={x:o/2,y:o/2};let a=0;const l=[],h=[];let u,d,p;const f=window.matchMedia("(prefers-reduced-motion: reduce)");function g(){if(f.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;u=document.createElement("canvas"),d=u.getContext("2d"),u.style.top="0px",u.style.left="0px",u.style.pointerEvents="none",n?(u.style.position="absolute",i.appendChild(u),u.width=i.clientWidth,u.height=i.clientHeight):(u.style.position="fixed",document.body.appendChild(u),u.width=o,u.height=r),d.font="21px serif",d.textBaseline="middle",d.textAlign="center",e.forEach((t=>{let e=d.measureText(t),n=document.createElement("canvas"),i=n.getContext("2d");n.width=e.width,n.height=2*e.actualBoundingBoxAscent,i.textAlign="center",i.font="21px serif",i.textBaseline="middle",i.fillText(t,n.width/2,e.actualBoundingBoxAscent),h.push(n)})),i.addEventListener("mousemove",m,{passive:!0}),i.addEventListener("touchmove",A,{passive:!0}),i.addEventListener("touchstart",A,{passive:!0}),window.addEventListener("resize",y),v()}function y(t){o=window.innerWidth,r=window.innerHeight,n?(u.width=i.clientWidth,u.height=i.clientHeight):(u.width=o,u.height=r)}function A(t){if(t.touches.length>0)for(let e=0;e{if(n){const e=i.getBoundingClientRect();s.x=t.clientX-e.left,s.y=t.clientY-e.top}else s.x=t.clientX,s.y=t.clientY;Math.hypot(s.x-c.x,s.y-c.y)>1&&(w(s.x,s.y,h[Math.floor(Math.random()*e.length)]),c.x=s.x,c.y=s.y,a=t.timeStamp)}))}function w(t,e,n){l.push(new x(t,e,n))}function v(){!function(){if(0!=l.length){d.clearRect(0,0,o,r);for(let t=0;t=0;t--)l[t].lifeSpan<0&&l.splice(t,1);0==l.length&&d.clearRect(0,0,o,r)}}(),p=requestAnimationFrame(v)}function _(){u.remove(),cancelAnimationFrame(p),i.removeEventListener("mousemove",m),i.removeEventListener("touchmove",A),i.removeEventListener("touchstart",A),window.addEventListener("resize",y)}function x(t,e,n){const i=Math.floor(60*Math.random()+80);this.initialLifeSpan=i,this.lifeSpan=i,this.velocity={x:(Math.random()<.5?-1:1)*(Math.random()/2),y:.4*Math.random()+.8},this.position={x:t,y:e},this.canv=n,this.update=function(t){this.position.x+=this.velocity.x,this.position.y+=this.velocity.y,this.lifeSpan--,this.velocity.y+=.05;const e=Math.max(this.lifeSpan/this.initialLifeSpan,0);t.drawImage(this.canv,this.position.x-this.canv.width/2*e,this.position.y-this.canv.height/2,this.canv.width*e,this.canv.height*e)}}return f.onchange=()=>{f.matches?_():g()},g(),{destroy:_}},e.fairyDustCursor=function(t){let e=t&&t.colors||["#D61C59","#E7D84B","#1B8798"],n=t&&t.element,i=n||document.body,o=window.innerWidth,r=window.innerHeight;const s={x:o/2,y:o/2},c={x:o/2,y:o/2},a=[],l=[];let h,u,d;const p=window.matchMedia("(prefers-reduced-motion: reduce)");function f(){if(p.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;h=document.createElement("canvas"),u=h.getContext("2d"),h.style.top="0px",h.style.left="0px",h.style.pointerEvents="none",n?(h.style.position="absolute",i.appendChild(h),h.width=i.clientWidth,h.height=i.clientHeight):(h.style.position="fixed",i.appendChild(h),h.width=o,h.height=r),u.font="21px serif",u.textBaseline="middle",u.textAlign="center",e.forEach((t=>{let e=u.measureText("*"),n=document.createElement("canvas"),i=n.getContext("2d");n.width=e.width,n.height=e.actualBoundingBoxAscent+e.actualBoundingBoxDescent,i.fillStyle=t,i.textAlign="center",i.font="21px serif",i.textBaseline="middle",i.fillText("*",n.width/2,e.actualBoundingBoxAscent),l.push(n)})),i.addEventListener("mousemove",A),i.addEventListener("touchmove",y,{passive:!0}),i.addEventListener("touchstart",y,{passive:!0}),window.addEventListener("resize",g),w()}function g(t){o=window.innerWidth,r=window.innerHeight,n?(h.width=i.clientWidth,h.height=i.clientHeight):(h.width=o,h.height=r)}function y(t){if(t.touches.length>0)for(let e=0;e{if(n){const e=i.getBoundingClientRect();s.x=t.clientX-e.left,s.y=t.clientY-e.top}else s.x=t.clientX,s.y=t.clientY;Math.hypot(s.x-c.x,s.y-c.y)>1.5&&(m(s.x,s.y,l[Math.floor(Math.random()*e.length)]),c.x=s.x,c.y=s.y)}))}function m(t,e,n){a.push(new _(t,e,n))}function w(){!function(){if(0!=a.length){u.clearRect(0,0,o,r);for(let t=0;t=0;t--)a[t].lifeSpan<0&&a.splice(t,1);0==a.length&&u.clearRect(0,0,o,r)}}(),d=requestAnimationFrame(w)}function v(){h.remove(),cancelAnimationFrame(d),i.removeEventListener("mousemove",A),i.removeEventListener("touchmove",y),i.removeEventListener("touchstart",y),window.addEventListener("resize",g)}function _(t,e,n){const i=Math.floor(30*Math.random()+60);this.initialLifeSpan=i,this.lifeSpan=i,this.velocity={x:(Math.random()<.5?-1:1)*(Math.random()/2),y:.7*Math.random()+.9},this.position={x:t,y:e},this.canv=n,this.update=function(t){this.position.x+=this.velocity.x,this.position.y+=this.velocity.y,this.lifeSpan--,this.velocity.y+=.02;const e=Math.max(this.lifeSpan/this.initialLifeSpan,0);t.drawImage(this.canv,this.position.x-this.canv.width/2*e,this.position.y-this.canv.height/2,this.canv.width*e,this.canv.height*e)}}return p.onchange=()=>{p.matches?v():f()},f(),{destroy:v}},e.followingDotCursor=function(t){let e,n,i=t&&t.element,o=i||document.body,r=window.innerWidth,s=window.innerHeight,c={x:r/2,y:r/2},a=new function(t,e,n,i){this.position={x:t,y:e},this.width=10,this.lag=10,this.moveTowards=function(t,e,n){this.position.x+=(t-this.position.x)/this.lag,this.position.y+=(e-this.position.y)/this.lag,n.fillStyle=l,n.beginPath(),n.arc(this.position.x,this.position.y,this.width,0,2*Math.PI),n.fill(),n.closePath()}}(r/2,s/2,10,10),l=t?.color||"#323232a6";const h=window.matchMedia("(prefers-reduced-motion: reduce)");function u(){if(h.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",i?(e.style.position="absolute",o.appendChild(e),e.width=o.clientWidth,e.height=o.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=r,e.height=s),o.addEventListener("mousemove",p),window.addEventListener("resize",d),f()}function d(t){r=window.innerWidth,s=window.innerHeight,i?(e.width=o.clientWidth,e.height=o.clientHeight):(e.width=r,e.height=s)}function p(t){if(i){const e=o.getBoundingClientRect();c.x=t.clientX-e.left,c.y=t.clientY-e.top}else c.x=t.clientX,c.y=t.clientY}function f(){n.clearRect(0,0,r,s),a.moveTowards(c.x,c.y,n),requestAnimationFrame(f)}function g(){e.remove(),cancelAnimationFrame(f),o.removeEventListener("mousemove",p),window.addEventListener("resize",d)}return h.onchange=()=>{h.matches?g():u()},u(),{destroy:g}},e.ghostCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=window.innerWidth,c=window.innerHeight,a={x:s/2,y:s/2},l=[],h=new Image;h.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAYAAACk9eypAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADKADAAQAAAABAAAAEwAAAAAChpcNAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAABqElEQVQoFY3SPUvDQBgH8BREpRHExYiDgmLFl6WC+AYmWeyLg4i7buJX8DMpOujgyxGvUYeCgzhUQUSKKLUS0+ZyptXh8Z5Ti621ekPyJHl+uftfomhaf9Ei5JyxXKfynyEA6EYcLHpwyflT958GAQ7DTABNHd8EbtDbEH2BD5QEQmi2mM8P/Iq+A0SzszEg+3sPjDnDdVEtQKQbMUidHD3xVzf6A9UDEmEm+8h9KTqTVUjT+vB53aHrCbAPiceYq1dQI1Aqv4EhMll0jzv+Y0yiRgCnLRSYyDQHVoqUXe4uKL9l+L7GXC4vkMhE6eW/AOJs9k583ORDUyXMZ8F5SVHVVnllmPNKSFagAJ5DofaqGXw/gHBYg51dIldkmknY3tguv3jOtHR4+MqAzaraJXbEhqHhcQlwGSOi5pytVQHZLN5s0WNe8HPrLYlFsO20RPHkImxsbmHdLJFI76th7Z4SeuF53hTeFLvhRCJRCTKZKxgdnRDbW+iozFJbBMw14/ElwGYc0egMBMFzT21f5Rog33Z7dX02GBm7WV5ZfT5Nn5bE3zuCDe9UxdTpNvK+5AAAAABJRU5ErkJggg==";const u=window.matchMedia("(prefers-reduced-motion: reduce)");function d(){if(u.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=s,e.height=c),r.addEventListener("mousemove",g),r.addEventListener("touchmove",f,{passive:!0}),r.addEventListener("touchstart",f,{passive:!0}),window.addEventListener("resize",p),A()}function p(t){s=window.innerWidth,c=window.innerHeight,o?(e.width=r.clientWidth,e.height=r.clientHeight):(e.width=s,e.height=c)}function f(t){if(t.touches.length>0)for(let e=0;e=0;t--)l[t].lifeSpan<0&&l.splice(t,1);0==l.length&&n.clearRect(0,0,s,c)}}(),i=requestAnimationFrame(A)}function m(){e.remove(),cancelAnimationFrame(i),r.removeEventListener("mousemove",g),r.removeEventListener("touchmove",f),r.removeEventListener("touchstart",f),window.addEventListener("resize",p)}function w(t,e,n){this.initialLifeSpan=40,this.lifeSpan=40,this.position={x:t,y:e},this.image=n,this.update=function(t){this.lifeSpan--;const e=Math.max(this.lifeSpan/this.initialLifeSpan,0);t.globalAlpha=e,t.drawImage(this.image,this.position.x,this.position.y)}}return u.onchange=()=>{u.matches?m():d()},d(),{destroy:m}},e.rainbowCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=window.innerWidth,c=window.innerHeight,a={x:s/2,y:s/2},l=[];const h=t?.length||20,u=t?.colors||["#FE0000","#FD8C00","#FFE500","#119F0B","#0644B3","#C22EDC"],d=t?.size||3;let p=!1;const f=window.matchMedia("(prefers-reduced-motion: reduce)");function g(){if(f.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=s,e.height=c),r.addEventListener("mousemove",A),window.addEventListener("resize",y),m()}function y(t){s=window.innerWidth,c=window.innerHeight,o?(e.width=r.clientWidth,e.height=r.clientHeight):(e.width=s,e.height=c)}function A(t){if(o){const e=r.getBoundingClientRect();a.x=t.clientX-e.left,a.y=t.clientY-e.top}else a.x=t.clientX,a.y=t.clientY;if(!1===p){p=!0;for(let t=0;t{n.beginPath(),n.strokeStyle=e,t.length&&n.moveTo(t[0].x,t[0].y+i*(d-1)),t.forEach(((t,e)=>{0!==e&&n.lineTo(t.x,t.y+i*d)})),n.lineWidth=d,n.lineCap="round",n.stroke()}))}(),i=requestAnimationFrame(m)}function w(){e.remove(),cancelAnimationFrame(i),r.removeEventListener("mousemove",A),window.addEventListener("resize",y)}function v(t,e){this.position={x:t,y:e}}return f.onchange=()=>{f.matches?w():g()},g(),{destroy:w}},e.snowflakeCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=["❄️"],c=window.innerWidth,a=window.innerHeight,l={x:c/2,y:c/2},h=[],u=[];const d=window.matchMedia("(prefers-reduced-motion: reduce)");function p(){if(d.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=c,e.height=a),n.font="12px serif",n.textBaseline="middle",n.textAlign="center",s.forEach((t=>{let e=n.measureText(t),i=document.createElement("canvas"),o=i.getContext("2d");i.width=e.width,i.height=2*e.actualBoundingBoxAscent,o.textAlign="center",o.font="12px serif",o.textBaseline="middle",o.fillText(t,i.width/2,e.actualBoundingBoxAscent),u.push(i)})),r.addEventListener("mousemove",y),r.addEventListener("touchmove",g,{passive:!0}),r.addEventListener("touchstart",g,{passive:!0}),window.addEventListener("resize",f),m()}function f(t){c=window.innerWidth,a=window.innerHeight,o?(e.width=r.clientWidth,e.height=r.clientHeight):(e.width=c,e.height=a)}function g(t){if(t.touches.length>0)for(let e=0;e=0;t--)h[t].lifeSpan<0&&h.splice(t,1);0==h.length&&n.clearRect(0,0,c,a)}}(),i=requestAnimationFrame(m)}function w(){e.remove(),cancelAnimationFrame(i),r.removeEventListener("mousemove",y),r.removeEventListener("touchmove",g),r.removeEventListener("touchstart",g),window.addEventListener("resize",f)}function v(t,e,n){const i=Math.floor(60*Math.random()+80);this.initialLifeSpan=i,this.lifeSpan=i,this.velocity={x:(Math.random()<.5?-1:1)*(Math.random()/2),y:1+Math.random()},this.position={x:t,y:e},this.canv=n,this.update=function(t){this.position.x+=this.velocity.x,this.position.y+=this.velocity.y,this.lifeSpan--,this.velocity.x+=2*(Math.random()<.5?-1:1)/75,this.velocity.y-=Math.random()/300;const e=Math.max(this.lifeSpan/this.initialLifeSpan,0),n=2*this.lifeSpan*.0174533;t.translate(this.position.x,this.position.y),t.rotate(n),t.drawImage(this.canv,-this.canv.width/2*e,-this.canv.height/2,this.canv.width*e,this.canv.height*e),t.rotate(-n),t.translate(-this.position.x,-this.position.y)}}return d.onchange=()=>{d.matches?w():p()},p(),{destroy:w}},e.springyEmojiCursor=function(t){let e,n,i,o,r=t&&t.emoji||"🤪",s=t&&t.element,c=s||document.body,a=window.innerWidth,l=window.innerHeight,h={x:a/2,y:a/2},u=[];const d=window.matchMedia("(prefers-reduced-motion: reduce)");function p(){if(d.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",s?(e.style.position="absolute",c.appendChild(e),e.width=c.clientWidth,e.height=c.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=a,e.height=l),n.font="16px serif",n.textBaseline="middle",n.textAlign="center";let t=n.measureText(r),i=document.createElement("canvas"),h=i.getContext("2d");i.width=t.width,i.height=2*t.actualBoundingBoxAscent,h.textAlign="center",h.font="16px serif",h.textBaseline="middle",h.fillText(r,i.width/2,t.actualBoundingBoxAscent),o=i;let p=0;for(p=0;p<7;p++)u[p]=new _(o);c.addEventListener("mousemove",y),c.addEventListener("touchmove",g,{passive:!0}),c.addEventListener("touchstart",g,{passive:!0}),window.addEventListener("resize",f),A()}function f(t){a=window.innerWidth,l=window.innerHeight,s?(e.width=c.clientWidth,e.height=c.clientHeight):(e.width=a,e.height=l)}function g(t){if(t.touches.length>0)if(s){const e=c.getBoundingClientRect();h.x=t.touches[0].clientX-e.left,h.y=t.touches[0].clientY-e.top}else h.x=t.touches[0].clientX,h.y=t.touches[0].clientY}function y(t){if(s){const e=c.getBoundingClientRect();h.x=t.clientX-e.left,h.y=t.clientY-e.top}else h.x=t.clientX,h.y=t.clientY}function A(){!function(){e.width=e.width,u[0].position.x=h.x,u[0].position.y=h.y;for(let t=1;t<7;t++){let i=new w(0,0);t>0&&v(t-1,t,i),t<6&&v(t+1,t,i);let o,r,s=new w(10*-u[t].velocity.x,10*-u[t].velocity.y),c=new w((i.X+s.X)/1,(i.Y+s.Y)/1+50);u[t].velocity.x+=.01*c.X,u[t].velocity.y+=.01*c.Y,Math.abs(u[t].velocity.x)<.1&&Math.abs(u[t].velocity.y)<.1&&Math.abs(c.X)<.1&&Math.abs(c.Y)<.1&&(u[t].velocity.x=0,u[t].velocity.y=0),u[t].position.x+=u[t].velocity.x,u[t].position.y+=u[t].velocity.y,o=e.clientHeight,r=e.clientWidth,u[t].position.y>=o-11-1&&(u[t].velocity.y>0&&(u[t].velocity.y=.7*-u[t].velocity.y),u[t].position.y=o-11-1),u[t].position.x>=r-11&&(u[t].velocity.x>0&&(u[t].velocity.x=.7*-u[t].velocity.x),u[t].position.x=r-11-1),u[t].position.x<0&&(u[t].velocity.x<0&&(u[t].velocity.x=.7*-u[t].velocity.x),u[t].position.x=0),u[t].draw(n)}}(),i=requestAnimationFrame(A)}function m(){e.remove(),cancelAnimationFrame(i),c.removeEventListener("mousemove",y),c.removeEventListener("touchmove",g),c.removeEventListener("touchstart",g),window.addEventListener("resize",f)}function w(t,e){this.X=t,this.Y=e}function v(t,e,n){let i=u[t].position.x-u[e].position.x,o=u[t].position.y-u[e].position.y,r=Math.sqrt(i*i+o*o);if(r>10){let t=10*(r-10);n.X+=i/r*t,n.Y+=o/r*t}}function _(t){this.position={x:h.x,y:h.y},this.velocity={x:0,y:0},this.canv=t,this.draw=function(t){t.drawImage(this.canv,this.position.x-this.canv.width/2,this.position.y-this.canv.height/2,this.canv.width,this.canv.height)}}return d.onchange=()=>{d.matches?m():p()},p(),{destroy:m}},e.textFlag=function(t){let e,n,i,o=t||{},r=t&&t.element,s=r||document.body,c=o.text?" "+t.text:" Your Text Here",a=o.font||"monospace",l=o.textSize||12,h=l+"px "+a,u=o.gap||l+2,d=0,p=[],f=window.innerWidth,g=window.innerHeight,y={x:f/2,y:f/2};for(let t=0;t0;t--)p[t].x=p[t-1].x+u,p[t].y=p[t-1].y,n.font=h,n.fillText(p[t].letter,p[t].x,p[t].y);let i=p[0].x,o=p[0].y;i+=(y.x-i)/5+t+2,o+=(y.y-o)/5+e,p[0].x=i,p[0].y=o}(),i=requestAnimationFrame(_)}function x(){e.remove(),cancelAnimationFrame(i),s.removeEventListener("mousemove",v),window.addEventListener("resize",w)}return A.onchange=()=>{A.matches?x():m()},m(),{destroy:x}},e.trailingCursor=function(t){let e,n,i,o=t&&t.element,r=o||document.body,s=window.innerWidth,c=window.innerHeight,a={x:s/2,y:s/2},l=[];const h=t?.particles||15,u=t?.rate||.4,d=t?.baseImageSrc||"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAYAAACk9eypAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADKADAAQAAAABAAAAEwAAAAAChpcNAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAABqElEQVQoFY3SPUvDQBgH8BREpRHExYiDgmLFl6WC+AYmWeyLg4i7buJX8DMpOujgyxGvUYeCgzhUQUSKKLUS0+ZyptXh8Z5Ti621ekPyJHl+uftfomhaf9Ei5JyxXKfynyEA6EYcLHpwyflT958GAQ7DTABNHd8EbtDbEH2BD5QEQmi2mM8P/Iq+A0SzszEg+3sPjDnDdVEtQKQbMUidHD3xVzf6A9UDEmEm+8h9KTqTVUjT+vB53aHrCbAPiceYq1dQI1Aqv4EhMll0jzv+Y0yiRgCnLRSYyDQHVoqUXe4uKL9l+L7GXC4vkMhE6eW/AOJs9k583ORDUyXMZ8F5SVHVVnllmPNKSFagAJ5DofaqGXw/gHBYg51dIldkmknY3tguv3jOtHR4+MqAzaraJXbEhqHhcQlwGSOi5pytVQHZLN5s0WNe8HPrLYlFsO20RPHkImxsbmHdLJFI76th7Z4SeuF53hTeFLvhRCJRCTKZKxgdnRDbW+iozFJbBMw14/ElwGYc0egMBMFzT21f5Rog33Z7dX02GBm7WV5ZfT5Nn5bE3zuCDe9UxdTpNvK+5AAAAABJRU5ErkJggg==";let p=!1,f=new Image;f.src=d;const g=window.matchMedia("(prefers-reduced-motion: reduce)");function y(){if(g.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init"),!1;e=document.createElement("canvas"),n=e.getContext("2d"),e.style.top="0px",e.style.left="0px",e.style.pointerEvents="none",o?(e.style.position="absolute",r.appendChild(e),e.width=r.clientWidth,e.height=r.clientHeight):(e.style.position="fixed",document.body.appendChild(e),e.width=s,e.height=c),r.addEventListener("mousemove",m),window.addEventListener("resize",A),w()}function A(t){s=window.innerWidth,c=window.innerHeight,o?(e.width=r.clientWidth,e.height=r.clientHeight):(e.width=s,e.height=c)}function m(t){if(o){const e=r.getBoundingClientRect();a.x=t.clientX-e.left,a.y=t.clientY-e.top}else a.x=t.clientX,a.y=t.clientY;if(!1===p){p=!0;for(let t=0;t{g.matches?v():y()},y(),{destroy:v}}}},__webpack_module_cache__={};function __webpack_require__(t){var e=__webpack_module_cache__[t];if(void 0!==e)return e.exports;var n=__webpack_module_cache__[t]={exports:{}};return __webpack_modules__[t](n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return __webpack_require__.d(e,{a:e}),e},__webpack_require__.d=(t,e)=>{for(var n in e)__webpack_require__.o(e,n)&&!__webpack_require__.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},__webpack_require__.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var __webpack_exports__={};(()=>{var t,e,n=(t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)},function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}),i=function(){function t(){}return t.prototype.check=function(t){return Math.random()<.01*t},t.prototype.enable=function(){this.settings.enabled=!0},t.prototype.disable=function(){this.settings.enabled=!1},t.prototype.toggle=function(t){void 0===t&&(t=null),this.settings.enabled=null===t?!this.settings.enabled:t},t}(),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e}(i),r=__webpack_require__(562),s=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),c=function(){function t(){this.ui=new r.d(this),this.core_settings=new a,this.jokes={}}return t.prototype.check=function(t){return Math.random()<.01*t},t.prototype.add=function(t){this.jokes[t.id]=t},t.prototype.addCustom=function(t,e,n){void 0===n&&(n=null);var o=new(function(n){function i(){var e=null!==n&&n.apply(this,arguments)||this;return e.id=t,e.title="Пользовательская шутка",e.description="Для шутки не определено описание",e.settings={chance:10,enabled:!0},e}return s(i,n),i.prototype.start=function(){e.call(this,this.settings)},i}(i));return Object.assign(o.settings,null!=n?n:{}),this.add(o),o},Object.defineProperty(t.prototype,"settings",{get:function(){var t={};t.core=this.core_settings;for(var e=0,n=Object.entries(this.jokes);e=0)return!0;var t=new Date,e=t.getMonth()+1,n=t.getDate();return 4===e&&1===n&&this.check(this.core_settings.chance)},t.prototype.regularStart=function(){this.regularCheck()&&(this.ui.show(),this.startAll())},t}(),a=function(){this.chance=100,this.enabled=!0,this.testers=[]},l=__webpack_require__(311),h=__webpack_require__.n(l),u=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),d=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.id="shake",e.title="Форумо-трясение",e.description="Страница форума начинает трястись",e.settings=new p,e.data_name="april-fools-shake",e}return u(e,t),e.prototype.rand=function(t){return t+this.settings.force*(2*Math.random()-1)},e.prototype.start=function(){var t=this;this.items=h()(this.settings.selector),this.items.each((function(e,n){var i={};t.settings.directions.forEach((function(t){i[t]=parseInt(h()(n).css("margin-"+t))})),h()(n).data(t.data_name,i)})),this.interval_id=setInterval((function(){t.items.each((function(e,n){for(var i=h()(n).data(t.data_name),o=0,r=Object.entries(i);o0?"тся":"ться"})))}))},e}(i),y=function(){this.enabled=!0,this.chance=20,this.selector=".post-content"},A=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),m=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.id="mirror",e.title="Зеркало",e.description="Элементы форума отражаются (по крайней мере, пытаются)",e.settings=new w,e}return A(e,t),e.prototype.start=function(){h()(".post, .post h3, .post-links, .post-author, .post-content").css("transform","scaleX(-1)").css("-moz-transform","scaleX(-1)").css("-moz-transform","scaleX(-1)").css("filter","FlipH").css("-ms-filter",'"FlipH"'),h()(".post-links, .post-links ul, .post h3 span").css("margin-left","0"),h()(".post h3 span").css("margin-right","25em")},e}(i),w=function(){this.enabled=!1,this.chance=30},v=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),_=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.id="carnival",e.title="Карнавал",e.description="Аватарки приобретают интересные цвета",e.settings=new x,e}return v(e,t),e.prototype.start=function(){var t=this;h()(this.settings.selector).each((function(e,n){for(var i=[],o=0,r=Object.entries(t.settings.variants);o0&&h()(n).css({filter:i.join(" ")})}))},e}(i),x=function(){this.enabled=!0,this.chance=30,this.selector='img[src*="/avatars/"]',this.variant_chance=20,this.variants={"sepia({0}%)":100,"saturate({0}%)":100,"hue-rotate({0}deg)":360,"invert({0}%)":100}},b=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),E=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.id="crazy_letters",e.title="Мама, Я сОшЛа С уМа!",e.description="иМеНа ЗаБоРчИкОм",e.settings=new C,e}return b(e,t),e.prototype.start=function(){var t=this;h()(this.settings.selector).each((function(e,n){for(var i=h()(t).text(),o="",r=0;r0;o--){var r=Math.floor(Math.random()*(o+1));e=[i[r],i[o]],i[o]=e[0],i[r]=e[1]}return O(O([n[0]],i,!0),[n[n.length-1]],!1).join("")},e.prototype.processNode=function(t){var e;t.textContent=null===(e=t.textContent)||void 0===e?void 0:e.replace(/([А-Яа-яA-Za-z]+)/gm,this.shuffleLetters)},e.prototype.start=function(){var t=this;h()(this.settings.selector).find("*").contents().filter((function(t,e){return e.nodeType===Node.TEXT_NODE})).each((function(e,n){return t.processNode(n)}))},e}(i),L=function(){this.enabled=!0,this.chance=20,this.selector=".post-content",this.shuffle_chance=50},k=function(){var t=function(e,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},t(e,n)};return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}(),B=__webpack_require__(442),R=function(t){function n(){var e=null!==t&&t.apply(this,arguments)||this;return e.id="cursor_effects",e.title="Красивый курсор",e.description="Эффекты, следующие за курсором",e.settings=new T,e}return k(n,t),n.prototype.enableAll=function(){for(var t=0,e=Object.keys(this.settings.effects);t0&&o[o.length-1])||6!==c[0]&&2!==c[0])){s=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]>>16,2246822507)^Math.imul(o^o>>>13,3266489909);var c=4294967296*(2097151&(o=Math.imul(o^o>>>16,2246822507)^Math.imul(i^i>>>13,3266489909)))+(i>>>0);return Math.floor(Math.pow(Math.sin(c),2)*n)%n},e.prototype.resetSeed=function(){new Date;var t=60*(new Date).getUTCHours()+(new Date).getUTCMinutes();this.seed=Math.floor(t/this.settings.change_frequency),console.log("Seed reset:",t,this.seed)},e.prototype.selectRandom=function(t,e){for(var n=Object.keys(e),i=n.reduce((function(t,n){return t+e[n]}),0),o=this.prng(t,this.seed++,i),r=0,s=0,c=n;s=0,enabled:e.indexOf("!")<0,weight:10*(e.indexOf("$")>=0?.5:1)*(e.indexOf("%")>=0?.5:1)*(e.indexOf("^")>=0?2:1)}))})),n}window.BuildStupdiTitleVariant=q,window.AprilJokes=(S=[d,g,m,_,E,j,R,F],D=new c,S.forEach((function(t){D.add(new t)})),$((function(){D.regularStart()})),D)})()})(); \ No newline at end of file +(()=>{"use strict";var __webpack_modules__={525:(e,t,i)=>{i.d(t,{Z:()=>n});const n=' '},554:(e,t,i)=>{i.d(t,{Z:()=>n});const n=' '},95:(e,t,i)=>{i.d(t,{Z:()=>n});const n='
'},562:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.d(__webpack_exports__,{d:()=>JokerUI});var jquery__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(311),jquery__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__),_html_button_html__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(525),_html_styles_html__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(554),_html_window_html__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(95);class JokerUI{constructor(e){this.joker=e,jquery__WEBPACK_IMPORTED_MODULE_0___default()('link[rel="stylesheet"]').eq(0).before(_html_styles_html__WEBPACK_IMPORTED_MODULE_1__.Z);e=this.button;e.hide(),e.mybbModal({title:"Настройки первоапрельских шуток",content:()=>this.render(),closer:!0,noscroll:!0,escClose:!0})}get button(){let e=jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__button");return e=0===e.length?jquery__WEBPACK_IMPORTED_MODULE_0___default()(_html_button_html__WEBPACK_IMPORTED_MODULE_2__.Z).appendTo("body"):e}show(){this.button.show()}render(){const result=jquery__WEBPACK_IMPORTED_MODULE_0___default()("
").html(_html_window_html__WEBPACK_IMPORTED_MODULE_3__.Z),row_template=jquery__WEBPACK_IMPORTED_MODULE_0___default()("#april-fools__window-row",result).html(),joke_container=jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__jokes",result);for(const joke of Object.values(this.joker.jokes)){const row=jquery__WEBPACK_IMPORTED_MODULE_0___default()(eval("`"+row_template+"`"));jquery__WEBPACK_IMPORTED_MODULE_0___default()('input[type="checkbox"]',row).prop("checked",joke.settings.enabled).on("click",e=>this.joker.toggleJoke(joke.id,e.currentTarget.checked)),joke_container.append(row)}return jquery__WEBPACK_IMPORTED_MODULE_0___default()("button",result).on("click",async()=>{await this.joker.clearUserStates(),window.location.reload()}),jquery__WEBPACK_IMPORTED_MODULE_0___default()(".april-fools__content",result)}}},311:e=>{e.exports=jQuery},442:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.bubbleCursor=function(e){let t,i,n,o=e&&e.element,s=o||document.body,r=window.innerWidth,a=window.innerHeight,l={x:r/2,y:r/2},c=[],h=[];const d=window.matchMedia("(prefers-reduced-motion: reduce)");function u(){if(d.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),i=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",o?(t.style.position="absolute",s.appendChild(t),t.width=s.clientWidth,t.height=s.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=r,t.height=a),s.addEventListener("mousemove",f),s.addEventListener("touchmove",g,{passive:!0}),s.addEventListener("touchstart",g,{passive:!0}),window.addEventListener("resize",p),m()}function p(e){r=window.innerWidth,a=window.innerHeight,o?(t.width=s.clientWidth,t.height=s.clientHeight):(t.width=r,t.height=a)}function g(t){if(0{(d.matches?w:u)()},u(),{destroy:w}},t.clockCursor=function(e){let t,s,r,i=e&&e.element,n=i||document.body,a=window.innerWidth,l=window.innerHeight,c={x:a/2,y:a/2};const W=e&&e.dateColor||"blue",T=e&&e.faceColor||"black",Y=e&&e.secondsColor||"red",H=e&&e.minutesColor||"black",P=e&&e.hoursColor||"black",h=.4;var e=new Date,F=e.getDate(),U=e.getYear()+1900;const o=(" "+["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"][e.getDay()]+" "+F+" "+["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"][e.getMonth()]+" "+U).split(""),d=["3","4","5","6","7","8","9","10","11","12","1","2"],u=d.length,p=["•","•","•"],g=["•","•","•","•"],f=["•","•","•","•","•"],A=360/u,m=360/o.length,w=45/6.5,_=[],v=[],y=[],x=[],E=[],b=[],M=[],C=[],k=[];var j=parseInt(o.length+u+p.length+g.length+f.length)+1;const L=window.matchMedia("(prefers-reduced-motion: reduce)");function B(){if(L.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),s=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",i?(t.style.position="absolute",n.appendChild(t),t.width=n.clientWidth,t.height=n.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=a,t.height=l),s.font="10px sans-serif",s.textAlign="center",s.textBaseline="middle";for(let e=0;e=l-80&&(_[e-1]=l-80),v[e-1]>=a-80&&(v[e-1]=a-80);s.clearRect(0,0,a,l);var e=new Date,t=e.getSeconds(),i=Math.PI*(t-15)/30,t=e.getMinutes(),n=Math.PI*(t-15)/30,t=e.getHours(),o=Math.PI*(t-3)/6+Math.PI*parseInt(e.getMinutes())/360;for(let e=0;e{(L.matches?O:B)()},B(),{destroy:O}},t.emojiCursor=function(e){const t=e&&e.emoji||["😀","😂","😆","😊"];let i=e&&e.element,n=i||document.body,o=window.innerWidth,s=window.innerHeight;const r={x:o/2,y:o/2},a={x:o/2,y:o/2};let l=0;const c=[],h=[];let d,u,p;const g=window.matchMedia("(prefers-reduced-motion: reduce)");function f(){if(g.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");d=document.createElement("canvas"),u=d.getContext("2d"),d.style.top="0px",d.style.left="0px",d.style.pointerEvents="none",i?(d.style.position="absolute",n.appendChild(d),d.width=n.clientWidth,d.height=n.clientHeight):(d.style.position="fixed",document.body.appendChild(d),d.width=o,d.height=s),u.font="21px serif",u.textBaseline="middle",u.textAlign="center",t.forEach(e=>{var t=u.measureText(e),i=document.createElement("canvas"),n=i.getContext("2d");i.width=t.width,i.height=2*t.actualBoundingBoxAscent,n.textAlign="center",n.font="21px serif",n.textBaseline="middle",n.fillText(e,i.width/2,t.actualBoundingBoxAscent),h.push(i)}),n.addEventListener("mousemove",w,{passive:!0}),n.addEventListener("touchmove",m,{passive:!0}),n.addEventListener("touchstart",m,{passive:!0}),window.addEventListener("resize",A),v()}function A(e){o=window.innerWidth,s=window.innerHeight,i?(d.width=n.clientWidth,d.height=n.clientHeight):(d.width=o,d.height=s)}function m(t){if(0{if(i){const t=n.getBoundingClientRect();r.x=e.clientX-t.left,r.y=e.clientY-t.top}else r.x=e.clientX,r.y=e.clientY;1{(g.matches?y:f)()},f(),{destroy:y}},t.fairyDustCursor=function(e){let t=e&&e.colors||["#D61C59","#E7D84B","#1B8798"],i=e&&e.element,n=i||document.body,o=window.innerWidth,s=window.innerHeight;const r={x:o/2,y:o/2},a={x:o/2,y:o/2},l=[],c=[];let h,d,u;const p=window.matchMedia("(prefers-reduced-motion: reduce)");function g(){if(p.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");h=document.createElement("canvas"),d=h.getContext("2d"),h.style.top="0px",h.style.left="0px",h.style.pointerEvents="none",i?(h.style.position="absolute",n.appendChild(h),h.width=n.clientWidth,h.height=n.clientHeight):(h.style.position="fixed",n.appendChild(h),h.width=o,h.height=s),d.font="21px serif",d.textBaseline="middle",d.textAlign="center",t.forEach(e=>{var t=d.measureText("*"),i=document.createElement("canvas"),n=i.getContext("2d");i.width=t.width,i.height=t.actualBoundingBoxAscent+t.actualBoundingBoxDescent,n.fillStyle=e,n.textAlign="center",n.font="21px serif",n.textBaseline="middle",n.fillText("*",i.width/2,t.actualBoundingBoxAscent),c.push(i)}),n.addEventListener("mousemove",m),n.addEventListener("touchmove",A,{passive:!0}),n.addEventListener("touchstart",A,{passive:!0}),window.addEventListener("resize",f),_()}function f(e){o=window.innerWidth,s=window.innerHeight,i?(h.width=n.clientWidth,h.height=n.clientHeight):(h.width=o,h.height=s)}function A(t){if(0{if(i){const t=n.getBoundingClientRect();r.x=e.clientX-t.left,r.y=e.clientY-t.top}else r.x=e.clientX,r.y=e.clientY;1.5{(p.matches?v:g)()},g(),{destroy:v}},t.followingDotCursor=function(e){let t,i,n=e&&e.element,o=n||document.body,s=window.innerWidth,r=window.innerHeight,a={x:s/2,y:s/2},l=new function(e,t,i,n){this.position={x:e,y:t},this.width=10,this.lag=10,this.moveTowards=function(e,t,i){this.position.x+=(e-this.position.x)/this.lag,this.position.y+=(t-this.position.y)/this.lag,i.fillStyle=c,i.beginPath(),i.arc(this.position.x,this.position.y,this.width,0,2*Math.PI),i.fill(),i.closePath()}}(s/2,r/2),c=e?.color||"#323232a6";const h=window.matchMedia("(prefers-reduced-motion: reduce)");function d(){if(h.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),i=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",n?(t.style.position="absolute",o.appendChild(t),t.width=o.clientWidth,t.height=o.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=s,t.height=r),o.addEventListener("mousemove",p),window.addEventListener("resize",u),g()}function u(e){s=window.innerWidth,r=window.innerHeight,n?(t.width=o.clientWidth,t.height=o.clientHeight):(t.width=s,t.height=r)}function p(e){var t;n?(t=o.getBoundingClientRect(),a.x=e.clientX-t.left,a.y=e.clientY-t.top):(a.x=e.clientX,a.y=e.clientY)}function g(){i.clearRect(0,0,s,r),l.moveTowards(a.x,a.y,i),requestAnimationFrame(g)}function f(){t.remove(),cancelAnimationFrame(g),o.removeEventListener("mousemove",p),window.addEventListener("resize",u)}return h.onchange=()=>{(h.matches?f:d)()},d(),{destroy:f}},t.ghostCursor=function(e){let t,i,n,o=e&&e.element,s=o||document.body,r=window.innerWidth,a=window.innerHeight,l={x:r/2,y:r/2},c=[],h=new Image;h.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAYAAACk9eypAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADKADAAQAAAABAAAAEwAAAAAChpcNAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAABqElEQVQoFY3SPUvDQBgH8BREpRHExYiDgmLFl6WC+AYmWeyLg4i7buJX8DMpOujgyxGvUYeCgzhUQUSKKLUS0+ZyptXh8Z5Ti621ekPyJHl+uftfomhaf9Ei5JyxXKfynyEA6EYcLHpwyflT958GAQ7DTABNHd8EbtDbEH2BD5QEQmi2mM8P/Iq+A0SzszEg+3sPjDnDdVEtQKQbMUidHD3xVzf6A9UDEmEm+8h9KTqTVUjT+vB53aHrCbAPiceYq1dQI1Aqv4EhMll0jzv+Y0yiRgCnLRSYyDQHVoqUXe4uKL9l+L7GXC4vkMhE6eW/AOJs9k583ORDUyXMZ8F5SVHVVnllmPNKSFagAJ5DofaqGXw/gHBYg51dIldkmknY3tguv3jOtHR4+MqAzaraJXbEhqHhcQlwGSOi5pytVQHZLN5s0WNe8HPrLYlFsO20RPHkImxsbmHdLJFI76th7Z4SeuF53hTeFLvhRCJRCTKZKxgdnRDbW+iozFJbBMw14/ElwGYc0egMBMFzT21f5Rog33Z7dX02GBm7WV5ZfT5Nn5bE3zuCDe9UxdTpNvK+5AAAAABJRU5ErkJggg==";const d=window.matchMedia("(prefers-reduced-motion: reduce)");function u(){if(d.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),i=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",o?(t.style.position="absolute",s.appendChild(t),t.width=s.clientWidth,t.height=s.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=r,t.height=a),s.addEventListener("mousemove",f),s.addEventListener("touchmove",g,{passive:!0}),s.addEventListener("touchstart",g,{passive:!0}),window.addEventListener("resize",p),m()}function p(e){r=window.innerWidth,a=window.innerHeight,o?(t.width=s.clientWidth,t.height=s.clientHeight):(t.width=r,t.height=a)}function g(t){if(0{(d.matches?w:u)()},u(),{destroy:w}},t.rainbowCursor=function(e){let t,r,i,n=e&&e.element,o=n||document.body,a=window.innerWidth,l=window.innerHeight,c={x:a/2,y:a/2},h=[];const s=e?.length||20,d=e?.colors||["#FE0000","#FD8C00","#FFE500","#119F0B","#0644B3","#C22EDC"],u=e?.size||3;let p=!1;const g=window.matchMedia("(prefers-reduced-motion: reduce)");function f(){if(g.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),r=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",n?(t.style.position="absolute",o.appendChild(t),t.width=o.clientWidth,t.height=o.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=a,t.height=l),o.addEventListener("mousemove",m),window.addEventListener("resize",A),w()}function A(e){a=window.innerWidth,l=window.innerHeight,n?(t.width=o.clientWidth,t.height=o.clientHeight):(t.width=a,t.height=l)}function m(e){if(n){const t=o.getBoundingClientRect();c.x=e.clientX-t.left,c.y=e.clientY-t.top}else c.x=e.clientX,c.y=e.clientY;if(!1===p){p=!0;for(let e=0;e{r.beginPath(),r.strokeStyle=e,n.length&&r.moveTo(n[0].x,n[0].y+i*(u-1)),n.forEach((e,t)=>{0!==t&&r.lineTo(e.x,e.y+i*u)}),r.lineWidth=u,r.lineCap="round",r.stroke()})}i=requestAnimationFrame(w)}function _(){t.remove(),cancelAnimationFrame(i),o.removeEventListener("mousemove",m),window.addEventListener("resize",A)}function v(e,t){this.position={x:e,y:t}}return g.onchange=()=>{(g.matches?_:f)()},f(),{destroy:_}},t.snowflakeCursor=function(e){let t,o,i,n=e&&e.element,s=n||document.body,r=["❄️"],a=window.innerWidth,l=window.innerHeight,c={x:a/2,y:a/2},h=[],d=[];const u=window.matchMedia("(prefers-reduced-motion: reduce)");function p(){if(u.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),o=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",n?(t.style.position="absolute",s.appendChild(t),t.width=s.clientWidth,t.height=s.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=a,t.height=l),o.font="12px serif",o.textBaseline="middle",o.textAlign="center",r.forEach(e=>{var t=o.measureText(e),i=document.createElement("canvas"),n=i.getContext("2d");i.width=t.width,i.height=2*t.actualBoundingBoxAscent,n.textAlign="center",n.font="12px serif",n.textBaseline="middle",n.fillText(e,i.width/2,t.actualBoundingBoxAscent),d.push(i)}),s.addEventListener("mousemove",A),s.addEventListener("touchmove",f,{passive:!0}),s.addEventListener("touchstart",f,{passive:!0}),window.addEventListener("resize",g),w()}function g(e){a=window.innerWidth,l=window.innerHeight,n?(t.width=s.clientWidth,t.height=s.clientHeight):(t.width=a,t.height=l)}function f(t){if(0{(u.matches?_:p)()},p(),{destroy:_}},t.springyEmojiCursor=function(e){let o,s,n,r,a=e&&e.emoji||"🤪",l=e&&e.element,c=l||document.body,h=window.innerWidth,d=window.innerHeight,u={x:h/2,y:h/2},p=[];const g=window.matchMedia("(prefers-reduced-motion: reduce)");function t(){if(g.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");o=document.createElement("canvas"),s=o.getContext("2d"),o.style.top="0px",o.style.left="0px",o.style.pointerEvents="none",l?(o.style.position="absolute",c.appendChild(o),o.width=c.clientWidth,o.height=c.clientHeight):(o.style.position="fixed",document.body.appendChild(o),o.width=h,o.height=d),s.font="16px serif",s.textBaseline="middle",s.textAlign="center";var e=s.measureText(a),t=document.createElement("canvas"),i=t.getContext("2d");t.width=e.width,t.height=2*e.actualBoundingBoxAscent,i.textAlign="center",i.font="16px serif",i.textBaseline="middle",i.fillText(a,t.width/2,e.actualBoundingBoxAscent),r=t;let n=0;for(n=0;n<7;n++)p[n]=new y(r);c.addEventListener("mousemove",m),c.addEventListener("touchmove",A,{passive:!0}),c.addEventListener("touchstart",A,{passive:!0}),window.addEventListener("resize",f),w()}function f(e){h=window.innerWidth,d=window.innerHeight,l?(o.width=c.clientWidth,o.height=c.clientHeight):(o.width=h,o.height=d)}function A(e){var t;0=i-11-1&&(0=t-11&&(0{(g.matches?i:t)()},t(),{destroy:i}},t.textFlag=function(e){let t,o,s,i=e||{},n=e&&e.element,r=n||document.body,a=i.text?" "+e.text:" Your Text Here",l=i.font||"monospace",c=i.textSize||12,h=c+"px "+l,d=i.gap||c+2,u=0,p=[],g=window.innerWidth,f=window.innerHeight,A={x:g/2,y:g/2};for(let e=0;e{(m.matches?x:w)()},w(),{destroy:x}},t.trailingCursor=function(e){let t,s,i,o=e&&e.element,r=o||document.body,a=window.innerWidth,l=window.innerHeight,c={x:a/2,y:a/2},h=[];const d=e?.particles||15,u=e?.rate||.4,n=e?.baseImageSrc||"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAATCAYAAACk9eypAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADKADAAQAAAABAAAAEwAAAAAChpcNAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAABqElEQVQoFY3SPUvDQBgH8BREpRHExYiDgmLFl6WC+AYmWeyLg4i7buJX8DMpOujgyxGvUYeCgzhUQUSKKLUS0+ZyptXh8Z5Ti621ekPyJHl+uftfomhaf9Ei5JyxXKfynyEA6EYcLHpwyflT958GAQ7DTABNHd8EbtDbEH2BD5QEQmi2mM8P/Iq+A0SzszEg+3sPjDnDdVEtQKQbMUidHD3xVzf6A9UDEmEm+8h9KTqTVUjT+vB53aHrCbAPiceYq1dQI1Aqv4EhMll0jzv+Y0yiRgCnLRSYyDQHVoqUXe4uKL9l+L7GXC4vkMhE6eW/AOJs9k583ORDUyXMZ8F5SVHVVnllmPNKSFagAJ5DofaqGXw/gHBYg51dIldkmknY3tguv3jOtHR4+MqAzaraJXbEhqHhcQlwGSOi5pytVQHZLN5s0WNe8HPrLYlFsO20RPHkImxsbmHdLJFI76th7Z4SeuF53hTeFLvhRCJRCTKZKxgdnRDbW+iozFJbBMw14/ElwGYc0egMBMFzT21f5Rog33Z7dX02GBm7WV5ZfT5Nn5bE3zuCDe9UxdTpNvK+5AAAAABJRU5ErkJggg==";let p=!1,g=new Image;g.src=n;const f=window.matchMedia("(prefers-reduced-motion: reduce)");function A(){if(f.matches)return console.log("This browser has prefers reduced motion turned on, so the cursor did not init");t=document.createElement("canvas"),s=t.getContext("2d"),t.style.top="0px",t.style.left="0px",t.style.pointerEvents="none",o?(t.style.position="absolute",r.appendChild(t),t.width=r.clientWidth,t.height=r.clientHeight):(t.style.position="fixed",document.body.appendChild(t),t.width=a,t.height=l),r.addEventListener("mousemove",w),window.addEventListener("resize",m),_()}function m(e){a=window.innerWidth,l=window.innerHeight,o?(t.width=r.clientWidth,t.height=r.clientHeight):(t.width=a,t.height=l)}function w(e){if(o){const t=r.getBoundingClientRect();c.x=e.clientX-t.left,c.y=e.clientY-t.top}else c.x=e.clientX,c.y=e.clientY;if(!1===p){p=!0;for(let e=0;e{(f.matches?v:A)()},A(),{destroy:v}}}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];return void 0!==t||(t=__webpack_module_cache__[e]={exports:{}},__webpack_modules__[e](t,t.exports,__webpack_require__)),t.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var i in t)__webpack_require__.o(t,i)&&!__webpack_require__.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var __webpack_exports__={};(()=>{class o{check(e){return Math.random()<.01*e}enable(){this.settings.enabled=!0}disable(){this.settings.enabled=!1}toggle(e=null){this.settings.enabled=null===e?!this.settings.enabled:e}}class i extends o{}var e=__webpack_require__(562);class n{constructor(){this.ui=new e.d(this),this.core_settings=new t,this.jokes={}}check(e){return Math.random()<.01*e}add(e){this.jokes[e.id]=e}addCustom(e,t,i=null){var n=new class extends o{constructor(){super(...arguments),this.id=e,this.title="Пользовательская шутка",this.description="Для шутки не определено описание",this.settings={chance:10,enabled:!0}}start(){t.call(this,this.settings)}};return Object.assign(n.settings,null!=i?i:{}),this.add(n),n}get settings(){var e={};e.core=this.core_settings;for(const n of Object.entries(this.jokes)){var t=n[0],i=n[1];e[t]=i.settings}return e}set settings(e){for(const n of Object.entries(e)){var t=n[0],i=n[1],t="core"===t?this.core_settings:this.jokes[t].settings;Object.assign(t,i)}}enable(){this.core_settings.enabled=!0}disable(){this.core_settings.enabled=!1}enableAll(){for(const e of Object.keys(this.jokes))this.jokes[e].enable()}disableAll(){for(const e of Object.keys(this.jokes))this.jokes[e].disable()}toggleJoke(e,t){e=this.jokes[e];e.settings.enabled=t,e instanceof i&&!t&&e.stop(),this.saveUserStates()}saveUserStates(){var e={};for(const t of Object.keys(this.jokes))e[t]=this.jokes[t].settings.enabled;fetch("/api.php?"+$.param({method:"storage.set",user_id:window.UserID,key:"april-fools",token:window.ForumAPITicket,value:JSON.stringify(e),timer:1440}))}async loadUserStates(){var e=await(await fetch("/api.php?"+$.param({method:"storage.get",user_id:window.UserID,key:"april-fools"}))).json();if(!e.error){var t=JSON.parse(e.response.storage.data["april-fools"]);for(const i of Object.keys(this.jokes))this.jokes[i].settings.enabled=t[i]}}async clearUserStates(){await fetch("/api.php?"+$.param({method:"storage.delete",user_id:window.UserID,key:"april-fools",token:window.ForumAPITicket}))}start(e,t=!1){e in this.jokes&&(e=this.jokes[e],t||e.settings.enabled&&this.check(e.settings.chance))&&e.start()}startAll(e=!1){for(const t of Object.keys(this.jokes))this.start(t,e)}regularCheck(){var e,t;return!!this.core_settings.enabled&&(0<=this.core_settings.testers.indexOf(window.UserID)||(e=(t=new Date).getMonth()+1,t=t.getDate(),4===e&&1===t&&this.check(this.core_settings.chance)))}async regularStart(){this.regularCheck()&&(await this.loadUserStates(),this.ui.show(),this.startAll())}}class t{constructor(){this.chance=100,this.enabled=!0,this.testers=[]}}var s,r=__webpack_require__(311),a=__webpack_require__.n(r);i;class l{constructor(){this.enabled=!1,this.chance=1,this.directions=["top","left","bottom","left"],this.force=.5,this.selector="[id^=pun]",this.interval=100}}function c(e){return a()(e).find("*").contents().filter((e,t)=>t.nodeType===Node.TEXT_NODE)}o;class h{constructor(){this.enabled=!0,this.chance=20,this.selector=".post-content"}}o;class d{constructor(){this.enabled=!1,this.chance=30}}o;class u{constructor(){this.enabled=!0,this.chance=30,this.selector='img[src*="/avatars/"]',this.variant_chance=20,this.variants={"sepia({0}%)":100,"saturate({0}%)":100,"hue-rotate({0}deg)":360,"invert({0}%)":100}}}o;class p{constructor(){this.enabled=!0,this.chance=20,this.selector=".pa-author a"}}o;class g{constructor(){this.enabled=!0,this.chance=20,this.selector=".post-content",this.shuffle_chance=50}}const f=__webpack_require__(442);i;(r=s=s||{}).Rainbow="rainbow",r.FairyDust="fairy_dust",r.SpringyEmoji="springy_emoji",r.Emoji="emoji",r.Ghost="ghost",r.Trailing="trailing",r.TextFlag="text_flag",r.FollowingDot="following_dot",r.Bubbles="bubbles",r.Snowflake="snowflake",r.Clock="clock";class A{constructor(){this.enabled=!0,this.chance=100,this.effects={[s.Rainbow]:new class extends m{constructor(){super(...arguments),this.length=20,this.size=3,this.colors=["#9400D3","#4B0082","#0000FF","#00FF00","#FFFF00","#FF7F00","#FF0000"]}},[s.SpringyEmoji]:new class extends m{constructor(){super(...arguments),this.emoji="🤪"}},[s.Emoji]:new class extends m{constructor(){super(...arguments),this.emoji=["🔥","🐬","🦆"]}},[s.FairyDust]:new class extends m{constructor(){super(...arguments),this.colors=["#ff0000","#00ff00","#0000ff"]}},[s.Ghost]:new m,[s.Trailing]:new class extends m{constructor(){super(...arguments),this.particles=15,this.rate=.4,this.baseImageSrc=null}},[s.TextFlag]:new class extends m{constructor(){super(...arguments),this.text="С днём смеха!",this.color="#000000",this.font="monospace",this.textSize=12,this.gap=14,this.size=3}},[s.FollowingDot]:new class extends m{constructor(){super(...arguments),this.color="#323232a6"}},[s.Bubbles]:new m,[s.Snowflake]:new class extends m{constructor(){super(...arguments),this.weight=0}},[s.Clock]:new class extends m{constructor(){super(...arguments),this.dateColor="blue",this.faceColor="black",this.secondsColor="red",this.minutesColor="black",this.hoursColor="black"}}}}}class m{constructor(){this.enabled=!0,this.weight=50}}o;class w{constructor(){this.enabled=!0,this.chance=100,this.gender_resolver=null,this.rude=!1,this.change_frequency=5,this.schemas={"{adj} {noun}{p}":10,"{noun} {adj}{p}":3,"{adj}, {adj} {noun}{p}":10,"{adj} и очень {adj} {noun}{p}":10,"{adj} {noun} {verb}{p}":10,"{adj} {noun} {adv} {verb}{p}":5,"{adj} {noun} {verb} {place}{p}":5,"{adj} {noun} {adv} {verb} {place}{p}":5},this.variants={adj:Object.assign(Object.assign({},v(!0,"жесткий,^удачливый,низкий,знакомый,откровенный,^мирный,грамотный,вкусный,виртуальный,пышный,провинциальный,$жирный,заинтересованный,объективный,^оригинальный,пожилой,чистый,особенный,выгодный,громадный,обыкновенный,чужой,ударный,^солнечный,истинный,посторонний,южный,седой,$бесполезный,острый,пестрый,формальный,повседневный,невозможный,$жалкий,целый,$глупый,последний,выходной,серьезный,подземный,небесный,любимый,былой,семейный,далекий,северный,суровый,гигантский,иностранный,родной,конструктивный,показательный,нужный,чрезвычайный,гордый,банальный,открытый,независимый,запасной,мстительный,грубый,алчный,мелочный,хладнокровный,спокойный,терпеливый,креативный,активный,адекватный,застенчивый,опрятный,безнадёжный,уверенный в себе,доброжелательный,ласковый,робкий,воспитанный,самовлюблённый,деятельный,двуличный,верный")),v(!1,"жесткая,^удачливая,низкая,знакомая,откровенная,^мирная,грамотная,вкусная,виртуальная,пышная,провинциальная,$жирная,заинтересованная,объективная,^оригинальная,пожилая,чистая,особенная,выгодная,громадная,обыкновенная,чужая,ударная,^солнечная,истинная,посторонняя,южная,седая,$бесполезная,острая,пестрая,формальная,повседневная,невозможная,$жалкая,целая,$глупая,последняя,выходная,серьезная,подземная,небесная,любимая,былая,семейная,далекая,северная,суровая,гигантская,иностранная,родная,конструктивная,показательная,нужная,чрезвычайная,гордая,банальная,открытая,независимая,запасная,мстительная,грубая,алчная,мелочная,хладнокровная,спокаяная,терпеливая,креативная,активная,адекватная,застенчивая,опрятная,безнадёжная,уверенная в себе,доброжелательная,ласковая,робкая,воспитанная,самовлюблённая,деятельная,двуличная,верная")),noun:Object.assign(Object.assign(Object.assign({},v(null,"")),v(!0,"орёл, ниндзя, манекен, пузырь, бродяга, рыцарь, кентавр, зайц, диван, наследник, сын, джентльмен, басурманин, карасик, $злоумышленник, $раб, хоббит, одиночка, отец, кролик, бруталище, дворф, актёр, %дед, спортсмен, $балбес, %мальчег, лев, ёж, организм, монах, хоббит, борец, тигр, монстр, массажист, мачо, эльф, ледник, жук, кот, зомби, проказник, дракон, носорог, волк, лесоруб, кит, %дедушка, динозавр, бард, кулак, принц, %сынок, мальчик, товарищ, ёжик, сурикат")),v(!1,"заноза, волторна, $личинка, детка, %бабушка, простуда, черепашка, мышь, волчица, деревяшка, пиранья, каруселька, красотка, леди, %дочка, орлица, принцесса, $ведьма, травка, актриса, наследница, %деффачка, горгулья, белочка, акула, машинка, конфетка, знаменитость, косточка, спортсменка, панда, мать, львица, эльфийка, $злоумышленница, чертовка, дворфиха, кошка, $рабыня, скамеечка, дочь, монашка, бактерия, рыбка, бусинка, $бабка, девочка, валькирия, килька, бабочка, милашка, крышка, тигрица, рыбка, русалочка")),verb:Object.assign(Object.assign(Object.assign({},v(null,"встаёт, снимает, приказывает, указывает, собирается, чувствует опасность, орёт, болеет, поздравляет, освобождает, поздравляет, бежит, берёт и делает, молчит, радуется, прощает, читает, снимает, снимается в фильме, что-то скрывает, думает, имеет план и придерживается его, тянет, работает, меняется, ловит, отказаться куда-то идти, заходит, замирает, оформляет, нарушает, отказывается что-то делать, шепчет, снимается в сериале, скрывается, учит, спрашивает, идёт, отказывается вставать, прибывает, отказывается, забывает, получает, плывёт, отвечает, поглядывает, говорит, просыпается, соединяет, оглядывается")),v(!0,"женится, женился, успел, не успел, смог, скрылся, заработался, познал дзен, присел, обиделся, проснулся, взял и сделал, додумался, не спал")),v(!1,"выходит замуж, вышла замуж, успела, не успела, смогла, скрылась, заработалась, познала дзен, присела, обиделась, проснулась, взяла и сделала, додумалась, не спала")),place:Object.assign({},v(null,"где-то, в пустыне, на пляже, под дождём, %под проливным дождём, в квартире, %в тёплой и уютной квартире, в космосе, в театре, в филармонии, на заснеженной вершине, на конференции, на форуме, в очереди, в лесу, в джунглях, под водой")),adv:Object.assign({},v(null,"счастливо, уныло, грустно, позже, немедленно, регулярно, вновь, опять, уже, внезапно, предсказуемо, медленно, быстро, %молниеносно, $грубо, безрассудно, осмысленно, расчётливо")),p:{"":new _({weight:10}),".":new _({weight:10}),"...":new _({weight:5}),"!":new _({weight:5}),"!!!":new _({weight:2}),"?":new _({weight:2}),"?!":new _({weight:1})}}}}class _{constructor(e=new Object){this.weight=10,this.enabled=!0,this.rude=!1,this.gender=null;for(const t of Object.entries(e))t[0]in this&&(this[t[0]]=t[1])}}function v(i,e){const n={};return e.split(",").map(e=>e.trim()).forEach(e=>{var t=e.replace(/[^А-ЯЁа-яёA-Za-z\- ]/g,"");""!==t&&(n[t]=new _({gender:i,rude:0<=e.indexOf("$"),enabled:e.indexOf("!")<0,weight:10*(0<=e.indexOf("$")?.5:1)*(0<=e.indexOf("%")?.5:1)*(0<=e.indexOf("^")?2:1)}))}),n}window.BuildStupdiTitleVariant=v,window.AprilJokes=(e=>{const t=new n;return e.forEach(e=>{t.add(new e)}),$(()=>t.regularStart()),t})([class extends i{constructor(){super(...arguments),this.id="shake",this.title="Форумо-трясение",this.description="Страница форума начинает трястись",this.settings=new l,this.data_name="april-fools-shake"}rand(e){return e+this.settings.force*(2*Math.random()-1)}start(){this.items=a()(this.settings.selector),this.items.each((e,t)=>{let i={};this.settings.directions.forEach(e=>{i[e]=parseInt(a()(t).css("margin-"+e))}),a()(t).data(this.data_name,i)}),this.interval_id=setInterval(()=>{this.items.each((e,t)=>{var i=a()(t).data(this.data_name);for(const n of Object.entries(i))a()(t).css("margin-"+n[0],this.rand(n[1]))})},this.settings.interval)}stop(){clearInterval(this.interval_id),this.items.each((e,t)=>{let i={};this.settings.directions.forEach(e=>{a()(t).css("margin-"+e,i[e])}),a()(t).data(this.data_name,i)})}},class extends o{constructor(){super(...arguments),this.id="humanitarian_hell",this.title="Ад гуманитария",this.description='Все "тся" заменяются на "ться", а все "ться" на "тся"',this.settings=new h}processText(e){return e.replace(/(ть?ся)/g,function(e){return 0{var i=a()(t).html();a()(t).html(this.processText(i))})}},class extends o{constructor(){super(...arguments),this.id="mirror",this.title="Зеркало",this.description="Элементы форума отражаются (по крайней мере, пытаются)",this.settings=new d}start(){a()(".post, .post h3, .post-links, .post-author, .post-content").css("transform","scaleX(-1)").css("-moz-transform","scaleX(-1)").css("-moz-transform","scaleX(-1)").css("filter","FlipH").css("-ms-filter",'"FlipH"'),a()(".post-links, .post-links ul, .post h3 span").css("margin-left","0"),a()(".post h3 span").css("margin-right","25em")}},class extends o{constructor(){super(...arguments),this.id="carnival",this.title="Карнавал",this.description="Аватарки приобретают интересные цвета",this.settings=new u}start(){a()(this.settings.selector).each((e,t)=>{var i=[];for(const n of Object.entries(this.settings.variants))this.check(this.settings.variant_chance)&&i.push(n[0].replace("{0}",Math.round(Math.random()*n[1]).toString()));0{var i=a()(this).text();let n="";for(let e=0;ethis.processNode(t))}},class extends i{constructor(){super(...arguments),this.id="cursor_effects",this.title="Красивый курсор",this.description="Эффекты, следующие за курсором",this.settings=new A}enableAll(){for(const e of Object.keys(this.settings.effects))this.settings.effects[e].enabled=!0}disableAll(){for(const e of Object.keys(this.settings.effects))this.settings.effects[e].enabled=!1}weight(e){e=this.settings.effects[e];return e.enabled?e.weight:0}getRandomEffect(){var e=Object.values(s).map(e=>e),t=e.reduce((e,t)=>e+this.weight(t),0),i=Math.random()*t;let n=0;for(const o of e)if(i<=(n+=this.weight(o)))return o;throw new Error("Тебя быть тут не должно...")}start(){var e=this.getRandomEffect(),t=this.settings.effects[e];this.active_cursor_effect=function(e,t){switch(e){case s.Rainbow:return f.rainbowCursor(t);case s.FairyDust:return f.fairyDustCursor(t);case s.SpringyEmoji:return f.springyEmojiCursor(t);case s.Emoji:return f.emojiCursor(t);case s.Ghost:return f.ghostCursor(t);case s.Trailing:return f.trailingCursor(t);case s.TextFlag:return f.textFlag(t);case s.FollowingDot:return f.followingDotCursor(t);case s.Bubbles:return f.bubbleCursor(t);case s.Snowflake:return f.snowflakeCursor(t);case s.Clock:return f.clockCursor(t)}}(e,t)}stop(){this.active_cursor_effect.destroy()}},class extends o{constructor(){super(...arguments),this.id="stupid_title",this.title="Глупые статусы",this.description="Каждому пользователю даётся новый глупый статус.",this.settings=new w,this.loadedGenders=null,this.seed=0}async loadGenders(){var e=a()(".pa-author a").map((e,t)=>t.innerText).toArray().reduce((e,t)=>(e.indexOf(t)<0&&e.push(t),e),[]),e="/api.php?"+a().param({method:"users.get",fields:"username,sex",username:e}),e=await(await fetch(e)).json();this.loadedGenders={},e.error||e.response.users.forEach(e=>{"0"!==e.sex&&(this.loadedGenders[e.username]="1"===e.sex)})}resolveGender(e){return null!==this.settings.gender_resolver?!!this.settings.gender_resolver.call(this,e):e in this.loadedGenders?!!this.loadedGenders[e]:(this.resetSeed(),"m"===this.selectRandom(e,{m:1,f:1}))}async start(){await this.loadGenders();const n={};a()(".post-author").each((e,t)=>{var i=a()(".pa-author a",t).text();i&&(i in n||(this.resetSeed(),n[i]=this.generatePhrase(i)),a()(".pa-title",t).text(n[i]))})}prng(i,e,t){let n=3735928559^e,o=1103547991^e;for(let e=0,t;e>>16,2246822507)^Math.imul(o^o>>>13,3266489909);e=4294967296*(2097151&(o=Math.imul(o^o>>>16,2246822507)^Math.imul(n^n>>>13,3266489909)))+(n>>>0);return Math.floor(Math.pow(Math.sin(e),2)*t)%t}resetSeed(){var e=new Date,t=60*e.getUTCHours()+e.getUTCMinutes();0===this.settings.change_frequency?this.seed=60*t+e.getUTCSeconds():this.seed=Math.floor(t/this.settings.change_frequency)}selectRandom(e,i){var t=Object.keys(i),n=t.reduce((e,t)=>e+i[t],0),o=this.prng(e,this.seed++,n);let s=0;for(const r of t)if(o<=(s+=i[r]))return r;throw new Error("Тебя быть тут не должно...")}buildVariants(e,t){var i={},e=this.settings.variants[e];for(const s of Object.entries(e)){var n=s[0],o=s[1];!o.enabled||o.gender===!t||!this.settings.rude&&o.rude||(i[n]=o.weight)}return i}capitalizeFirst(e){return e.charAt(0).toUpperCase()+e.slice(1)}generatePhrase(i){const n=this.resolveGender(i);var e=this.selectRandom(i,this.settings.schemas);return this.capitalizeFirst(e.replace(/\{(.+?)\}/g,(e,t)=>{t=this.buildVariants(t,n);return this.selectRandom(i,t)}))}}])})()})(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5023cce..b829856 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "markdown-it": "^13.0.1", "markdown-it-container": "^3.0.0", "prettier": "^2.8.2", + "terser-webpack-plugin": "^5.3.7", "ts-loader": "^9.4.2", "tsify": "^5.0.4", "typescript": "^5.0.2", diff --git a/package.json b/package.json index abdd919..2c09fca 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "markdown-it": "^13.0.1", "markdown-it-container": "^3.0.0", "prettier": "^2.8.2", + "terser-webpack-plugin": "^5.3.7", "ts-loader": "^9.4.2", "tsify": "^5.0.4", "typescript": "^5.0.2", diff --git a/settings.compact.js b/settings.compact.js index f183193..8f6cbc4 100644 --- a/settings.compact.js +++ b/settings.compact.js @@ -3,158 +3,158 @@ window.AprilJokes.disableAll(); window.AprilJokes.jokes.cursor.disableAll(); window.AprilJokes.settings = { - shake: { - enabled: true, - chance: 1, - directions: ['top', 'left', 'bottom', 'left'], - force: 0.5, - selector: '[id^=pun]', - interval: 100, - }, + shake: { + enabled: true, + chance: 1, + directions: ["top", "left", "bottom", "left"], + force: 0.5, + selector: "[id^=pun]", + interval: 100, + }, - mirror: { + mirror: { + enabled: false, + chance: 30, + }, + + carnival: { + enabled: true, + chance: 30, + selector: 'img[src*="/avatars/"]', + variant_chance: 20, + variants: { + "sepia({0}%)": 100, + "saturate({0}%)": 100, + "hue-rotate({0}deg)": 360, + "invert({0}%)": 100, + }, + }, + + humanitarian_hell: { + enabled: true, + chance: 20, + selector: ".post-content", + }, + + crazy_letters: { + enabled: true, + chance: 20, + selector: ".pa-author a", + }, + + letter_chaos: { + enabled: true, + chance: 20, + selector: ".post-content", + shuffle_chance: 50, + }, + + cursor: { + enabled: true, + chance: 100, + effects: { + rainbow: { + enabled: true, + weight: 50, + length: 20, + size: 3, + colors: [ + "#9400D3", + "#4B0082", + "#0000FF", + "#00FF00", + "#FFFF00", + "#FF7F00", + "#FF0000", + ], + }, + springy_emoji: { + enabled: true, + weight: 50, + emoji: "🤪", + }, + emoji: { + enabled: true, + weight: 50, + emoji: ["🔥", "🐬", "🦆"], + }, + fairy_dust: { + enabled: true, + weight: 50, + colors: ["#ff0000", "#00ff00", "#0000ff"], + }, + ghost: { + enabled: true, + weight: 50, + }, + trailing: { + enabled: true, + weight: 50, + particles: 15, + rate: 0.4, + baseImageSrc: null, + }, + text_flag: { + enabled: true, + weight: 50, + text: "С днём смеха!", + color: "#000000", + font: "monospace", + textSize: 12, + gap: 14, + }, + following_dot: { + enabled: true, + weight: 50, + color: "#323232a6", + }, + bubbles: { + enabled: true, + weight: 50, + }, + snowflake: { enabled: false, - chance: 30, - }, - - carnival: { + weight: 50, + }, + clock: { enabled: true, - chance: 30, - selector: 'img[src*="/avatars/"]', - variant_chance: 20, - variants: { - 'sepia({0}%)': 100, - 'saturate({0}%)': 100, - 'hue-rotate({0}deg)': 360, - 'invert({0}%)': 100, - }, + weight: 50, + dateColor: (string = "blue"), + faceColor: (string = "black"), + secondsColor: (string = "red"), + minutesColor: (string = "black"), + hoursColor: (string = "black"), + }, }, + }, - humanitarian_hell: { - enabled: true, - chance: 20, - selector: '.post-content', + stupid_title: { + enabled: true, + chance: 20, + gender_resolver: null, + rude: false, + change_frequency: 5, + schemas: { + "{adj} {noun}{p}": 10, + "{noun} {adj}{p}": 3, + "{adj}, {adj} {noun}{p}": 10, + "{adj} и очень {adj} {noun}{p}": 10, + "{adj} {noun} {verb}{p}": 10, + "{adj} {noun} {adv} {verb}{p}": 5, + "{adj} {noun} {verb} {place}{p}": 5, + "{adj} {noun} {adv} {verb} {place}{p}": 5, }, - - crazy_letters: { - enabled: true, - chance: 20, - selector: '.pa-author a' + variants: { + adj: { + ...window.AprilJokes.settings.stupid_title.variants.adj, + ...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"), + ...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"), + }, + noun: { ...window.AprilJokes.settings.stupid_title.variants.noun }, + verb: { ...window.AprilJokes.settings.stupid_title.variants.verb }, + place: { ...window.AprilJokes.settings.stupid_title.variants.place }, + adv: { ...window.AprilJokes.settings.stupid_title.variants.adv }, + p: { ...window.AprilJokes.settings.stupid_title.variants.p }, }, - - letter_chaos: { - enabled: true, - chance: 20, - selector: '.post-content', - shuffle_chance: 50, - }, - - cursor: { - enabled: true, - chance: 100, - effects: { - rainbow: { - enabled: true, - weight: 50, - length: 20, - size: 3, - colors: [ - "#9400D3", - "#4B0082", - "#0000FF", - "#00FF00", - "#FFFF00", - "#FF7F00", - "#FF0000" - ], - }, - springy_emoji: { - enabled: true, - weight: 50, - emoji: "🤪", - }, - emoji: { - enabled: true, - weight: 50, - emoji: ["🔥", "🐬", "🦆"], - }, - fairy_dust: { - enabled: true, - weight: 50, - colors: ["#ff0000", "#00ff00", "#0000ff"], - }, - ghost: { - enabled: true, - weight: 50, - }, - trailing: { - enabled: true, - weight: 50, - particles: 15, - rate: 0.4, - baseImageSrc: null, - }, - text_flag: { - enabled: true, - weight: 50, - text: "С днём смеха!", - color: "#000000", - font: "monospace", - textSize: 12, - gap: 14, - }, - following_dot: { - enabled: true, - weight: 50, - color: "#323232a6", - }, - bubbles: { - enabled: true, - weight: 50, - }, - snowflake: { - enabled: false, - weight: 50, - }, - clock: { - enabled: true, - weight: 50, - dateColor: string = "blue", - faceColor: string = "black", - secondsColor: string = "red", - minutesColor: string = "black", - hoursColor: string = "black", - }, - }, - }, - - stupid_title: { - enabled: true, - chance: 20, - gender_resolver: null, - rude: false, - change_frequency: 5, - schemas: { - '{adj} {noun}{p}': 10, - '{noun} {adj}{p}': 3, - '{adj}, {adj} {noun}{p}': 10, - '{adj} и очень {adj} {noun}{p}': 10, - '{adj} {noun} {verb}{p}': 10, - '{adj} {noun} {adv} {verb}{p}': 5, - '{adj} {noun} {verb} {place}{p}': 5, - '{adj} {noun} {adv} {verb} {place}{p}': 5, - }, - variants: { - adj: { - ...window.AprilJokes.settings.stupid_title.variants.adj, - ...BuildStupdiTitleVariant(true, 'скромный, шутливый, !грубый'), - ...BuildStupdiTitleVariant(false, 'скромная, шутливая, !грубая'), - }, - noun: { ...window.AprilJokes.settings.stupid_title.variants.noun, }, - verb: { ...window.AprilJokes.settings.stupid_title.variants.verb, }, - place: { ...window.AprilJokes.settings.stupid_title.variants.place, }, - adv: { ...window.AprilJokes.settings.stupid_title.variants.adv, }, - p: { ...window.AprilJokes.settings.stupid_title.variants.p, }, - }, - }, -} \ No newline at end of file + }, +}; diff --git a/settings.example.js b/settings.example.js index 3aaa951..85db36f 100644 --- a/settings.example.js +++ b/settings.example.js @@ -9,444 +9,445 @@ window.AprilJokes.disableAll(); window.AprilJokes.jokes.cursor.disableAll(); window.AprilJokes.settings = { + /** + * Глобальные настройки + */ + core: { /** - * Глобальные настройки + * Активность шутки. + * Установите это значение `false`, что бы отключить шутку. + * Если `true`, то шутка будет обработана как обычно. */ - core: { - /** - * Активность шутки. - * Установите это значение `false`, что бы отключить шутку. - * Если `true`, то шутка будет обработана как обычно. - */ - enabled: true, - - /** - * Вероятность срабатывания в процентах. - * Если установлено значение `100`, шутка будет срабатывать всегда. - * Если установлено значение `0`, шутка никогда не сработает. - * Лучше отключать шутку, используя enabled = false! - */ - chance: 100, + enabled: true, + + /** + * Вероятность срабатывания в процентах. + * Если установлено значение `100`, шутка будет срабатывать всегда. + * Если установлено значение `0`, шутка никогда не сработает. + * Лучше отключать шутку, используя enabled = false! + */ + chance: 100, + }, + + /** + * Форумо-трясение + * + * Страница форума начинает трястись. + * + * @author Kozhilya + */ + shake: { + enabled: false, + chance: 1, + + /** + * Направление тряски + */ + directions: ["top", "left", "bottom", "left"], + + /** + * Сила тряски + */ + force: 0.5, + + /** + * Селектор всех элементов, которые будут трястись + */ + selector: "[id^=pun]", + + /** + * Частота тряски + */ + interval: 100, + }, + + /** + * Зеркало + * + * Элементы форума отражаются (по крайней мере, пытаются) + * + * @author Kozhilya + */ + mirror: { + enabled: false, + chance: 30, + }, + + /** + * Карнавал + * + * Аватарки приобретают интересные цвета + * + * @author Kozhilya + */ + carnival: { + enabled: true, + chance: 30, + + /** + * Селектор всех элементов, которые будут перекрашены. + */ + selector: 'img[src*="/avatars/"]', + + /** + * Вероятность применения фильтра (может сработать нескольк раз). + */ + variant_chance: 20, + + /** + * Список фильтров и диапозона случайных параметров. + */ + variants: { + "sepia({0}%)": 100, + "saturate({0}%)": 100, + "hue-rotate({0}deg)": 360, + "invert({0}%)": 100, }, - + }, + + /** + * Ад гуманитария + * + * Все "тся" заменяются на "ться", а все "ться" на "тся" + * + * @author Kozhilya + */ + humanitarian_hell: { + enabled: true, + chance: 20, + /** - * Форумо-трясение - * - * Страница форума начинает трястись. - * - * @author Kozhilya + * Селектор всех элементов, которые будут затронуты. */ - shake: { + selector: ".post-content", + }, + + /** + * Мама, Я сОшЛа С уМа! + * + * иМеНа ЗаБоРчИкОм + * + * @author Kozhilya + */ + crazy_letters: { + enabled: true, + chance: 20, + + /** + * Селектор всех элементов, которые будут затронуты. + */ + selector: ".pa-author a", + }, + + /** + * **Буквенный хаос** + * + * Все буквы в словах, кроме первой и последней, перемешены. + * + * @author Kozhilya + */ + letter_chaos: { + enabled: true, + chance: 20, + + /** + * Селектор всех элементов, которые будут затронуты + */ + selector: ".post-content", + + /** + * Вероятность того, что буквы будут перемешаны + */ + shuffle_chance: 50, + }, + + /** + * **Красивый курсор** + * + * Эффекты, следующие за курсором + * + * @author Tim Holman + * @author Kozhilya + * + * @link https://tholman.com/cursor-effects/ + */ + cursor: { + enabled: true, + chance: 100, + + /** + * Список эффектов курсора + */ + effects: { + /** + * Радужный след за курсором + */ + rainbow: { + enabled: true, + weight: 50, + + /** + * Длина полосы + */ + length: 20, + + /** + * Ширина полосы + */ + size: 3, + + /** + * Цвета полос (сверху вниз) + */ + colors: [ + "#9400D3", + "#4B0082", + "#0000FF", + "#00FF00", + "#FFFF00", + "#FF7F00", + "#FF0000", + ], + }, + + /** + * Цепочка из эмодзи "на резинке" под курсором + */ + springy_emoji: { + enabled: true, + weight: 50, + + /** + * Висящий эмодзи + */ + emoji: "🤪", + }, + + /** + * Падающие от курсора эмодзи + */ + emoji: { + enabled: true, + weight: 50, + + /** + * Падающие эмодзи + */ + emoji: ["🔥", "🐬", "🦆"], + }, + + /** + * Падающие от курсора пылинки + */ + fairy_dust: { + enabled: true, + weight: 50, + + /** + * Цвет пылинок + */ + colors: ["#ff0000", "#00ff00", "#0000ff"], + }, + + /** + * След "зависших" курсоров + */ + ghost: { + enabled: true, + weight: 50, + }, + + /** + * След курсоров "на резинке" + */ + trailing: { + enabled: true, + weight: 50, + + /** + * Количество элементов + */ + particles: 15, + + /** + * Скорость частиц + */ + rate: 0.4, + + /** + * Ссылка на картинку с курсором + * Используйте `null`, что бы использовать картинку курсора по умолчанию + */ + baseImageSrc: null, + }, + + /** + * Текст, развивающийся флагом от курсора + */ + text_flag: { + enabled: true, + weight: 50, + + /** + * Отображаемый текст + */ + text: "С днём смеха!", + + /** + * Цвет текста + */ + color: "#000000", + + /** + * Шрифт текста + */ + font: "monospace", + + /** + * Размер текста + */ + textSize: 12, + + /** + * Растояние между бквами + */ + gap: 14, + }, + + /** + * Точка, преследующая курсор + */ + following_dot: { + enabled: true, + weight: 50, + + /** + * Цвет догоняющей точки + */ + color: "#323232a6", + }, + + /** + * Пузырьки от курсора + */ + bubbles: { + enabled: true, + weight: 50, + }, + + /** + * Снежинки, летящие от курсора + * + * Отключено, потому что сейчас не зима :D + */ + snowflake: { enabled: false, - chance: 1, + weight: 50, + }, - /** - * Направление тряски - */ - directions: ['top', 'left', 'bottom', 'left'], - - /** - * Сила тряски - */ - force: 0.5, - - /** - * Селектор всех элементов, которые будут трястись - */ - selector: '[id^=pun]', - - /** - * Частота тряски - */ - interval: 100, - }, - - /** - * Зеркало - * - * Элементы форума отражаются (по крайней мере, пытаются) - * - * @author Kozhilya - */ - mirror: { - enabled: false, - chance: 30, - }, - - /** - * Карнавал - * - * Аватарки приобретают интересные цвета - * - * @author Kozhilya - */ - carnival: { + /** + * Циферблат вокруг курсора + */ + clock: { enabled: true, - chance: 30, + weight: 50, /** - * Селектор всех элементов, которые будут перекрашены. + * Цвет даты */ - selector: 'img[src*="/avatars/"]', + dateColor: (string = "blue"), /** - * Вероятность применения фильтра (может сработать нескольк раз). + * Цвет циферблата */ - variant_chance: 20, + faceColor: (string = "black"), /** - * Список фильтров и диапозона случайных параметров. + * Цвет секундной стрелки */ - variants: { - 'sepia({0}%)': 100, - 'saturate({0}%)': 100, - 'hue-rotate({0}deg)': 360, - 'invert({0}%)': 100, - }, + secondsColor: (string = "red"), + + /** + * Цвет минутной стрелки + */ + minutesColor: (string = "black"), + + /** + * Цвет часовой стрелки + */ + hoursColor: (string = "black"), + }, + }, + }, + + /** + * **Глупые статусы** + * + * Каждому пользователю даётся новый глупый статус. + * + * @author Kozhilya + */ + stupid_title: { + enabled: true, + chance: 20, + + /** + * Определение пола по имени. + * По умолчанию род устанавливается случайным образом + * + * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом. + * + * @param name Имя персонажа + * @returns true, если мужской род; false, если женский род + */ + gender_resolver: null, + + /** + * Разрешить возможно оскорбительные слова + */ + rude: false, + + /** + * Частота смены статусов (в минутах) + * Установите значение 0, что бы обновление происходило при каждом обновлении страницы + */ + change_frequency: 5, + + /** + * Разрешённые схемы формирования статусов + * + * {adj} - прилагательное + * {noun} - имя существительно + * {verb} - глагол + * {adv} - наречие + * {p} - знак препинания + */ + schemas: { + "{adj} {noun}{p}": 10, + "{noun} {adj}{p}": 3, + "{adj}, {adj} {noun}{p}": 10, + "{adj} и очень {adj} {noun}{p}": 10, + "{adj} {noun} {verb}{p}": 10, + "{adj} {noun} {adv} {verb}{p}": 5, + "{adj} {noun} {verb} {place}{p}": 5, + "{adj} {noun} {adv} {verb} {place}{p}": 5, }, /** - * Ад гуманитария - * - * Все "тся" заменяются на "ться", а все "ться" на "тся" - * - * @author Kozhilya + * Вариант слов. + * Смотрите раздел описания скрипта, что бы настроить это поле */ - humanitarian_hell: { - enabled: true, - chance: 20, - - /** - * Селектор всех элементов, которые будут затронуты. - */ - selector: '.post-content', + variants: { + adj: { + ...window.AprilJokes.settings.stupid_title.variants.adj, + ...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"), + ...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"), + }, + noun: { ...window.AprilJokes.settings.stupid_title.variants.noun }, + verb: { ...window.AprilJokes.settings.stupid_title.variants.verb }, + place: { ...window.AprilJokes.settings.stupid_title.variants.place }, + adv: { ...window.AprilJokes.settings.stupid_title.variants.adv }, + p: { ...window.AprilJokes.settings.stupid_title.variants.p }, }, - - /** - * Мама, Я сОшЛа С уМа! - * - * иМеНа ЗаБоРчИкОм - * - * @author Kozhilya - */ - crazy_letters: { - enabled: true, - chance: 20, - - /** - * Селектор всех элементов, которые будут затронуты. - */ - selector: '.pa-author a' - }, - - /** - * **Буквенный хаос** - * - * Все буквы в словах, кроме первой и последней, перемешены. - * - * @author Kozhilya - */ - letter_chaos: { - enabled: true, - chance: 20, - - /** - * Селектор всех элементов, которые будут затронуты - */ - selector: '.post-content', - - /** - * Вероятность того, что буквы будут перемешаны - */ - shuffle_chance: 50, - }, - - /** - * **Красивый курсор** - * - * Эффекты, следующие за курсором - * - * @author Tim Holman - * @author Kozhilya - * - * @link https://tholman.com/cursor-effects/ - */ - cursor: { - enabled: true, - chance: 100, - - /** - * Список эффектов курсора - */ - effects: { - /** - * Радужный след за курсором - */ - rainbow: { - enabled: true, - weight: 50, - - /** - * Длина полосы - */ - length: 20, - - /** - * Ширина полосы - */ - size: 3, - - /** - * Цвета полос (сверху вниз) - */ - colors: [ - "#9400D3", - "#4B0082", - "#0000FF", - "#00FF00", - "#FFFF00", - "#FF7F00", - "#FF0000" - ], - }, - - /** - * Цепочка из эмодзи "на резинке" под курсором - */ - springy_emoji: { - enabled: true, - weight: 50, - - /** - * Висящий эмодзи - */ - emoji: "🤪", - }, - - /** - * Падающие от курсора эмодзи - */ - emoji: { - enabled: true, - weight: 50, - - /** - * Падающие эмодзи - */ - emoji: ["🔥", "🐬", "🦆"], - }, - - /** - * Падающие от курсора пылинки - */ - fairy_dust: { - enabled: true, - weight: 50, - - /** - * Цвет пылинок - */ - colors: ["#ff0000", "#00ff00", "#0000ff"], - }, - - /** - * След "зависших" курсоров - */ - ghost: { - enabled: true, - weight: 50, - }, - - /** - * След курсоров "на резинке" - */ - trailing: { - enabled: true, - weight: 50, - - /** - * Количество элементов - */ - particles: 15, - - /** - * Скорость частиц - */ - rate: 0.4, - - /** - * Ссылка на картинку с курсором - * Используйте `null`, что бы использовать картинку курсора по умолчанию - */ - baseImageSrc: null, - }, - - /** - * Текст, развивающийся флагом от курсора - */ - text_flag: { - enabled: true, - weight: 50, - - /** - * Отображаемый текст - */ - text: "С днём смеха!", - - /** - * Цвет текста - */ - color: "#000000", - - /** - * Шрифт текста - */ - font: "monospace", - - /** - * Размер текста - */ - textSize: 12, - - /** - * Растояние между бквами - */ - gap: 14, - }, - - /** - * Точка, преследующая курсор - */ - following_dot: { - enabled: true, - weight: 50, - - /** - * Цвет догоняющей точки - */ - color: "#323232a6", - }, - - /** - * Пузырьки от курсора - */ - bubbles: { - enabled: true, - weight: 50, - }, - - /** - * Снежинки, летящие от курсора - * - * Отключено, потому что сейчас не зима :D - */ - snowflake: { - enabled: false, - weight: 50, - }, - - /** - * Циферблат вокруг курсора - */ - clock: { - enabled: true, - weight: 50, - - /** - * Цвет даты - */ - dateColor: string = "blue", - - /** - * Цвет циферблата - */ - faceColor: string = "black", - - /** - * Цвет секундной стрелки - */ - secondsColor: string = "red", - - /** - * Цвет минутной стрелки - */ - minutesColor: string = "black", - - /** - * Цвет часовой стрелки - */ - hoursColor: string = "black", - }, - }, - }, - - /** - * **Глупые статусы** - * - * Каждому пользователю даётся новый глупый статус. - * - * @author Kozhilya - */ - stupid_title: { - enabled: true, - chance: 20, - - /** - * Определение пола по имени. - * По умолчанию род устанавливается случайным образом - * - * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом. - * - * @param name Имя персонажа - * @returns true, если мужской род; false, если женский род - */ - gender_resolver: null, - - /** - * Разрешить возможно оскорбительные слова - */ - rude: false, - - /** - * Частота смены статусов (в минутах) - */ - change_frequency: 5, - - /** - * Разрешённые схемы формирования статусов - * - * {adj} - прилагательное - * {noun} - имя существительно - * {verb} - глагол - * {adv} - наречие - * {p} - знак препинания - */ - schemas: { - '{adj} {noun}{p}': 10, - '{noun} {adj}{p}': 3, - '{adj}, {adj} {noun}{p}': 10, - '{adj} и очень {adj} {noun}{p}': 10, - '{adj} {noun} {verb}{p}': 10, - '{adj} {noun} {adv} {verb}{p}': 5, - '{adj} {noun} {verb} {place}{p}': 5, - '{adj} {noun} {adv} {verb} {place}{p}': 5, - }, - - /** - * Вариант слов. - * Смотрите раздел описания скрипта, что бы настроить это поле - */ - variants: { - adj: { - ...window.AprilJokes.settings.stupid_title.variants.adj, - ...BuildStupdiTitleVariant(true, 'скромный, шутливый, !грубый'), - ...BuildStupdiTitleVariant(false, 'скромная, шутливая, !грубая'), - }, - noun: { ...window.AprilJokes.settings.stupid_title.variants.noun, }, - verb: { ...window.AprilJokes.settings.stupid_title.variants.verb, }, - place: { ...window.AprilJokes.settings.stupid_title.variants.place, }, - adv: { ...window.AprilJokes.settings.stupid_title.variants.adv, }, - p: { ...window.AprilJokes.settings.stupid_title.variants.p, }, - }, - }, -} \ No newline at end of file + }, +}; diff --git a/src/common.ts b/src/common.ts new file mode 100644 index 0000000..4d5a4cb --- /dev/null +++ b/src/common.ts @@ -0,0 +1,14 @@ +import $ from "jquery"; + +/** + * Получение всех элементов, являющимися TextNode. + * Используется некоторыми шутками для уменьшения влияния на существующее DOM-дерево. + */ +export function getTextNodes( + root: any +): JQuery { + return $(root) + .find("*") + .contents() + .filter((_, node) => node.nodeType === Node.TEXT_NODE); +} diff --git a/src/data/stupid_title_variants.ts b/src/data/stupid_title_variants.ts new file mode 100644 index 0000000..7868214 --- /dev/null +++ b/src/data/stupid_title_variants.ts @@ -0,0 +1,57 @@ +import { + StupidTitleVariants, + BuildStupdiTitleVariant, +} from "../jokes/stupid_title"; +export function StupidTitleDefaultVariants(vars: StupidTitleVariants) { + vars.adj = { + ...BuildStupdiTitleVariant( + true, + "адекватный,$адский,активный,алчный,%ангельский,банальный,безнадёжный,$бесполезный,былой,верный,виртуальный,вкусный,воспитанный,выгодный,выходной,гигантский,$глупый,гордый,грамотный,громадный,грубый,далекий,двуличный,деятельный,доброжелательный,$жалкий,жёсткий,жестокий,$жирный,заинтересованный,запасной,застенчивый,знакомый,иностранный,истинный,конструктивный,креативный,ласковый,любимый,мелочный,^мирный,мстительный,небесный,невозможный,независимый,низкий,нужный,объективный,обыкновенный,опрятный,^оригинальный,особенный,острый,откровенный,открытый,пестрый,повседневный,подземный,пожилой,показательный,последний,посторонний,провинциальный,пышный,робкий,родной,самовлюблённый,северный,седой,семейный,серьёзный,сногсшибательный,^солнечный,спокойный,суровый,терпеливый,уверенный в себе,ударный,^удачливый,формальный,хладнокровный,целый,чистый,чрезвычайный,чужой,южный" + ), + ...BuildStupdiTitleVariant( + false, + "адекватная,$адская,активная,алчная,%ангельская,банальная,безнадёжная,$бесполезная,былая,верная,виртуальная,вкусная,воспитанная,выгодная,выходная,гигантская,$глупая,гордая,грамотная,громадная,грубая,далекая,двуличная,деятельная,доброжелательная,$жалкая,жёсткая,жестокая,$жирная,заинтересованная,запасная,застенчивая,знакомая,иностранная,истинная,конструктивная,креативная,ласковая,любимая,мелочная,^мирная,мстительная,небесная,невозможная,независимая,низкая,нужная,объективная,обыкновенная,опрятная,^оригинальная,особенная,острая,откровенная,открытая,пестрая,повседневная,подземная,пожилая,показательная,последняя,посторонняя,провинциальная,пышная,робкая,родная,самовлюблённая,северная,седая,семейная,серьезная,сногсшибательная,^солнечная,спокаяная,суровая,терпеливая,уверенная в себе,ударная,^удачливая,формальная,хладнокровная,целая,чистая,чрезвычайная,чужая,южная" + ), + ...vars.adj, + }; + vars.noun = { + ...BuildStupdiTitleVariant( + true, + "актёр,$балбес,бард,басурманин,борец,бродяга,бруталище,волк,дворф,%дед,%дедушка,джентльмен,диван,динозавр,дракон,ёж,%ёжик,жук,зайц,$злоумышленник,зомби,карасик,кентавр,кит,кот,кролик,кулак,лев,ледник,лесоруб,%мальчег,мальчик,манекен,массажист,мачо,монах,монстр,наследник,ниндзя,носорог,одиночка,организм,орёл,отец,принц,проказник,пузырь,$раб,рыцарь,спортсмен,сурикат,сын,%сынок,тигр,товарищ,хоббит,эльф" + ), + ...BuildStupdiTitleVariant( + false, + "актриса,акула,$бабка,бабочка,%бабушка,бактерия,белочка,бусинка,валькирия,$ведьма,волторна,волчица,горгулья,дворфиха,девочка,деревяшка,детка,%деффачка,%дочка,дочь,заноза,$злоумышленница,знаменитость,каруселька,килька,конфетка,косточка,кошка,красотка,крышка,леди,$личинка,львица,мать,машина,милашка,монашка,мышь,наследница,орлица,панда,пиранья,принцесса,простуда,$рабыня,русалочка,рыбка,рыбка,скамеечка,спортсменка,тигрица,травка,черепашка,чертовка,эльфийка" + ), + ...vars.noun, + }; + vars.verb = { + ...BuildStupdiTitleVariant( + null, + "бежит,берёт и делает,болеет,встаёт,говорит,думает,забывает,замирает,заходит,идёт,%имеет план и придерживается его,ловит,меняется,молчит,нарушает,оглядывается,орёт,освобождает,отвечает,отказаться куда-то идти,отказывается,отказывается вставать,отказывается что-то делать,оформляет,плывёт,поглядывает,поздравляет,поздравляет,получает,прибывает,приказывает,просыпается,прощает,работает,радуется,скрывается,снимает,снимает,снимается в сериале,снимается в фильме,собирается,соединяет,спрашивает,тянет,указывает,учит,читает,что-то скрывает,чувствует опасность,шепчет" + ), + ...BuildStupdiTitleVariant( + true, + "взял и сделал,додумался,женился,женится,заработался,не спал,не успел,обиделся,познал дзен,присел,проснулся,скрылся,смог,успел" + ), + ...BuildStupdiTitleVariant( + false, + "взяла и сделала,выходит замуж,вышла замуж,додумалась,заработалась,не спала,не успела,обиделась,познала дзен,присела,проснулась,скрылась,смогла,успела" + ), + ...vars.verb, + }; + vars.place = { + ...BuildStupdiTitleVariant( + null, + "в джунглях,в квартире,в космосе,в лесу,в очереди,в пустыне,в театре,%в тёплой и уютной квартире,в филармонии,где-то,на заснеженной вершине,на конференции,на пляже,на форуме,под водой,под дождём,%под проливным дождём" + ), + ...vars.place, + }; + vars.adv = { + ...BuildStupdiTitleVariant( + null, + "безрассудно,быстро,внезапно,вновь,$грубо,грустно,медленно,%молниеносно,немедленно,опять,осмысленно,позже,предсказуемо,расчётливо,регулярно,счастливо,уже,уныло" + ), + ...vars.adv, + }; +} diff --git a/src/html.d.ts b/src/html.d.ts index 56b1935..3a031d8 100644 --- a/src/html.d.ts +++ b/src/html.d.ts @@ -1,4 +1,4 @@ declare module "*.html" { - const content: string; - export default content; -} \ No newline at end of file + const content: string; + export default content; +} diff --git a/src/html/button.html b/src/html/button.html index a3646ae..9d8db74 100644 --- a/src/html/button.html +++ b/src/html/button.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/html/styles.html b/src/html/styles.html index 14ee2e5..50fe776 100644 --- a/src/html/styles.html +++ b/src/html/styles.html @@ -1,5 +1,5 @@ \ No newline at end of file + } + diff --git a/src/html/window.html b/src/html/window.html index 5d4b981..8e41faa 100644 --- a/src/html/window.html +++ b/src/html/window.html @@ -1,15 +1,23 @@
-
+
- +
\ No newline at end of file +
+ + +
+ diff --git a/src/joke.ts b/src/joke.ts index 9377908..9c04a95 100644 --- a/src/joke.ts +++ b/src/joke.ts @@ -2,87 +2,85 @@ * Объект настроек шутки */ export interface JokeSettings { - /** - * Флаг блокировки срабатывания - */ - enabled: boolean; + /** + * Флаг блокировки срабатывания + */ + enabled: boolean; - /** - * Вероятность срабатывания в процентах - */ - chance: number; + /** + * Вероятность срабатывания в процентах + */ + chance: number; } /** * Объект, описывающий шутку */ export abstract class Joke { - /** - * Идентификатор шутки - */ - abstract id: string; + /** + * Идентификатор шутки + */ + abstract id: string; - /** - * Заголовок шутки - */ - abstract title: string; + /** + * Заголовок шутки + */ + abstract title: string; - /** - * Описание шутки - */ - abstract description: string; + /** + * Описание шутки + */ + abstract description: string; - /** - * Настройки шутки - */ - settings: JokeSettings; + /** + * Настройки шутки + */ + settings: JokeSettings; - /** - * Проверка вероятности - * - * @param {number} chance Вероятность срабатывания - * @returns {boolean} Флаг срабатывания (true - сработало) - */ - check(chance: number): boolean { - return Math.random() < 0.01 * chance; - } - - /** - * Разблокировать шутку - */ - enable() { - this.settings.enabled = true; - } - - /** - * Заблокировать шутку - */ - disable() { - this.settings.enabled = false; - } + /** + * Проверка вероятности + * + * @param {number} chance Вероятность срабатывания + * @returns {boolean} Флаг срабатывания (true - сработало) + */ + check(chance: number): boolean { + return Math.random() < 0.01 * chance; + } - /** - * Переключить блокировку шутки - * @param value Новое значение - */ - toggle(value: boolean|null = null) { - this.settings.enabled = (value === null) ? !this.settings.enabled : value; - } + /** + * Разблокировать шутку + */ + enable() { + this.settings.enabled = true; + } - /** - * Запуск шутки - */ - abstract start(): void; + /** + * Заблокировать шутку + */ + disable() { + this.settings.enabled = false; + } + + /** + * Переключить блокировку шутки + * @param value Новое значение + */ + toggle(value: boolean | null = null) { + this.settings.enabled = value === null ? !this.settings.enabled : value; + } + + /** + * Запуск шутки + */ + abstract start(): void; } /** * Объект, описывающий шутку, которая может быть остановлена */ -export abstract class StopableJoke extends Joke -{ - /** - * Остановка шутки, если возможно - */ - abstract stop(): void; +export abstract class StopableJoke extends Joke { + /** + * Остановка шутки, если возможно + */ + abstract stop(): void; } - diff --git a/src/joker.ts b/src/joker.ts index 0452246..989d10f 100644 --- a/src/joker.ts +++ b/src/joker.ts @@ -4,279 +4,294 @@ import { JokerUI } from "./ui"; /** * Блок обработки перво-апрельских шуток - * + * * @author Kozhilya */ export class JokerClass { - ui: JokerUI = new JokerUI(this); + ui: JokerUI = new JokerUI(this); - /** - * Проверка вероятности - * - * @param {number} chance Вероятность срабатывания - * @returns {boolean} Флаг срабатывания (true - сработало) - */ - check(chance: number): boolean { - return Math.random() < 0.01 * chance; + /** + * Проверка вероятности + * + * @param {number} chance Вероятность срабатывания + * @returns {boolean} Флаг срабатывания (true - сработало) + */ + check(chance: number): boolean { + return Math.random() < 0.01 * chance; + } + + /** + * Добавление шутки + * + * @param joke Объект шутки + */ + add(joke: Joke): void { + this.jokes[joke.id] = joke; + } + + /** + * Регистрация новой шутки + * + * @param id Идентификатор шутки + * @param handler Метод, выполняющий шутку + * @param settings Объект настроек шутки + */ + addCustom( + id: string, + handler: Function, + settings: JokeSettings | null = null + ): Joke { + const joke = new (class extends Joke { + id = id; + + title = "Пользовательская шутка"; + + description = "Для шутки не определено описание"; + + settings: JokeSettings = { chance: 10, enabled: true }; + + start() { + handler.call(this, this.settings); + } + })(); + + Object.assign(joke.settings, settings ?? {}); + + this.add(joke); + + return joke; + } + + /** + * Получение полного списка настроек + */ + get settings(): SettingsMap { + const result: SettingsMap = {}; + + result["core"] = this.core_settings; + + for (const entries of Object.entries(this.jokes)) { + const id = entries[0]; + const joke = entries[1]; + + result[id] = joke.settings; } - /** - * Добавление шутки - * - * @param joke Объект шутки - */ - add(joke: Joke): void { - this.jokes[joke.id] = joke; + return result; + } + + /** + * Запись новых настроек + * + * @param settings + */ + set settings(settings: SettingsMap) { + for (const entry of Object.entries(settings)) { + const id = entry[0]; + const jokeSettings = entry[1]; + const targetSettings = + id === "core" ? this.core_settings : this.jokes[id].settings; + + Object.assign(targetSettings, jokeSettings); + } + } + + /** + * Разблокировать систему + */ + enable() { + this.core_settings.enabled = true; + } + + /** + * Заблокировать систему + */ + disable() { + this.core_settings.enabled = false; + } + + /** + * Разблокировать все шутки + */ + enableAll() { + for (const key of Object.keys(this.jokes)) { + this.jokes[key].enable(); + } + } + + /** + * Заблокировать все шутки + */ + disableAll() { + for (const key of Object.keys(this.jokes)) { + this.jokes[key].disable(); + } + } + + /** + * Переключение шутки + */ + toggleJoke(joke_id: string, state: boolean) { + const joke = this.jokes[joke_id]; + joke.settings.enabled = state; + + if (joke instanceof StopableJoke && !state) { + joke.stop(); } - /** - * Регистрация новой шутки - * - * @param id Идентификатор шутки - * @param handler Метод, выполняющий шутку - * @param settings Объект настроек шутки - */ - addCustom(id: string, handler: Function, settings: JokeSettings|null = null): Joke { - const joke = new class extends Joke { - id = id; + this.saveUserStates(); + } - title = 'Пользовательская шутка'; + /** + * Сохранение пользовательских настроек + */ + saveUserStates() { + const states: any = {}; - description = 'Для шутки не определено описание'; - - settings: JokeSettings = { chance: 10, enabled: true }; - - start() { - handler.call(this, this.settings); - } - }; - - Object.assign(joke.settings, settings ?? {}); - - this.add(joke); - - return joke; + for (const key of Object.keys(this.jokes)) { + states[key] = this.jokes[key].settings.enabled; } - /** - * Получение полного списка настроек - */ - get settings(): SettingsMap { - const result: SettingsMap = {}; + fetch( + "/api.php?" + + $.param({ + method: "storage.set", + user_id: (window).UserID, + key: "april-fools", + token: (window).ForumAPITicket, + value: JSON.stringify(states), + timer: 24 * 60, + }) + ); + } - result['core'] = this.core_settings; + /** + * Загрузка пользовательских настроек + */ + async loadUserStates() { + const response = await fetch( + "/api.php?" + + $.param({ + method: "storage.get", + user_id: (window).UserID, + key: "april-fools", + }) + ); + const json = await response.json(); - for (const entries of Object.entries(this.jokes)) { - const id = entries[0]; - const joke = entries[1]; - - result[id] = joke.settings; - } - - return result; + if (json.error) { + return; } - /** - * Запись новых настроек - * - * @param settings - */ - set settings(settings: SettingsMap) { - for (const entry of Object.entries(settings)) { - const id = entry[0]; - const jokeSettings = entry[1]; - const targetSettings = (id === 'core') ? this.core_settings : this.jokes[id].settings; + const data = JSON.parse(json.response.storage.data["april-fools"]); - Object.assign(targetSettings, jokeSettings); - } + for (const key of Object.keys(this.jokes)) { + this.jokes[key].settings.enabled = data[key]; } - - /** - * Разблокировать систему - */ - enable() { - this.core_settings.enabled = true; - } - - /** - * Заблокировать систему - */ - disable() { - this.core_settings.enabled = false; - } - - /** - * Разблокировать все шутки - */ - enableAll() { - for (const key of Object.keys(this.jokes)) { - this.jokes[key].enable(); - } - } - - /** - * Заблокировать все шутки - */ - disableAll() { - for (const key of Object.keys(this.jokes)) { - this.jokes[key].disable(); - } + } + + async clearUserStates() { + await fetch( + "/api.php?" + + $.param({ + method: "storage.delete", + user_id: (window).UserID, + key: "april-fools", + token: (window).ForumAPITicket, + }) + ); + + return; + } + + /** + * Запуск шутки + * + * @param id + * @param {boolean} forced + */ + start(id: string, forced: boolean = false) { + if (!(id in this.jokes)) return; + + const joke = this.jokes[id]; + + if ( + !forced && + (!joke.settings.enabled || !this.check(joke.settings.chance)) + ) { + return; } - /** - * Переключение шутки - */ - toggleJoke(joke_id: string, state: boolean) { - const joke = this.jokes[joke_id]; - joke.settings.enabled = state; + joke.start(); + } - if (joke instanceof StopableJoke && !state) { - joke.stop(); - } + /** + * Запуск всех шуток + */ + startAll(forced: boolean = false): void { + for (const key of Object.keys(this.jokes)) { + this.start(key, forced); + } + } - this.saveUserStates(); + regularCheck(): boolean { + if (!this.core_settings.enabled) { + return false; } - /** - * Сохранение пользовательских настроек - */ - saveUserStates() { - const states: any = {}; - - for (const key of Object.keys(this.jokes)) { - states[key] = this.jokes[key].settings.enabled; - } - - fetch('/api.php?' + $.param({ - method: 'storage.set', - user_id: ( window).UserID, - key: 'april-fools', - token: ( window).ForumAPITicket, - value: JSON.stringify(states), - timer: 24 * 60 - })); + if (this.core_settings.testers.indexOf((window).UserID) >= 0) { + return true; } - /** - * Загрузка пользовательских настроек - */ - async loadUserStates() { - const response = await fetch('/api.php?' + $.param({ - method: 'storage.get', - user_id: ( window).UserID, - key: 'april-fools', - })); - const json = await response.json(); + const today = new Date(); + const month = today.getMonth() + 1; + const day = today.getDate(); - if (json.error) { - return; - } - - const data = JSON.parse(json.response.storage.data['april-fools']); - - for (const key of Object.keys(this.jokes)) { - this.jokes[key].settings.enabled = data[key]; - } + if (month !== 4 || day !== 1) { + return false; } - async clearUserStates() { - await fetch('/api.php?' + $.param({ - method: 'storage.delete', - user_id: ( window).UserID, - key: 'april-fools', - token: ( window).ForumAPITicket, - })); + return this.check(this.core_settings.chance); + } - return; + async regularStart() { + if (!this.regularCheck()) { + return; } + await this.loadUserStates(); + this.ui.show(); + this.startAll(); + } - /** - * Запуск шутки - * - * @param id - * @param {boolean} forced - */ - start(id: string, forced: boolean = false) { - if (!(id in this.jokes)) - return; + /** + * Общие настройки системы + */ + core_settings = new CoreSettings(); - const joke = this.jokes[id]; - - if (!forced && (!joke.settings.enabled || !this.check(joke.settings.chance))) { - return; - } - - joke.start(); - } - - /** - * Запуск всех шуток - */ - startAll(forced: boolean = false): void { - for (const key of Object.keys(this.jokes)) { - this.start(key, forced); - } - } - - regularCheck(): boolean { - if (!this.core_settings.enabled) { - return false; - } - - if (this.core_settings.testers.indexOf(( window).UserID) >= 0) { - return true; - } - - const today = new Date(); - const month = today.getMonth() + 1; - const day = today.getDate(); - - if (month !== 4 || day !== 1) { - return false; - } - - return this.check(this.core_settings.chance); - } - - async regularStart() { - if (!this.regularCheck()) { - return; - } - - await this.loadUserStates(); - this.ui.show(); - this.startAll(); - } - - /** - * Общие настройки системы - */ - core_settings = new CoreSettings; - - /** - * Перечисление всех шуток - */ - jokes: JokeMap = {} + /** + * Перечисление всех шуток + */ + jokes: JokeMap = {}; } /** * Объект хранения шуток */ interface JokeMap { - [key: string]: Joke; + [key: string]: Joke; } /** * Объект задания настроек */ interface SettingsMap { - [key: string]: JokeSettings; + [key: string]: JokeSettings; } class CoreSettings implements JokeSettings { - chance = 100; - enabled = true; + chance = 100; + enabled = true; - testers: number[] = []; -} \ No newline at end of file + testers: number[] = []; +} diff --git a/src/jokes/carnival.ts b/src/jokes/carnival.ts index 47873b5..10cf3f4 100644 --- a/src/jokes/carnival.ts +++ b/src/jokes/carnival.ts @@ -4,65 +4,70 @@ import { JokerClass } from "../joker"; /** * **Карнавал** - * + * * Аватарки приобретают интересные цвета - * + * * @author Kozhilya */ export class CarnivalJoke extends Joke { - id = 'carnival'; + id = "carnival"; - title = 'Карнавал'; + title = "Карнавал"; - description = 'Аватарки приобретают интересные цвета'; + description = "Аватарки приобретают интересные цвета"; - settings = new CarnivalJokeSettings; - - start(): void { - $(this.settings.selector).each((_, elem) => { - const filters: string[] = []; + settings = new CarnivalJokeSettings(); - for (const entry of Object.entries(this.settings.variants)) { - if (!this.check(this.settings.variant_chance)) { - continue; - } + start(): void { + $(this.settings.selector).each((_, elem) => { + const filters: string[] = []; - filters.push(entry[0].replace('{0}', Math.round(Math.random() * entry[1]).toString())); - } + for (const entry of Object.entries(this.settings.variants)) { + if (!this.check(this.settings.variant_chance)) { + continue; + } - if (filters.length > 0) { - $(elem).css({'filter': filters.join(' ')}); - } - }); - } + filters.push( + entry[0].replace( + "{0}", + Math.round(Math.random() * entry[1]).toString() + ) + ); + } + + if (filters.length > 0) { + $(elem).css({ filter: filters.join(" ") }); + } + }); + } } export class CarnivalJokeSettings implements JokeSettings { - enabled: boolean = true; + enabled: boolean = true; - chance: number = 30; + chance: number = 30; - /** - * Селектор всех элементов, которые будут перекрашены - */ - selector: string = 'img[src*="/avatars/"]'; + /** + * Селектор всех элементов, которые будут перекрашены + */ + selector: string = 'img[src*="/avatars/"]'; - /** - * Вероятность применения некоторого фильтра - */ - variant_chance: number = 20; + /** + * Вероятность применения некоторого фильтра + */ + variant_chance: number = 20; - /** - * Список фильтров и диапозона случайных параметров - */ - variants: CarnivalJokeFilters = { - 'sepia({0}%)': 100, - 'saturate({0}%)': 100, - 'hue-rotate({0}deg)': 360, - 'invert({0}%)': 100, - } + /** + * Список фильтров и диапозона случайных параметров + */ + variants: CarnivalJokeFilters = { + "sepia({0}%)": 100, + "saturate({0}%)": 100, + "hue-rotate({0}deg)": 360, + "invert({0}%)": 100, + }; } export interface CarnivalJokeFilters { - [key: string]: number; -} \ No newline at end of file + [key: string]: number; +} diff --git a/src/jokes/crazy_letters.ts b/src/jokes/crazy_letters.ts index 2b0f91e..bfff8b1 100644 --- a/src/jokes/crazy_letters.ts +++ b/src/jokes/crazy_letters.ts @@ -3,41 +3,41 @@ import $ from "jquery"; /** * **Мама, Я сОшЛа С уМа!** - * + * * иМеНа ЗаБоРчИкОм - * + * * @author Kozhilya */ export class CrazyLettersJoke extends Joke { - id = 'crazy_letters'; + id = "crazy_letters"; - title = 'Мама, Я сОшЛа С уМа!'; + title = "Мама, Я сОшЛа С уМа!"; - description = 'иМеНа ЗаБоРчИкОм'; + description = "иМеНа ЗаБоРчИкОм"; - settings = new CrazyLettersJokeSettings; + settings = new CrazyLettersJokeSettings(); - start(): void { - $(this.settings.selector).each((_, elem) => { - let text = $(this).text(); - let result = ''; + start(): void { + $(this.settings.selector).each((_, elem) => { + let text = $(this).text(); + let result = ""; - for (let i = 0; i < text.length; i++) { - result += text[i][(i % 2) ? 'toLowerCase' : 'toUpperCase'](); - } + for (let i = 0; i < text.length; i++) { + result += text[i][i % 2 ? "toLowerCase" : "toUpperCase"](); + } - $(this).text(result); - }); - } + $(this).text(result); + }); + } } export class CrazyLettersJokeSettings implements JokeSettings { - enabled: boolean = true; + enabled: boolean = true; - chance: number = 20; + chance: number = 20; - /** - * Селектор всех элементов, которые будут затронуты - */ - selector: string = '.pa-author a'; -} \ No newline at end of file + /** + * Селектор всех элементов, которые будут затронуты + */ + selector: string = ".pa-author a"; +} diff --git a/src/jokes/cursor.ts b/src/jokes/cursor.ts index 298c82a..a98efc1 100644 --- a/src/jokes/cursor.ts +++ b/src/jokes/cursor.ts @@ -6,319 +6,333 @@ const cursor_effects = require("cursor-effects"); /** * **Красивый курсор** - * + * * Эффекты, следующие за курсором - * + * * @author Tim Holman * @link https://tholman.com/cursor-effects/ */ export class CursorEffectsJoke extends StopableJoke { - id = 'cursor_effects'; + id = "cursor_effects"; - title = 'Красивый курсор'; + title = "Красивый курсор"; - description = 'Эффекты, следующие за курсором'; + description = "Эффекты, следующие за курсором"; - settings = new CursorEffectsJokeSettings; + settings = new CursorEffectsJokeSettings(); - active_cursor_effect: any; - - /** - * Разблокировать все варианты курсоров - */ - enableAll() { - for (const key of Object.keys(this.settings.effects)) { - this.settings.effects[ key].enabled = true; - } - } - - /** - * Заблокировать все варианты курсоров - */ - disableAll() { - for (const key of Object.keys(this.settings.effects)) { - this.settings.effects[ key].enabled = false; - } + active_cursor_effect: any; + + /** + * Разблокировать все варианты курсоров + */ + enableAll() { + for (const key of Object.keys(this.settings.effects)) { + this.settings.effects[key].enabled = true; + } + } + + /** + * Заблокировать все варианты курсоров + */ + disableAll() { + for (const key of Object.keys(this.settings.effects)) { + this.settings.effects[key].enabled = false; + } + } + + private weight(effect: CursorEffectsEnum): number { + const s = this.settings.effects[effect]; + return s.enabled ? s.weight : 0; + } + + getRandomEffect(): CursorEffectsEnum { + const elements = Object.values(CursorEffectsEnum).map( + (e) => e + ); + const totalWeight = elements.reduce( + (sum, element) => sum + this.weight(element), + 0 + ); + const randomWeight = Math.random() * totalWeight; + + let currentWeight = 0; + for (const element of elements) { + currentWeight += this.weight(element); + if (randomWeight <= currentWeight) { + return element; + } } - private weight(effect: CursorEffectsEnum): number { - const s = this.settings.effects[effect]; - return s.enabled ? s.weight : 0; - } + throw new Error("Тебя быть тут не должно..."); + } - getRandomEffect(): CursorEffectsEnum { - const elements = Object.values(CursorEffectsEnum).map(e => e); - const totalWeight = elements.reduce((sum, element) => sum + this.weight(element), 0); - const randomWeight = Math.random() * totalWeight; - - let currentWeight = 0; - for (const element of elements) { - currentWeight += this.weight(element); - if (randomWeight <= currentWeight) { - return element; - } - } + start(): void { + const effect = this.getRandomEffect(); + const settings = this.settings.effects[effect]; - throw new Error("Тебя быть тут не должно..."); - } - - start(): void { - const effect = this.getRandomEffect(); - const settings = this.settings.effects[effect]; + this.active_cursor_effect = resolveCursorEffectsEnum(effect, settings); + } - this.active_cursor_effect = resolveCursorEffectsEnum(effect, settings); - } - - stop(): void { - this.active_cursor_effect.destroy(); - } + stop(): void { + this.active_cursor_effect.destroy(); + } } enum CursorEffectsEnum { - Rainbow = 'rainbow', - FairyDust = 'fairy_dust', - SpringyEmoji = 'springy_emoji', - Emoji = 'emoji', - Ghost = 'ghost', - Trailing = 'trailing', - TextFlag = 'text_flag', - FollowingDot = 'following_dot', - Bubbles = 'bubbles', - Snowflake = 'snowflake', - Clock = 'clock' + Rainbow = "rainbow", + FairyDust = "fairy_dust", + SpringyEmoji = "springy_emoji", + Emoji = "emoji", + Ghost = "ghost", + Trailing = "trailing", + TextFlag = "text_flag", + FollowingDot = "following_dot", + Bubbles = "bubbles", + Snowflake = "snowflake", + Clock = "clock", } -function resolveCursorEffectsEnum(effect: CursorEffectsEnum|string, options: CursorEffectsSetting): any { - switch (effect) { - case CursorEffectsEnum.Rainbow: - return cursor_effects.rainbowCursor(options); +function resolveCursorEffectsEnum( + effect: CursorEffectsEnum | string, + options: CursorEffectsSetting +): any { + switch (effect) { + case CursorEffectsEnum.Rainbow: + return cursor_effects.rainbowCursor(options); - case CursorEffectsEnum.FairyDust: - return cursor_effects.fairyDustCursor(options); + case CursorEffectsEnum.FairyDust: + return cursor_effects.fairyDustCursor(options); - case CursorEffectsEnum.SpringyEmoji: - return cursor_effects.springyEmojiCursor(options); + case CursorEffectsEnum.SpringyEmoji: + return cursor_effects.springyEmojiCursor(options); - case CursorEffectsEnum.Emoji: - return cursor_effects.emojiCursor(options); + case CursorEffectsEnum.Emoji: + return cursor_effects.emojiCursor(options); - case CursorEffectsEnum.Ghost: - return cursor_effects.ghostCursor(options); + case CursorEffectsEnum.Ghost: + return cursor_effects.ghostCursor(options); - case CursorEffectsEnum.Trailing: - return cursor_effects.trailingCursor(options); + case CursorEffectsEnum.Trailing: + return cursor_effects.trailingCursor(options); - case CursorEffectsEnum.TextFlag: - return cursor_effects.textFlag(options); + case CursorEffectsEnum.TextFlag: + return cursor_effects.textFlag(options); - case CursorEffectsEnum.FollowingDot: - return cursor_effects.followingDotCursor(options); + case CursorEffectsEnum.FollowingDot: + return cursor_effects.followingDotCursor(options); - case CursorEffectsEnum.Bubbles: - return cursor_effects.bubbleCursor(options); + case CursorEffectsEnum.Bubbles: + return cursor_effects.bubbleCursor(options); - case CursorEffectsEnum.Snowflake: - return cursor_effects.snowflakeCursor(options); + case CursorEffectsEnum.Snowflake: + return cursor_effects.snowflakeCursor(options); - case CursorEffectsEnum.Clock: - return cursor_effects.clockCursor(options); - } + case CursorEffectsEnum.Clock: + return cursor_effects.clockCursor(options); + } } export class CursorEffectsJokeSettings implements JokeSettings { - enabled: boolean = true; + enabled: boolean = true; - chance: number = 100; + chance: number = 100; - effects: { [key in CursorEffectsEnum]?: CursorEffectsSetting } = { + effects: { [key in CursorEffectsEnum]?: CursorEffectsSetting } = { + /** + * Радужный след за курсором + */ + [CursorEffectsEnum.Rainbow]: + new (class extends DefaultCursorEffectsSetting { /** - * Радужный след за курсором + * Длина полосы */ - [CursorEffectsEnum.Rainbow]: new class extends DefaultCursorEffectsSetting { - /** - * Длина полосы - */ - length: number = 20; - - /** - * Ширина полосы - */ - size: number = 3; - - /** - * Цвета полос (сверху вниз) - */ - colors: string[] = [ - "#9400D3", - "#4B0082", - "#0000FF", - "#00FF00", - "#FFFF00", - "#FF7F00", - "#FF0000" - ]; - }, + length: number = 20; /** - * Цепочка из эмодзи "на резинке" под курсором + * Ширина полосы */ - [CursorEffectsEnum.SpringyEmoji]: new class extends DefaultCursorEffectsSetting { - /** - * Висящий эмодзи - */ - emoji: string = "🤪" - }, + size: number = 3; /** - * Падающие от курсора эмодзи + * Цвета полос (сверху вниз) */ - [CursorEffectsEnum.Emoji]: new class extends DefaultCursorEffectsSetting { - /** - * Падающие эмодзи - */ - emoji: string[] = ["🔥", "🐬", "🦆"] - }, + colors: string[] = [ + "#9400D3", + "#4B0082", + "#0000FF", + "#00FF00", + "#FFFF00", + "#FF7F00", + "#FF0000", + ]; + })(), + + /** + * Цепочка из эмодзи "на резинке" под курсором + */ + [CursorEffectsEnum.SpringyEmoji]: + new (class extends DefaultCursorEffectsSetting { + /** + * Висящий эмодзи + */ + emoji: string = "🤪"; + })(), + + /** + * Падающие от курсора эмодзи + */ + [CursorEffectsEnum.Emoji]: new (class extends DefaultCursorEffectsSetting { + /** + * Падающие эмодзи + */ + emoji: string[] = ["🔥", "🐬", "🦆"]; + })(), + + /** + * Падающие от курсора пылинки + */ + [CursorEffectsEnum.FairyDust]: + new (class extends DefaultCursorEffectsSetting { + /** + * Цвет пылинок + */ + colors: string[] = ["#ff0000", "#00ff00", "#0000ff"]; + })(), + + /** + * След "зависших" курсоров + */ + [CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting(), + + /** + * След курсоров "на резинке" + */ + [CursorEffectsEnum.Trailing]: + new (class extends DefaultCursorEffectsSetting { + /** + * Количество элементов + */ + particles: number = 15; /** - * Падающие от курсора пылинки + * Скорость частиц */ - [CursorEffectsEnum.FairyDust]: new class extends DefaultCursorEffectsSetting { - /** - * Цвет пылинок - */ - colors: string[] = ["#ff0000", "#00ff00", "#0000ff"]; - }, + rate: number = 0.4; /** - * След "зависших" курсоров + * Ссылка на картинку с курсором + * Используйте `null`, что бы использовать картинку курсора по умолчанию */ - [CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting, + baseImageSrc: string | null = null; + })(), + + /** + * Текст, развивающийся флагом от курсора + */ + [CursorEffectsEnum.TextFlag]: + new (class extends DefaultCursorEffectsSetting { + /** + * Отображаемый текст + */ + text: string = "С днём смеха!"; /** - * След курсоров "на резинке" + * Цвет текста */ - [CursorEffectsEnum.Trailing]: new class extends DefaultCursorEffectsSetting { - /** - * Количество элементов - */ - particles: number = 15; - - /** - * Скорость частиц - */ - rate: number = 0.4; - - /** - * Ссылка на картинку с курсором - * Используйте `null`, что бы использовать картинку курсора по умолчанию - */ - baseImageSrc: string | null = null; - }, + color: string = "#000000"; /** - * Текст, развивающийся флагом от курсора + * Шрифт текста */ - [CursorEffectsEnum.TextFlag]: new class extends DefaultCursorEffectsSetting { - /** - * Отображаемый текст - */ - text: string = "С днём смеха!"; - - /** - * Цвет текста - */ - color: string = "#000000"; - - /** - * Шрифт текста - */ - font: string = "monospace"; - - /** - * Размер текста - */ - textSize: number = 12; - - /** - * Растояние между бквами - */ - gap: number = 14; - - /** - * Размер... чего-то. - */ - size: number = 3; - - }, + font: string = "monospace"; /** - * Точка, преследующая курсор + * Размер текста */ - [CursorEffectsEnum.FollowingDot]: new class extends DefaultCursorEffectsSetting { - /** - * Цвет догоняющей точки - */ - color: string = "#323232a6"; - }, - - /** - * Пузырьки от курсора - */ - [CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting, + textSize: number = 12; /** - * Снежинки, летящие от курсора - * - * Отключено, потому что сейчас не зима :D + * Растояние между бквами */ - [CursorEffectsEnum.Snowflake]: new class extends DefaultCursorEffectsSetting { - weight: number = 0; - }, + gap: number = 14; /** - * Циферблат вокруг курсора + * Размер... чего-то. */ - [CursorEffectsEnum.Clock]: new class extends DefaultCursorEffectsSetting { - /** - * Цвет даты - */ - dateColor: string = "blue"; + size: number = 3; + })(), - /** - * Цвет циферблата - */ - faceColor: string = "black"; - - /** - * Цвет секундной стрелки - */ - secondsColor: string = "red"; - - /** - * Цвет минутной стрелки - */ - minutesColor: string = "black"; - - /** - * Цвет часовой стрелки - */ - hoursColor: string = "black"; - }, - }; + /** + * Точка, преследующая курсор + */ + [CursorEffectsEnum.FollowingDot]: + new (class extends DefaultCursorEffectsSetting { + /** + * Цвет догоняющей точки + */ + color: string = "#323232a6"; + })(), + + /** + * Пузырьки от курсора + */ + [CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting(), + + /** + * Снежинки, летящие от курсора + * + * Отключено, потому что сейчас не зима :D + */ + [CursorEffectsEnum.Snowflake]: + new (class extends DefaultCursorEffectsSetting { + weight: number = 0; + })(), + + /** + * Циферблат вокруг курсора + */ + [CursorEffectsEnum.Clock]: new (class extends DefaultCursorEffectsSetting { + /** + * Цвет даты + */ + dateColor: string = "blue"; + + /** + * Цвет циферблата + */ + faceColor: string = "black"; + + /** + * Цвет секундной стрелки + */ + secondsColor: string = "red"; + + /** + * Цвет минутной стрелки + */ + minutesColor: string = "black"; + + /** + * Цвет часовой стрелки + */ + hoursColor: string = "black"; + })(), + }; } interface CursorEffectsSetting { - [key: string]: any; + [key: string]: any; } class DefaultCursorEffectsSetting implements CursorEffectsSetting { - /** - * Флаг возможности срабатывания - */ - enabled: boolean = true; + /** + * Флаг возможности срабатывания + */ + enabled: boolean = true; - /** - * Весовой коэффициент вероятности курсора - */ - weight: number = 50; + /** + * Весовой коэффициент вероятности курсора + */ + weight: number = 50; } diff --git a/src/jokes/humanitarian_hell.ts b/src/jokes/humanitarian_hell.ts index 658de9d..5869a6d 100644 --- a/src/jokes/humanitarian_hell.ts +++ b/src/jokes/humanitarian_hell.ts @@ -1,38 +1,45 @@ import { Joke, JokeSettings, StopableJoke } from "../joke"; +import { getTextNodes } from "../common"; import $ from "jquery"; /** * **Ад гуманитария** - * + * * Все "тся" заменяются на "ться", а все "ться" на "тся" - * + * * @author Kozhilya */ export class HumanitarianHellJoke extends Joke { - id = 'humanitarian_hell'; + id = "humanitarian_hell"; - title = 'Ад гуманитария'; + title = "Ад гуманитария"; - description = 'Все "тся" заменяются на "ться", а все "ться" на "тся"'; - - settings = new HumanitarianHellJokeSettings; + description = 'Все "тся" заменяются на "ться", а все "ться" на "тся"'; - start(): void { - $(this.settings.selector).each(function () { - $(this).html($(this).html().replace(/(ть?ся)/g, function (fnd) { - return (fnd.indexOf('ь') > 0) ? 'тся' : 'ться'; - })); - }); - } + settings = new HumanitarianHellJokeSettings(); + + processText(text: string): string { + return text.replace(/(ть?ся)/g, function (fnd) { + return fnd.indexOf("ь") > 0 ? "тся" : "ться"; + }); + } + + start(): void { + const textNodes = getTextNodes(this.settings.selector); + + textNodes.each((_, elem) => { + elem.textContent = this.processText(elem.textContent); + }); + } } export class HumanitarianHellJokeSettings implements JokeSettings { - enabled: boolean = true; + enabled: boolean = true; - chance: number = 20; + chance: number = 20; - /** - * Селектор всех элементов, которые будут затронуты - */ - selector: string = '.post-content'; -} \ No newline at end of file + /** + * Селектор всех элементов, которые будут затронуты + */ + selector: string = ".post-content"; +} diff --git a/src/jokes/letter_chaos.ts b/src/jokes/letter_chaos.ts index 771e023..c53c469 100644 --- a/src/jokes/letter_chaos.ts +++ b/src/jokes/letter_chaos.ts @@ -1,68 +1,79 @@ import { Joke, JokeSettings, StopableJoke } from "../joke"; +import { getTextNodes } from "../common"; import $ from "jquery"; import { JokerClass } from "../joker"; /** * **Буквенный хаос** - * - * Все буквы в словах, кроме первой и последней, перемешены. - * + * + * Все буквы в словах, кроме первой и последней, перемешены + * * @author Kozhilya */ export class LetterChaosJoke extends Joke { - id = 'letter_chaos'; + id = "letter_chaos"; - title = 'Буквенный хаос'; + title = "Буквенный хаос"; - description = 'Все буквы в словах, кроме первой и последней, перемешены.'; + description = "Все буквы в словах, кроме первой и последней, перемешены"; - settings = new LetterChaosJokeSettings; + settings = new LetterChaosJokeSettings(); - punctuationSymbols: string[] | null = null; + punctuationSymbols: string[] | null = null; - private shuffleLetters(word: string): string { - // Check if the word has two or more letters - if ((word.length < 3) || !this.check(this.settings.shuffle_chance)) { - return word; - } - - // Split the word into an array of characters - const characters = word.split(""); - - // Shuffle the characters between the first and last letters - const middleCharacters = characters.slice(1, -1); - for (let i = middleCharacters.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [middleCharacters[i], middleCharacters[j]] = [middleCharacters[j], middleCharacters[i]]; - } - - // Join the shuffled characters back into a word - return [characters[0], ...middleCharacters, characters[characters.length - 1]].join(""); + private shuffleLetters(word: string): string { + // Check if the word has two or more letters + if (word.length < 3 || !this.check(this.settings.shuffle_chance)) { + return word; } - private processNode(node: any) { - node.textContent = node.textContent?.replace(/([А-Яа-яA-Za-z]+)/gm, this.shuffleLetters); + // Split the word into an array of characters + const characters = word.split(""); + + // Shuffle the characters between the first and last letters + const middleCharacters = characters.slice(1, -1); + for (let i = middleCharacters.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [middleCharacters[i], middleCharacters[j]] = [ + middleCharacters[j], + middleCharacters[i], + ]; } - start(): void { - const items = $(this.settings.selector).find('*').contents().filter((_, node) => node.nodeType === Node.TEXT_NODE); + // Join the shuffled characters back into a word + return [ + characters[0], + ...middleCharacters, + characters[characters.length - 1], + ].join(""); + } - items.each((_, node) => this.processNode(node)) - } + private processNode(node: any) { + node.textContent = node.textContent?.replace( + /([А-Яа-яA-Za-z]+)/gm, + this.shuffleLetters + ); + } + + start(): void { + const textNodes = getTextNodes(this.settings.selector); + + textNodes.each((_, node) => this.processNode(node)); + } } export class LetterChaosJokeSettings implements JokeSettings { - enabled: boolean = true; + enabled: boolean = true; - chance: number = 20; + chance: number = 20; - /** - * Селектор всех элементов, которые будут затронуты - */ - selector: string = '.post-content'; + /** + * Селектор всех элементов, которые будут затронуты + */ + selector: string = ".post-content"; - /** - * Вероятность того, что буквы будут перемешаны - */ - shuffle_chance: number = 50; + /** + * Вероятность того, что буквы будут перемешаны + */ + shuffle_chance: number = 50; } diff --git a/src/jokes/mirror.ts b/src/jokes/mirror.ts index 53cd7a1..451805d 100644 --- a/src/jokes/mirror.ts +++ b/src/jokes/mirror.ts @@ -3,30 +3,34 @@ import $ from "jquery"; /** * **Зеркало** - * + * * Элементы форума отражаются (по крайней мере, пытаются) - * + * * @author Kozhilya */ export class MirrorJoke extends Joke { - id = 'mirror'; + id = "mirror"; - title = 'Зеркало'; + title = "Зеркало"; - description = 'Элементы форума отражаются (по крайней мере, пытаются)'; - - settings = new MirrorJokeSettings; + description = "Элементы форума отражаются (по крайней мере, пытаются)"; - start(): void { - $('.post, .post h3, .post-links, .post-author, .post-content') - .css('transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('filter', 'FlipH').css('-ms-filter', '"FlipH"'); - $('.post-links, .post-links ul, .post h3 span').css('margin-left', '0'); - $('.post h3 span').css('margin-right', '25em'); - } + settings = new MirrorJokeSettings(); + + start(): void { + $(".post, .post h3, .post-links, .post-author, .post-content") + .css("transform", "scaleX(-1)") + .css("-moz-transform", "scaleX(-1)") + .css("-moz-transform", "scaleX(-1)") + .css("filter", "FlipH") + .css("-ms-filter", '"FlipH"'); + $(".post-links, .post-links ul, .post h3 span").css("margin-left", "0"); + $(".post h3 span").css("margin-right", "25em"); + } } export class MirrorJokeSettings implements JokeSettings { - enabled: boolean = false; + enabled: boolean = false; - chance: number = 30; -} \ No newline at end of file + chance: number = 30; +} diff --git a/src/jokes/shake.ts b/src/jokes/shake.ts index d3542bc..49ec8e4 100644 --- a/src/jokes/shake.ts +++ b/src/jokes/shake.ts @@ -3,95 +3,95 @@ import $ from "jquery"; /** * **Форумо-трясение** - * + * * Страница форума начинает трястись - * + * * @author Kozhilya */ export class ShakeJoke extends StopableJoke { - id = 'shake'; + id = "shake"; - title = 'Форумо-трясение'; + title = "Форумо-трясение"; - description = 'Страница форума начинает трястись'; + description = "Страница форума начинает трястись"; - settings = new ShakeJokeSettings; + settings = new ShakeJokeSettings(); - private interval_id: NodeJS.Timer; + private interval_id: NodeJS.Timer; - private items: JQuery; + private items: JQuery; - private data_name: string = 'april-fools-shake'; + private data_name: string = "april-fools-shake"; - rand(a: number): number { - return a + this.settings.force * (Math.random() * 2 - 1); - } + rand(a: number): number { + return a + this.settings.force * (Math.random() * 2 - 1); + } - start(): void { - this.items = $(this.settings.selector); + start(): void { + this.items = $(this.settings.selector); - this.items.each((_, elem) => { - let data: ShakeJokeMargin = {}; + this.items.each((_, elem) => { + let data: ShakeJokeMargin = {}; - this.settings.directions.forEach(d => { - data[d] = parseInt($(elem).css('margin-' + d)); - }); + this.settings.directions.forEach((d) => { + data[d] = parseInt($(elem).css("margin-" + d)); + }); - $(elem).data(this.data_name, data); - }); + $(elem).data(this.data_name, data); + }); - this.interval_id = setInterval(() => { - this.items.each((_, elem) => { - const data: ShakeJokeMargin = $(elem).data(this.data_name); + this.interval_id = setInterval(() => { + this.items.each((_, elem) => { + const data: ShakeJokeMargin = $(elem).data(this.data_name); - for (const entry of Object.entries(data)) { - $(elem).css('margin-' + entry[0], this.rand(entry[1])) - } - }); - }, this.settings.interval); - } + for (const entry of Object.entries(data)) { + $(elem).css("margin-" + entry[0], this.rand(entry[1])); + } + }); + }, this.settings.interval); + } - stop(): void { - clearInterval(this.interval_id); - - this.items.each((_, elem) => { - let data: ShakeJokeMargin = {}; + stop(): void { + clearInterval(this.interval_id); - this.settings.directions.forEach(d => { - $(elem).css('margin-' + d, data[d]); - }); + this.items.each((_, elem) => { + let data: ShakeJokeMargin = {}; - $(elem).data(this.data_name, data); - }); - } + this.settings.directions.forEach((d) => { + $(elem).css("margin-" + d, data[d]); + }); + + $(elem).data(this.data_name, data); + }); + } } export class ShakeJokeSettings implements JokeSettings { - enabled: boolean = false; + enabled: boolean = false; - chance: number = 1; + chance: number = 1; - /** - * Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения) - */ - directions: string[] = ['top', 'left', 'bottom', 'left']; + /** + * Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения) + */ + directions: string[] = ["top", "left", "bottom", "left"]; - /** - * Сила тряски - насколько отклоняется элемент от стандартного значения - */ - force: number = 0.5; + /** + * Сила тряски - насколько отклоняется элемент от стандартного значения + */ + force: number = 0.5; - /** - * Селектор всех элементов, которые будут трястись - */ - selector: string = '[id^=pun]'; + /** + * Селектор всех элементов, которые будут трястись + */ + selector: string = "[id^=pun]"; - /** - * Частота тряски - */ - interval: number = 100; + /** + * Частота тряски + */ + interval: number = 100; } export interface ShakeJokeMargin { - [key: string]: number; -} \ No newline at end of file + [key: string]: number; +} diff --git a/src/jokes/stupid_title.ts b/src/jokes/stupid_title.ts index 9ef6a3f..83ffba4 100644 --- a/src/jokes/stupid_title.ts +++ b/src/jokes/stupid_title.ts @@ -1,88 +1,99 @@ import { Joke, JokeSettings, StopableJoke } from "../joke"; import $ from "jquery"; +import { StupidTitleDefaultVariants } from "../data/stupid_title_variants"; /** * **Глупые статусы** - * - * Каждому пользователю даётся новый глупый статус. - * + * + * Каждому пользователю даётся новый глупый статус + * * @author Kozhilya */ export class StupidTitleJoke extends Joke { - id = 'stupid_title'; + id = "stupid_title"; - title = 'Глупые статусы'; + title = "Глупые статусы"; - description = 'Каждому пользователю даётся новый глупый статус.'; + description = "Каждому пользователю даётся новый глупый статус"; - settings = new StupidTitleJokeSettings; + settings = new StupidTitleJokeSettings(); - private loadedGenders: any = null; + private loadedGenders: any = null; - async loadGenders(): Promise { - const names = $('.pa-author a') - .map((_, elem) => elem.innerText).toArray() - .reduce((arr: string[], name: string) => { - if (arr.indexOf(name) < 0){ - arr.push(name); - } - return arr - }, []); - - const url = '/api.php?' + $.param({ method: 'users.get', fields: 'username,sex', username: names }); - const response = await fetch(url); - const json = await response.json(); - - this.loadedGenders = {}; - - if (json.error) { - return; + async loadGenders(): Promise { + const names = $(".pa-author a") + .map((_, elem) => elem.innerText) + .toArray() + .reduce((arr: string[], name: string) => { + if (arr.indexOf(name) < 0) { + arr.push(name); } + return arr; + }, []); - json.response.users.forEach((element: any) => { - if (element.sex === '0') { - return; - } + const url = + "/api.php?" + + $.param({ method: "users.get", fields: "username,sex", username: names }); + const response = await fetch(url); + const json = await response.json(); - this.loadedGenders[element.username] = element.sex === '1'; - }); + this.loadedGenders = {}; + + if (json.error) { + return; } - resolveGender(name: string): boolean { - if (this.settings.gender_resolver !== null) { - return !!this.settings.gender_resolver.call(this, name); - } + json.response.users.forEach((element: any) => { + if (element.sex === "0") { + return; + } - if (name in this.loadedGenders) { - return !!this.loadedGenders[name]; - } + this.loadedGenders[element.username] = element.sex === "1"; + }); + } + resolveGender(name: string): boolean { + if (this.settings.gender_resolver !== null) { + return !!this.settings.gender_resolver.call(this, name); + } + + if (name in this.loadedGenders) { + return !!this.loadedGenders[name]; + } + + this.resetSeed(); + return this.selectRandom(name, { m: 1, f: 1 }) === "m"; + } + + private variantsGenerated = false; + + async start(): Promise { + if (!this.variantsGenerated) { + StupidTitleDefaultVariants(this.settings.variants); + this.variantsGenerated = true; + } + + await this.loadGenders(); + + const cache: any = {}; + + $(".post-author").each((_, root) => { + const name = $(".pa-author a", root).text(); + if (!name) { + return; + } + + if (!(name in cache)) { this.resetSeed(); - return this.selectRandom(name, { 'm': 1, 'f': 1 }) === 'm'; - } + cache[name] = this.generatePhrase(name); + } - async start(): Promise { - await this.loadGenders(); + $(".pa-title", root).text(cache[name]); + }); + } - const cache: any = {}; - - $('.post-author').each((_, root) => { - const name = $('.pa-author a', root).text(); - if (!name) { - return; - } - - if (!(name in cache)) { - this.resetSeed(); - cache[name] = this.generatePhrase(name); - } - - $('.pa-title', root).text(cache[name]); - }); - } - - private prng(name: string, seed: number, limit: number): number { - /* + private prng(name: string, seed: number, limit: number): number { + /* https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js cyrb53 (c) 2018 bryc (github.com/bryc) @@ -90,223 +101,230 @@ export class StupidTitleJoke extends Joke { Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. Public domain. Attribution appreciated. */ - let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; - for (let i = 0, ch; i < name.length; i++) { - ch = name.charCodeAt(i); - h1 = Math.imul(h1 ^ ch, 2654435761); - h2 = Math.imul(h2 ^ ch, 1597334677); - } - h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909); - h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909); - - const value = 4294967296 * (2097151 & h2) + (h1>>>0); - - return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit; + let h1 = 0xdeadbeef ^ seed, + h2 = 0x41c6ce57 ^ seed; + for (let i = 0, ch; i < name.length; i++) { + ch = name.charCodeAt(i); + h1 = Math.imul(h1 ^ ch, 2654435761); + h2 = Math.imul(h2 ^ ch, 1597334677); + } + h1 = + Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ + Math.imul(h2 ^ (h2 >>> 13), 3266489909); + h2 = + Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ + Math.imul(h1 ^ (h1 >>> 13), 3266489909); + + const value = 4294967296 * (2097151 & h2) + (h1 >>> 0); + + return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit; + } + + private seed = 0; + + private resetSeed(): void { + const date = new Date(); + const time = date.getUTCHours() * 60 + date.getUTCMinutes(); + + if (this.settings.change_frequency === 0) { + this.seed = time * 60 + date.getUTCSeconds(); + return; } - private seed = 0; + this.seed = Math.floor(time / this.settings.change_frequency); + } - private resetSeed(): void { - const date = new Date(); - const time = new Date().getUTCHours() * 60 + new Date().getUTCMinutes(); - this.seed = Math.floor(time / this.settings.change_frequency); + private selectRandom( + name: string, + variants: StupidTitleWeightedVariants + ): string { + const elements = Object.keys(variants); + const totalWeight = elements.reduce( + (sum, element) => sum + variants[element], + 0 + ); + const randomWeight = this.prng(name, this.seed++, totalWeight); - console.log('Seed reset:', time, this.seed); + let currentWeight = 0; + for (const element of elements) { + currentWeight += variants[element]; + if (randomWeight <= currentWeight) { + return element; + } } - private selectRandom(name: string, variants: StupidTitleWeightedVariants): string { - const elements = Object.keys(variants); - const totalWeight = elements.reduce((sum, element) => sum + variants[element], 0); - const randomWeight = this.prng(name, this.seed++, totalWeight); - - let currentWeight = 0; - for (const element of elements) { - currentWeight += variants[element]; - if (randomWeight <= currentWeight) { - return element; - } - } + throw new Error("Тебя быть тут не должно..."); + } - throw new Error("Тебя быть тут не должно..."); + private buildVariants( + type: string, + gender: boolean + ): StupidTitleWeightedVariants { + const result: StupidTitleWeightedVariants = {}; + const variants: StupidTitleVariant = this.settings.variants[type]; + + for (const iterator of Object.entries(variants)) { + const word = iterator[0]; + const wordSettings = iterator[1]; + + if (!wordSettings.enabled || wordSettings.gender === !gender) { + continue; + } + + if (!this.settings.rude && wordSettings.rude) { + continue; + } + + result[word] = wordSettings.weight; } - private buildVariants(type: string, gender: boolean): StupidTitleWeightedVariants { - const result: StupidTitleWeightedVariants = {}; - const variants: StupidTitleVariant = this.settings.variants[type]; + return result; + } - for (const iterator of Object.entries(variants)) { - const word = iterator[0]; - const wordSettings = iterator[1]; - - if (!wordSettings.enabled || (wordSettings.gender === !gender)) { - continue; - } + private capitalizeFirst(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); + } - if (!this.settings.rude && wordSettings.rude) { - continue; - } + generatePhrase(name: string): string { + const gender = this.resolveGender(name); + const prhase = this.selectRandom(name, this.settings.schemas); - result[word] = wordSettings.weight; - } - - return result; - } + return this.capitalizeFirst( + prhase.replace(/\{(.+?)\}/g, (_, type: string) => { + const variants = this.buildVariants(type, gender); - private capitalizeFirst(str: string): string { - return str.charAt(0).toUpperCase() + str.slice(1); - } - - generatePhrase(name: string): string { - const gender = this.resolveGender(name); - const prhase = this.selectRandom(name, this.settings.schemas); - - return this.capitalizeFirst(prhase.replace(/\{(.+?)\}/g, (_, type: string) => { - const variants = this.buildVariants(type, gender); - - return this.selectRandom(name, variants); - })); - } + return this.selectRandom(name, variants); + }) + ); + } } export class StupidTitleJokeSettings implements JokeSettings { - enabled: boolean = true; - chance: number = 100; + enabled: boolean = true; + chance: number = 100; - /** - * Определение пола по имени. - * По умолчанию род устанавливается случайным образом - * - * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом. - * - * @param name Имя персонажа - * @returns true, если мужской род; false, если женский род - */ - gender_resolver: Function | null = null; + /** + * Определение пола по имени. + * По умолчанию род устанавливается случайным образом + * + * Если установлено значение `null`, система попытается загрузить пол, установленный в настройках аккаунта. Если этот пол определить невозможно, то он будет выбран случайно. Эта настройка позволяет изменить это поведение, если ваш форум обладает ролевой системой, в которой пол определяется иным образом. + * + * @param name Имя персонажа + * @returns true, если мужской род; false, если женский род + */ + gender_resolver: Function | null = null; - /** - * Разрешить возможно оскорбительные варианты - */ - rude: boolean = false; + /** + * Разрешить возможно оскорбительные варианты + */ + rude: boolean = false; - /** - * Частота смены статусов (в минутах) - */ - change_frequency: number = 5; + /** + * Частота смены статусов (в минутах) + * Установите значение 0, что бы обновление происходило при каждом обновлении страницы + */ + change_frequency: number = 5; - /** - * Разрешённые схемы формирования статусов - * - * {adj} - прилагательное - * {noun} - имя существительно - * {verb} - глагол - * {adv} - наречие - * {place} - дополнение места - * {p} - знак препинания - */ - schemas: StupidTitleWeightedVariants = { - '{adj} {noun}{p}': 10, - '{noun} {adj}{p}': 3, - '{adj}, {adj} {noun}{p}': 10, - '{adj} и очень {adj} {noun}{p}': 10, - '{adj} {noun} {verb}{p}': 10, - '{adj} {noun} {adv} {verb}{p}': 5, - '{adj} {noun} {verb} {place}{p}': 5, - '{adj} {noun} {adv} {verb} {place}{p}': 5, - }; - - /** - * Вариант слов - * Смотрите раздел описания скрипта, что бы настроить это поле - */ - variants: StupidTitleVariants = { - adj: { - ...buildVariant(true, 'жесткий,^удачливый,низкий,знакомый,откровенный,^мирный,грамотный,вкусный,виртуальный,пышный,провинциальный,$жирный,заинтересованный,объективный,^оригинальный,пожилой,чистый,особенный,выгодный,громадный,обыкновенный,чужой,ударный,^солнечный,истинный,посторонний,южный,седой,$бесполезный,острый,пестрый,формальный,повседневный,невозможный,$жалкий,целый,$глупый,последний,выходной,серьезный,подземный,небесный,любимый,былой,семейный,далекий,северный,суровый,гигантский,иностранный,родной,конструктивный,показательный,нужный,чрезвычайный,гордый,банальный,открытый,независимый,запасной,мстительный,грубый,алчный,мелочный,хладнокровный,спокойный,терпеливый,креативный,активный,адекватный,застенчивый,опрятный,безнадёжный,уверенный в себе,доброжелательный,ласковый,робкий,воспитанный,самовлюблённый,деятельный,двуличный,верный'), - ...buildVariant(false, 'жесткая,^удачливая,низкая,знакомая,откровенная,^мирная,грамотная,вкусная,виртуальная,пышная,провинциальная,$жирная,заинтересованная,объективная,^оригинальная,пожилая,чистая,особенная,выгодная,громадная,обыкновенная,чужая,ударная,^солнечная,истинная,посторонняя,южная,седая,$бесполезная,острая,пестрая,формальная,повседневная,невозможная,$жалкая,целая,$глупая,последняя,выходная,серьезная,подземная,небесная,любимая,былая,семейная,далекая,северная,суровая,гигантская,иностранная,родная,конструктивная,показательная,нужная,чрезвычайная,гордая,банальная,открытая,независимая,запасная,мстительная,грубая,алчная,мелочная,хладнокровная,спокаяная,терпеливая,креативная,активная,адекватная,застенчивая,опрятная,безнадёжная,уверенная в себе,доброжелательная,ласковая,робкая,воспитанная,самовлюблённая,деятельная,двуличная,верная'), - }, - noun: { - ...buildVariant(null, ''), - - ...buildVariant(true, 'орёл, ниндзя, манекен, пузырь, бродяга, рыцарь, кентавр, зайц, диван, наследник, сын, джентльмен, басурманин, карасик, $злоумышленник, $раб, хоббит, одиночка, отец, кролик, бруталище, дворф, актёр, %дед, спортсмен, $балбес, %мальчег, лев, ёж, организм, монах, хоббит, борец, тигр, монстр, массажист, мачо, эльф, ледник, жук, кот, зомби, проказник, дракон, носорог, волк, лесоруб, кит, %дедушка, динозавр, бард, кулак, принц, %сынок, мальчик, товарищ, ёжик, сурикат'), - - ...buildVariant(false, 'заноза, волторна, $личинка, детка, %бабушка, простуда, черепашка, мышь, волчица, деревяшка, пиранья, каруселька, красотка, леди, %дочка, орлица, принцесса, $ведьма, травка, актриса, наследница, %деффачка, горгулья, белочка, акула, машинка, конфетка, знаменитость, косточка, спортсменка, панда, мать, львица, эльфийка, $злоумышленница, чертовка, дворфиха, кошка, $рабыня, скамеечка, дочь, монашка, бактерия, рыбка, бусинка, $бабка, девочка, валькирия, килька, бабочка, милашка, крышка, тигрица, рыбка, русалочка'), - }, - verb: { - ...buildVariant(null, 'встаёт, снимает, приказывает, указывает, собирается, чувствует опасность, орёт, болеет, поздравляет, освобождает, поздравляет, бежит, берёт и делает, молчит, радуется, прощает, читает, снимает, снимается в фильме, что-то скрывает, думает, имеет план и придерживается его, тянет, работает, меняется, ловит, отказаться куда-то идти, заходит, замирает, оформляет, нарушает, отказывается что-то делать, шепчет, снимается в сериале, скрывается, учит, спрашивает, идёт, отказывается вставать, прибывает, отказывается, забывает, получает, плывёт, отвечает, поглядывает, говорит, просыпается, соединяет, оглядывается'), - - ...buildVariant(true, 'женится, женился, успел, не успел, смог, скрылся, заработался, познал дзен, присел, обиделся, проснулся, взял и сделал, додумался, не спал'), - - ...buildVariant(false, 'выходит замуж, вышла замуж, успела, не успела, смогла, скрылась, заработалась, познала дзен, присела, обиделась, проснулась, взяла и сделала, додумалась, не спала'), - }, - place: { - ...buildVariant(null, 'где-то, в пустыне, на пляже, под дождём, %под проливным дождём, в квартире, %в тёплой и уютной квартире, в космосе, в театре, в филармонии, на заснеженной вершине, на конференции, на форуме, в очереди, в лесу, в джунглях, под водой'), - }, - adv: { - ...buildVariant(null, 'счастливо, уныло, грустно, позже, немедленно, регулярно, вновь, опять, уже, внезапно, предсказуемо, медленно, быстро, %молниеносно, $грубо, безрассудно, осмысленно, расчётливо'), - }, - p: { - '': new StupidTitleSetting({ weight: 10 }), - '.': new StupidTitleSetting({ weight: 10 }), - '...': new StupidTitleSetting({ weight: 5 }), - '!': new StupidTitleSetting({ weight: 5 }), - '!!!': new StupidTitleSetting({ weight: 2 }), - '?': new StupidTitleSetting({ weight: 2 }), - '?!': new StupidTitleSetting({ weight: 1 }), - }, - }; + /** + * Разрешённые схемы формирования статусов + * + * {adj} - прилагательное + * {noun} - имя существительно + * {verb} - глагол + * {adv} - наречие + * {place} - дополнение места + * {p} - знак препинания + */ + schemas: StupidTitleWeightedVariants = { + "{adj} {noun}{p}": 10, + "{noun} {adj}{p}": 3, + "{adj}, {adj} {noun}{p}": 10, + "{adj} и очень {adj} {noun}{p}": 10, + "{adj} {noun} {verb}{p}": 10, + "{adj} {noun} {adv} {verb}{p}": 5, + "{adj} {noun} {verb} {place}{p}": 5, + "{adj} {noun} {adv} {verb} {place}{p}": 5, + }; + /** + * Вариант слов + * Смотрите раздел описания скрипта, что бы настроить это поле + */ + variants: StupidTitleVariants = { + adj: {}, + noun: {}, + verb: {}, + place: {}, + adv: {}, + p: { + "": new StupidTitleSetting({ weight: 10 }), + ".": new StupidTitleSetting({ weight: 10 }), + "...": new StupidTitleSetting({ weight: 5 }), + "!": new StupidTitleSetting({ weight: 5 }), + "!!!": new StupidTitleSetting({ weight: 2 }), + "?": new StupidTitleSetting({ weight: 2 }), + "?!": new StupidTitleSetting({ weight: 1 }), + }, + }; } -interface StupidTitleVariants { - [key: string]: StupidTitleVariant +export interface StupidTitleVariants { + [key: string]: StupidTitleVariant; } interface StupidTitleVariant { - [key: string]: StupidTitleSetting + [key: string]: StupidTitleSetting; } interface StupidTitleWeightedVariants { - [key: string]: number + [key: string]: number; } class StupidTitleSetting { - weight: number = 10; + weight: number = 10; - enabled: boolean = true; - - rude: boolean = false; + enabled: boolean = true; - gender: boolean|null = null; + rude: boolean = false; - constructor(options: any = new Object) { - for (const iterator of Object.entries(options)) { - if (iterator[0] in this) { - ( this)[iterator[0]] = iterator[1]; - } - } + gender: boolean | null = null; + + constructor(options: any = new Object()) { + for (const iterator of Object.entries(options)) { + if (iterator[0] in this) { + (this)[iterator[0]] = iterator[1]; + } } + } } -function buildVariant(gender: boolean|null, input: string): StupidTitleVariant -{ - const result: StupidTitleVariant = {}; - const words = input.split(',').map(word => word.trim()); - - words.forEach(word => { - const clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\- ]/g, ''); +export function BuildStupdiTitleVariant( + gender: boolean | null, + input: string +): StupidTitleVariant { + const result: StupidTitleVariant = {}; + const words = input.split(",").map((word) => word.trim()); - if (clean_word === '') { - return; - } + words.forEach((word) => { + const clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\- ]/g, ""); - result[clean_word] = new StupidTitleSetting({ - gender, - rude: word.indexOf('$') >= 0, - enabled: word.indexOf('!') < 0, - weight: 10 * ((word.indexOf('$') >= 0) ? 0.5 : 1) * ((word.indexOf('%') >= 0) ? 0.5 : 1) * ((word.indexOf('^') >= 0) ? 2 : 1) - }); + if (clean_word === "") { + return; + } + + result[clean_word] = new StupidTitleSetting({ + gender, + rude: word.indexOf("$") >= 0, + enabled: word.indexOf("!") < 0, + weight: + 10 * + (word.indexOf("$") >= 0 ? 0.5 : 1) * + (word.indexOf("%") >= 0 ? 0.5 : 1) * + (word.indexOf("^") >= 0 ? 2 : 1), }); + }); - return result; + return result; } -(window as any).BuildStupdiTitleVariant = buildVariant; \ No newline at end of file +(window as any).BuildStupdiTitleVariant = BuildStupdiTitleVariant; diff --git a/src/main.ts b/src/main.ts index f364710..3f0fb7b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,24 +10,24 @@ import { CursorEffectsJoke } from "./jokes/cursor"; import { StupidTitleJoke } from "./jokes/stupid_title"; (window as any).AprilJokes = ((jokes: JokeClassList): JokerClass => { - const cl = new JokerClass(); + const cl = new JokerClass(); - jokes.forEach(joke => { - cl.add(new joke()); - }); + jokes.forEach((joke) => { + cl.add(new joke()); + }); - $(() => cl.regularStart()); + $(() => cl.regularStart()); - return cl; + return cl; })([ - ShakeJoke, - HumanitarianHellJoke, - MirrorJoke, - CarnivalJoke, - CrazyLettersJoke, - LetterChaosJoke, - CursorEffectsJoke, - StupidTitleJoke, + ShakeJoke, + HumanitarianHellJoke, + MirrorJoke, + CarnivalJoke, + CrazyLettersJoke, + LetterChaosJoke, + CursorEffectsJoke, + StupidTitleJoke, ]); -interface JokeClassList extends Array Joke> {} \ No newline at end of file +interface JokeClassList extends Array Joke> {} diff --git a/src/ui.ts b/src/ui.ts index 7d67cdb..db3401c 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -5,58 +5,60 @@ import button_html from "./html/button.html"; import styles_html from "./html/styles.html"; import window_html from "./html/window.html"; - export class JokerUI { - joker: JokerClass; + joker: JokerClass; - constructor(joker: JokerClass) { - this.joker = joker; + constructor(joker: JokerClass) { + this.joker = joker; - $('link[rel="stylesheet"]').eq(0).before(styles_html); + $('link[rel="stylesheet"]').eq(0).before(styles_html); - const button = this.button; + const button = this.button; - button.hide(); - (button).mybbModal({ - title: "Настройки первоапрельских шуток", - content: () => this.render(), - closer: true, - noscroll: true, - escClose: true, - }); + button.hide(); + (button).mybbModal({ + title: "Настройки первоапрельских шуток", + content: () => this.render(), + closer: true, + noscroll: true, + escClose: true, + }); + } + + get button() { + let button = $(".april-fools__button"); + + if (button.length === 0) { + button = $(button_html).appendTo("body"); } - get button() { - let button = $('.april-fools__button'); + return button; + } - if (button.length === 0) { - button = $(button_html).appendTo('body'); - } + show() { + this.button.show(); + } - return button; + render(): JQuery { + const result: JQuery = $("
").html(window_html); + const row_template = $("#april-fools__window-row", result).html(); + const joke_container = $(".april-fools__jokes", result); + + for (const joke of Object.values(this.joker.jokes)) { + const row = $(eval("`" + row_template + "`")); + $('input[type="checkbox"]', row) + .prop("checked", joke.settings.enabled) + .on("click", (e) => + this.joker.toggleJoke(joke.id, (e).currentTarget.checked) + ); + joke_container.append(row); } - show() { - this.button.show(); - } + $("button", result).on("click", async () => { + await this.joker.clearUserStates(); + window.location.reload(); + }); - render(): JQuery { - const result: JQuery = $('
').html(window_html); - const row_template = $('#april-fools__window-row', result).html(); - const joke_container = $('.april-fools__jokes', result); - - for (const joke of Object.values(this.joker.jokes)) { - const row = $(eval('`' + row_template + '`')); - $('input[type="checkbox"]', row).prop('checked', joke.settings.enabled) - .on('click', e => this.joker.toggleJoke(joke.id, (e).currentTarget.checked)); - joke_container.append(row); - } - - $('button', result).on('click', async () => { - await this.joker.clearUserStates(); - window.location.reload(); - }); - - return $('.april-fools__content', result); - } -} \ No newline at end of file + return $(".april-fools__content", result); + } +} diff --git a/tsconfig.json b/tsconfig.json index 27937c3..836bf50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,13 +3,10 @@ "allowSyntheticDefaultImports": true, "noImplicitAny": true, "module": "es6", - "target": "es5", + "target": "es2017", "allowJs": true, "moduleResolution": "node", - "typeRoots": [ - "./node_modules/@types", - "./types" - ] + "typeRoots": ["./node_modules/@types", "./types"] }, "files": ["src/main.ts"] -} \ No newline at end of file +} diff --git a/webpack.config.js b/webpack.config.js index 3a95cfb..7ed4bf5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,8 +2,9 @@ const path = require("path"); const webpack = require("webpack"); -const BomPlugin = require('webpack-utf8-bom'); -const { exec } = require('node:child_process'); +const BomPlugin = require("webpack-utf8-bom"); +const { exec } = require("node:child_process"); +const TerserPlugin = require("terser-webpack-plugin"); const isProduction = process.env.NODE_ENV == "production"; @@ -11,21 +12,21 @@ const config = { entry: "./src/main.ts", output: { path: path.resolve(__dirname, "dist"), - filename: () => ('april-fools' + (isProduction ? '.min' : '') + '.js'), + filename: () => "april-fools" + (isProduction ? ".min" : "") + ".js", }, plugins: [ new BomPlugin(true), { apply: (compiler) => { - compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => { - exec('./upload.sh', (err, stdout, stderr) => { + compiler.hooks.afterEmit.tap("AfterEmitPlugin", (compilation) => { + exec("./upload.sh", (err, stdout, stderr) => { if (stdout) process.stdout.write(stdout); if (stderr) process.stderr.write(stderr); console.log("Uploaded."); }); }); - } - } + }, + }, // Add your plugins here // Learn more about plugins from https://webpack.js.org/configuration/plugins/ ], @@ -52,11 +53,20 @@ const config = { extensions: [".tsx", ".ts", ".jsx", ".js", "..."], }, externals: { - jquery: 'jQuery', + jquery: "jQuery", }, watchOptions: { aggregateTimeout: 20, }, + optimization: { + minimize: isProduction, + minimizer: [new TerserPlugin({ + terserOptions: { + compress: true, + }, + minify: TerserPlugin.uglifyJsMinify, + })], + }, }; module.exports = () => { @@ -82,4 +92,4 @@ module.exports = () => { "src/main.ts" ] } -*/ \ No newline at end of file +*/