From 288cbb3e207dc7ecf95f5db1203a50783a24d775 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 17 Mar 2023 11:09:43 -0400 Subject: [PATCH 01/18] Make error handling for ajax list incrementing more robust --- app/logs/.gitkeep | 0 frontEndSrc/js/anime.js | 58 +- frontEndSrc/js/fns.js | 103 +++ frontEndSrc/js/manga.js | 63 +- frontEndSrc/package.json | 2 +- frontEndSrc/spack.config.js | 19 +- frontEndSrc/yarn.lock | 1612 ++++++++++++++++++++++++---------- public/css/auto.min.css | 2 +- public/css/dark.min.css | 2 +- public/css/light.min.css | 2 +- public/js/scripts.min.js | 39 +- public/js/scripts.min.js.map | 2 +- public/js/tables.min.js | 2 +- public/js/tables.min.js.map | 2 +- 14 files changed, 1375 insertions(+), 533 deletions(-) mode change 100644 => 100755 app/logs/.gitkeep create mode 100644 frontEndSrc/js/fns.js diff --git a/app/logs/.gitkeep b/app/logs/.gitkeep old mode 100644 new mode 100755 diff --git a/frontEndSrc/js/anime.js b/frontEndSrc/js/anime.js index a163ae88..670a78f3 100644 --- a/frontEndSrc/js/anime.js +++ b/frontEndSrc/js/anime.js @@ -1,5 +1,6 @@ import _ from './anime-client.js' import { renderSearchResults } from './template-helpers.js' +import { getNestedProperty, hasNestedProperty } from "./fns"; const search = (query, isCollection = false) => { // Show the loader @@ -70,6 +71,14 @@ _.on('body.anime.list', 'click', '.plus-one', (e) => { } }; + const displayMessage = (type, message) => { + _.hide('#loading-shadow'); + _.showMessage(type, `${message} ${title}.`); + _.scrollToTop(); + } + + const showError = () => displayMessage('error', 'Failed to update'); + // If the episode count is 0, and incremented, // change status to currently watching if (isNaN(watchedCount) || watchedCount === 0) { @@ -89,36 +98,31 @@ _.on('body.anime.list', 'click', '.plus-one', (e) => { dataType: 'json', type: 'POST', success: (res) => { - const resData = JSON.parse(res); + try { + const resData = JSON.parse(res); - if (resData.error) { - _.hide('#loading-shadow'); - _.showMessage('error', `Failed to update ${title}. `); - _.scrollToTop(); + // Do a rough sanity check for weird errors + let updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress'); + if (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) { + showError(); + return; + } - return; + // We've completed the series + if (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') { + _.hide(parentSel); + displayMessage('success', 'Completed') + + return; + } + + // Just a normal update + _.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount; + displayMessage('success', 'Updated'); + } catch (_) { + showError(); } - - // We've completed the series - if (resData.data.libraryEntry.update.libraryEntry.status === 'COMPLETED') { - _.hide(parentSel); - _.hide('#loading-shadow'); - _.showMessage('success', `Successfully completed ${title}`); - _.scrollToTop(); - - return; - } - - _.hide('#loading-shadow'); - - _.showMessage('success', `Successfully updated ${title}`); - _.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount; - _.scrollToTop(); }, - error: () => { - _.hide('#loading-shadow'); - _.showMessage('error', `Failed to update ${title}. `); - _.scrollToTop(); - } + error: showError, }); }); \ No newline at end of file diff --git a/frontEndSrc/js/fns.js b/frontEndSrc/js/fns.js new file mode 100644 index 00000000..54400bd5 --- /dev/null +++ b/frontEndSrc/js/fns.js @@ -0,0 +1,103 @@ +/** + * Make sure properties are in an easily splittable format + * + * @private + * @param {String} props + * @param {String} [sep='.'] The default separator + * @return {String} + */ +function _normalizeProperty(props, sep = '.') { + // Since we split by period, and property lookup + // is the same by dot or [], replace bracket lookups + // with periods + return props.replace(/\[(.*?)]/g, sep + '$1'); +} + +/** + * Tell if a nested object has a given property (or array a given index) + * given an object such as a.b.c.d = 5, hasNestedProperty(a, 'b.c.d') will return true. + * + * @param {Object} object the object to get the property from + * @param {String} property the path to the property as a string + * @returns {boolean} true when property in object, false otherwise + */ +export function hasNestedProperty(object, property) { + if (object && typeof object === 'object') { + if (typeof property === 'string' && property !== '') { + property = _normalizeProperty(property); + + let split = property.split('.'); + return split.reduce((obj, prop, idx, array) => { + if (idx === array.length - 1) { + return !!(obj && obj.hasOwnProperty(prop)); + } + + return obj && obj[prop]; + }, object); + } else if (typeof property === 'number') { + return property in object; + } + } + + return false; +} + +/** + * Get the value of a deeply nested property in an object + * + * @param {Object} object the object to get the property + * @param {string} property the path to the property as a string + * @param {string} [sep='.'] The default separator to split on + * @return {*} the value of the property + */ +export function getNestedProperty(object, property, sep = '.') { + if (isType('string', property) && property !== '') { + // convert numbers to dot syntax + property = _normalizeProperty(property, sep); + const levels = property.split(sep); + + try { + return levels.reduce((obj, prop) => obj[prop], object); + } catch (e) { + return undefined; + } + } + + return null; +} + +/** + * Reliably get the type of the value of a variable + * + * @param {*} x The variable to get the type of + * @return {string} The name of the type + */ +export function getType(x) { + // is it an array? + if (Array.isArray(x)) { + return 'array'; + } + + // Use typeof for truthy primitives + if (typeof x !== 'object') { + return (typeof x).toLowerCase(); + } + + const type = function () { + return Object.prototype.toString.call(this).slice(8, -1); + } + + // Otherwise, strip the type out of the '[Object x]' toString value + return type.call(x).toLowerCase(); +} + +/** + * Check whether the value matches the passed type name + * + * @param {string} type Javascript type name + * @param {*} val The value to type check + * @return {boolean} + */ +export function isType(type, val) { + return getType(val) === String(type).toLowerCase(); +} \ No newline at end of file diff --git a/frontEndSrc/js/manga.js b/frontEndSrc/js/manga.js index b35df7d3..13d2228d 100644 --- a/frontEndSrc/js/manga.js +++ b/frontEndSrc/js/manga.js @@ -1,5 +1,6 @@ import _ from './anime-client.js' import { renderSearchResults } from './template-helpers.js' +import { getNestedProperty, hasNestedProperty } from "./fns"; const search = (query) => { _.show('.cssload-loader'); @@ -36,7 +37,7 @@ _.on('.manga.list', 'click', '.edit-buttons button', (e) => { let type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume'; let completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0; let total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10); - let mangaName = _.$('.name', parentSel)[ 0 ].textContent; + let title = _.$('.name', parentSel)[ 0 ].textContent; if (isNaN(completed)) { completed = 0; @@ -45,12 +46,21 @@ _.on('.manga.list', 'click', '.edit-buttons button', (e) => { // Setup the update data let data = { id: parentSel.dataset.kitsuId, + anilist_id: parentSel.dataset.anilistId, mal_id: parentSel.dataset.malId, data: { progress: completed } }; + const displayMessage = (type, message) => { + _.hide('#loading-shadow'); + _.showMessage(type, `${message} ${title}.`); + _.scrollToTop(); + } + + const showError = () => displayMessage('error', 'Failed to update'); + // If the episode count is 0, and incremented, // change status to currently reading if (isNaN(completed) || completed === 0) { @@ -73,33 +83,32 @@ _.on('.manga.list', 'click', '.edit-buttons button', (e) => { type: 'POST', mimeType: 'application/json', success: (res) => { - const resData = JSON.parse(res) - if (resData.error) { - _.hide('#loading-shadow'); - _.showMessage('error', `Failed to update ${mangaName}. `); - _.scrollToTop(); - return; + try { + const resData = JSON.parse(res); + + // Do a rough sanity check for weird errors + let updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress'); + if (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) { + showError(); + return; + } + + // We've completed the series + if (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') { + _.hide(parentSel); + displayMessage('success', 'Completed') + + return; + } + + // Just a normal update + _.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed); + displayMessage('success', 'Updated'); + + } catch (_) { + showError(); } - - if (String(data.data.status).toUpperCase() === 'COMPLETED') { - _.hide(parentSel); - _.hide('#loading-shadow'); - _.showMessage('success', `Successfully completed ${mangaName}`); - _.scrollToTop(); - - return; - } - - _.hide('#loading-shadow'); - - _.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed); - _.showMessage('success', `Successfully updated ${mangaName}`); - _.scrollToTop(); }, - error: () => { - _.hide('#loading-shadow'); - _.showMessage('error', `Failed to update ${mangaName}`); - _.scrollToTop(); - } + error: showError, }); }); \ No newline at end of file diff --git a/frontEndSrc/package.json b/frontEndSrc/package.json index 45a1ba69..20044146 100644 --- a/frontEndSrc/package.json +++ b/frontEndSrc/package.json @@ -15,7 +15,7 @@ "cssnano": "^5.0.1", "postcss": "^8.2.6", "postcss-import": "^15.0.0", - "postcss-preset-env": "^7.8.2", + "postcss-preset-env": "^8.0.1", "watch": "^1.0.2" } } diff --git a/frontEndSrc/spack.config.js b/frontEndSrc/spack.config.js index 929087bb..2e93e149 100644 --- a/frontEndSrc/spack.config.js +++ b/frontEndSrc/spack.config.js @@ -1,4 +1,6 @@ -module.exports = { +const { config } = require("@swc/core/spack"); + +module.exports = config({ entry: { 'scripts.min': __dirname + '/js/index.js', 'tables.min': __dirname + '/js/base/sort-tables.js', @@ -8,12 +10,15 @@ module.exports = { }, options: { jsc: { - target: 'es3', - loose: true, + parser: { + syntax: "ecmascript", + jsx: false, + }, + target: 'es2016', + loose: false, }, minify: true, - module: { - type: 'es6' - } + sourceMaps: false, + isModule: true, } -} \ No newline at end of file +}); \ No newline at end of file diff --git a/frontEndSrc/yarn.lock b/frontEndSrc/yarn.lock index 1cfbde35..0b4e385b 100644 --- a/frontEndSrc/yarn.lock +++ b/frontEndSrc/yarn.lock @@ -2,111 +2,196 @@ # yarn lockfile v1 -"@csstools/postcss-cascade-layers@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad" - integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== +"@csstools/cascade-layer-name-parser@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.1.tgz#5957adeb71be8159e543d37a9c48e124dcd6c32e" + integrity sha512-SAAi5DpgJJWkfTvWSaqkgyIsTawa83hMwKrktkj6ra2h+q6ZN57vOGZ6ySHq6RSo+CbP64fA3aPChPBRDDUgtw== + +"@csstools/color-helpers@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-1.0.0.tgz#7097722a51da1e9e622345ca000261f1ae6e8f58" + integrity sha512-tgqtiV8sU/VaWYjOB3O7PWs7HR/MmOLl2kTYRW2qSsTSEniJq7xmyAYFB1LPpXvvQcE5u2ih2dK9fyc8BnrAGQ== + +"@csstools/css-calc@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-1.0.0.tgz#f93e4cc9d80b504467aee1b5251bb2fd8be435a7" + integrity sha512-Xw0b/Jr+vLGGYD8cxsGWPaY5n1GtVC6G4tcga+eZPXZzRjjZHorPwW739UgtXzL2Da1RLxNE73c0r/KvmizPsw== + +"@csstools/css-parser-algorithms@^2.0.0", "@csstools/css-parser-algorithms@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.0.1.tgz#ff02629c7c95d1f4f8ea84d5ef1173461610535e" + integrity sha512-B9/8PmOtU6nBiibJg0glnNktQDZ3rZnGn/7UmDfrm2vMtrdlXO3p7ErE95N0up80IRk9YEtB5jyj/TmQ1WH3dw== + +"@csstools/css-tokenizer@^2.0.0", "@csstools/css-tokenizer@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.0.tgz#fee4de3d444db3ce9007f3af6474af8ba3e4b930" + integrity sha512-dtqFyoJBHUxGi9zPZdpCKP1xk8tq6KPHJ/NY4qWXiYo6IcSGwzk3L8x2XzZbbyOyBs9xQARoGveU2AsgLj6D2A== + +"@csstools/media-query-list-parser@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.1.tgz#d85a366811563a5d002755ed10e5212a1613c91d" + integrity sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA== + +"@csstools/postcss-cascade-layers@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-3.0.1.tgz#d839386e90428b448e3f75276bc01d516e852a0d" + integrity sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA== dependencies: "@csstools/selector-specificity" "^2.0.2" postcss-selector-parser "^6.0.10" -"@csstools/postcss-color-function@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz#2bd36ab34f82d0497cfacdc9b18d34b5e6f64b6b" - integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== +"@csstools/postcss-color-function@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-2.1.0.tgz#2ed0320b4f7e0d7718280e273f88ba4164eae7e7" + integrity sha512-XBoCClLyWchlYGHGlmMOa6M2UXZNrZm63HVfsvgD/z1RPm/s3+FhHyT6VkDo+OvEBPhCgn6xz4IeCu4pRctKDQ== dependencies: - "@csstools/postcss-progressive-custom-properties" "^1.1.0" + "@csstools/color-helpers" "^1.0.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-font-format-keywords@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz#677b34e9e88ae997a67283311657973150e8b16a" - integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== +"@csstools/postcss-font-format-keywords@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-2.0.2.tgz#d798d96f4af6cddcfee459f598c976e6011042d2" + integrity sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA== dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-hwb-function@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz#ab54a9fce0ac102c754854769962f2422ae8aa8b" - integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== +"@csstools/postcss-hwb-function@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-2.1.1.tgz#a86efbae9f95236022d6bed83e06357a3bfb4de7" + integrity sha512-XijKzdxBdH2hU6IcPWmnaU85FKEF1XE5hGy0d6dQC6XznFUIRu1T4uebL3krayX40m4xIcxfCBsQm5zphzVrtg== dependencies: + "@csstools/color-helpers" "^1.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-ic-unit@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz#28237d812a124d1a16a5acc5c3832b040b303e58" - integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== +"@csstools/postcss-ic-unit@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-2.0.2.tgz#5a5e481c53977deec3d63793788eec924d4c5f7d" + integrity sha512-N84qGTJkfLTPj2qOG5P4CIqGjpZBbjOEMKMn+UjO5wlb9lcBTfBsxCF0lQsFdWJUzBHYFOz19dL66v71WF3Pig== dependencies: - "@csstools/postcss-progressive-custom-properties" "^1.1.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-is-pseudo-class@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz#846ae6c0d5a1eaa878fce352c544f9c295509cd1" - integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== +"@csstools/postcss-is-pseudo-class@^3.0.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-3.1.1.tgz#81b0f3ba388bf3c8966e1a4413e1839beef7960e" + integrity sha512-hhiacuby4YdUnnxfCYCRMBIobyJImozf0u+gHSbQ/tNOdwvmrZtVROvgW7zmfYuRkHVDNZJWZslq2v5jOU+j/A== dependencies: "@csstools/selector-specificity" "^2.0.0" postcss-selector-parser "^6.0.10" -"@csstools/postcss-nested-calc@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz#d7e9d1d0d3d15cf5ac891b16028af2a1044d0c26" - integrity sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ== - dependencies: - postcss-value-parser "^4.2.0" - -"@csstools/postcss-normalize-display-values@^1.0.1": +"@csstools/postcss-logical-float-and-clear@^1.0.0": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz#15da54a36e867b3ac5163ee12c1d7f82d4d612c3" - integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== - dependencies: - postcss-value-parser "^4.2.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-1.0.1.tgz#d255ea7aad18880930b63d8a04164f56182f2ecf" + integrity sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw== -"@csstools/postcss-oklab-function@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz#88cee0fbc8d6df27079ebd2fa016ee261eecf844" - integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== - dependencies: - "@csstools/postcss-progressive-custom-properties" "^1.1.0" - postcss-value-parser "^4.2.0" - -"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" - integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== - dependencies: - postcss-value-parser "^4.2.0" - -"@csstools/postcss-stepped-value-functions@^1.0.1": +"@csstools/postcss-logical-resize@^1.0.0": version "1.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz#f8772c3681cc2befed695e2b0b1d68e22f08c4f4" - integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-resize/-/postcss-logical-resize-1.0.1.tgz#826d3de929d7d786c32c2c118f78e813a1c2cdec" + integrity sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ== dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-text-decoration-shorthand@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz#ea96cfbc87d921eca914d3ad29340d9bcc4c953f" - integrity sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw== - dependencies: - postcss-value-parser "^4.2.0" - -"@csstools/postcss-trigonometric-functions@^1.0.2": +"@csstools/postcss-logical-viewport-units@^1.0.0": version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz#94d3e4774c36d35dcdc88ce091336cb770d32756" - integrity sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og== + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-1.0.2.tgz#b968c57e1459429b48b24e2c250ca0904d71df6e" + integrity sha512-nnKFywBqRMYjv5jyjSplD/nbAnboUEGFfdxKw1o34Y1nvycgqjQavhKkmxbORxroBBIDwC5y6SfgENcPPUcOxQ== dependencies: - postcss-value-parser "^4.2.0" + "@csstools/css-tokenizer" "^2.0.0" -"@csstools/postcss-unset-value@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz#c99bb70e2cdc7312948d1eb41df2412330b81f77" - integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== +"@csstools/postcss-media-queries-aspect-ratio-number-values@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-1.0.1.tgz#fd6a8e50c2d6d46a5c95b6cdc5563a091fa2f0fa" + integrity sha512-V9yQqXdje6OfqDf6EL5iGOpi6N0OEczwYK83rql9UapQwFEryXlAehR5AqH8QqLYb6+y31wUXK6vMxCp0920Zg== + dependencies: + "@csstools/css-parser-algorithms" "^2.0.0" + "@csstools/css-tokenizer" "^2.0.0" + "@csstools/media-query-list-parser" "^2.0.0" -"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": +"@csstools/postcss-nested-calc@^2.0.0": version "2.0.2" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-2.0.2.tgz#a0857650ef88b1aa7b094c7ea8ea1378c35695e0" + integrity sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-2.0.1.tgz#35dc188c5b4713cf902959fe3c8ce613fcb7543e" + integrity sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-2.1.0.tgz#0f9b914574549e617942a40297ffe76da76809c6" + integrity sha512-U/odSNjOVhagNRu+RDaNVbn8vaqA9GyCOoneQA2je7697KOrtRDc7/POrYsP7QioO2aaezDzKNX02wBzc99fkQ== + dependencies: + "@csstools/color-helpers" "^1.0.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-2.1.0.tgz#df35da0e85a6d5e1d8e4c9a0ba9032e8486e8b9d" + integrity sha512-tRX1rinsXajZlc4WiU7s9Y6O9EdSHScT997zDsvDUjQ1oZL2nvnL6Bt0s9KyQZZTdC3lrG2PIdBqdOIWXSEPlQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-scope-pseudo-class@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-2.0.2.tgz#6325e1e3b321093c59b008ec670bb772e17f06fe" + integrity sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w== + dependencies: + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-stepped-value-functions@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-2.1.0.tgz#8ca134a7f70e00b14f5796fb32ed33a656ba0b1b" + integrity sha512-CkEo9BF8fQeMoXW3biXjlgTLY7PA4UFihn6leq7hPoRzIguLUI0WZIVgsITGXfX8LXmkhCSTjXO2DLYu/LUixQ== + dependencies: + "@csstools/css-calc" "^1.0.0" + "@csstools/css-parser-algorithms" "^2.0.1" + "@csstools/css-tokenizer" "^2.0.1" + +"@csstools/postcss-text-decoration-shorthand@^2.0.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-2.2.1.tgz#1accf54487d74aa7ccade2e674c7290bb2ce10ae" + integrity sha512-Ow6/cWWdjjVvA83mkm3kLRvvWsbzoe1AbJCxkpC+c9ibUjyS8pifm+LpZslQUKcxRVQ69ztKHDBEbFGTDhNeUw== + dependencies: + "@csstools/color-helpers" "^1.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-2.0.1.tgz#2ecede7066187cf08423f8318ef5796cda75351f" + integrity sha512-uGmmVWGHozyWe6+I4w321fKUC034OB1OYW0ZP4ySHA23n+r9y93K+1yrmW+hThpSfApKhaWySoD4I71LLlFUYQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-2.0.1.tgz#67091dd6cff556bff896c95053eb070cc6b21c25" + integrity sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew== + +"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.1", "@csstools/selector-specificity@^2.0.2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz#c9c61d9fe5ca5ac664e1153bb0aa0eba1c6d6308" + integrity sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw== + +"@mole-inc/bin-wrapper@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz#d7fd0ceb1cfa8a855293a3ed9d7d135f4d442f0e" + integrity sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA== + dependencies: + bin-check "^4.1.0" + bin-version-check "^5.0.0" + content-disposition "^0.5.4" + ext-name "^5.0.0" + file-type "^17.1.6" + filenamify "^5.0.2" + got "^11.8.5" + os-filter-obj "^2.0.0" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -129,127 +214,140 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + "@swc/cli@^0.1.39": - version "0.1.57" - resolved "https://registry.yarnpkg.com/@swc/cli/-/cli-0.1.57.tgz#a9c424de5a217ec20a4b7c2c0e5c343980537e83" - integrity sha512-HxM8TqYHhAg+zp7+RdTU69bnkl4MWdt1ygyp6BDIPjTiaJVH6Dizn2ezbgDS8mnFZI1FyhKvxU/bbaUs8XhzQg== + version "0.1.62" + resolved "https://registry.yarnpkg.com/@swc/cli/-/cli-0.1.62.tgz#6442fde2fcf75175a300fb4fcf30f8c60bbb3ab3" + integrity sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw== dependencies: + "@mole-inc/bin-wrapper" "^8.0.1" commander "^7.1.0" fast-glob "^3.2.5" + semver "^7.3.8" slash "3.0.0" source-map "^0.7.3" -"@swc/core-android-arm-eabi@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.3.2.tgz#55f11e0f01d568b832a59d0ff6156c14d5458c7a" - integrity sha512-jCqckwATVC4HbNjjrJii6xZzFKl7ecxVtY94odGD15+7qu5VCMuLD+Pj3bYxIQxQyzvi1z8S/187uUrAKMC2/w== - dependencies: - "@swc/wasm" "1.2.122" +"@swc/core-darwin-arm64@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.41.tgz#c8ec25fb3171e1e53546d0fbf4044c33d5ab42c5" + integrity sha512-D4fybODToO/BvuP35bionDUrSuTVVr8eW+mApr1unOqb3mfiqOrVv0VP2fpWNRYiA+xMq+oBCB6KcGpL60HKWQ== -"@swc/core-android-arm64@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.3.2.tgz#f3165028ec35d73103e1f5a928847356517199ce" - integrity sha512-zZ3EX5jmY6kTBlnAqLmIhDFGlsAB3Tiwk/sqoMLruZT1RsueDToQAXtjT5TWSlPh/GXAZyJQwqar2xIdi5pPAA== - dependencies: - "@swc/wasm" "1.2.130" +"@swc/core-darwin-x64@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.41.tgz#0f9d7077762f4274d50a8ef76a56b76096a8f0ff" + integrity sha512-0RoVyiPCnylf3TG77C3S86PRSmaq+SaYB4VDLJFz3qcEHz1pfP0LhyskhgX4wjQV1mveDzFEn1BVAuo0eOMwZA== -"@swc/core-darwin-arm64@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.2.tgz#ddd4e6daa505d08e6177f111be6a2caa31211d8b" - integrity sha512-YQpbRkd5zhycr+Nl1mm1p7koFqr8hsY8Z7XzNjfNIaJeFsXg9wjjH7yVmedQl+If+ibaPWpS3gMWfcIoUhdvGg== +"@swc/core-linux-arm-gnueabihf@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.41.tgz#5f6a03c4e8cae674b6262fc0d625379af14985be" + integrity sha512-mZW7GeY7Uw1nkKoWpx898ou20oCSt8MR+jAVuAhMjX+G4Zr0WWXYSigWNiRymhR6Q9KhyvoFpMckguSvYWmXsw== -"@swc/core-darwin-x64@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.2.tgz#057515579ccc52717a1c3938dffd0ac6e1ed2caa" - integrity sha512-DMvvdWgi/2dHtSGk4m6OcmlW8AAEUUl7Zys+Sxp+AtyIlQvn0Lbw9HCMPG6pqC0SHEO1kcNj6f6ARt3lL25jSA== +"@swc/core-linux-arm64-gnu@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.41.tgz#e1c0a1669873dbab9ecb9573c2f7dd81b764212e" + integrity sha512-e91LGn+6KuLFw3sWk5swwGc/dP4tXs0mg3HrhjImRoofU02Bb9aHcj5zgrSO8ZByvDtm/Knn16h1ojxIMOFaxg== -"@swc/core-freebsd-x64@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.3.2.tgz#1b80c6adc20a4bebe2a2dfc86acd47647d37dd75" - integrity sha512-GUXqDnmJTWZBoTbOMOKG+mw/jJ7dAOOKuUKwnQvyzconLkqHZZfJTimDsc1KWpikf9IPdQNY0+0/NqAVPGA0Dg== - dependencies: - "@swc/wasm" "1.2.130" +"@swc/core-linux-arm64-musl@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.41.tgz#add780ae831a72a65ec799009d0c0e3e78bb969c" + integrity sha512-Q7hmrniLWsQ7zjtImGcjx1tl5/Qxpel+fC+OXTnGvAyyoGssSftIBlXMnqVLteL78zhxIPAzi+gizWAe5RGqrA== -"@swc/core-linux-arm-gnueabihf@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.2.tgz#7aa675f9daaa35319e95f22bf0d0e145340a338a" - integrity sha512-Df3ln4IhiFxOYBNr/x192tXhRBTVEhJPMLRDl9Q0WY/lvPp/n5Ee0VgKR1CaQ16bg3/z3lZjXrZRBw01kENEew== - dependencies: - "@swc/wasm" "1.2.130" +"@swc/core-linux-x64-gnu@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.41.tgz#5b2bf83493e6fa0a58c3fb1815b9e59b923e300f" + integrity sha512-h4sv1sCfZQgRIwmykz8WPqVpbvHb13Qm3SsrbOudhAp2MuzpWzsgMP5hAEpdCP/nWreiCz3aoM6L8JeakRDq0g== -"@swc/core-linux-arm64-gnu@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.2.tgz#a071167f4268a479c4e75e7a4b50f8dbf7aeaaa8" - integrity sha512-jPtcA61HqWFxlIr5OCToa97kqTS6u4I2GJR5whc8u2rSzn2N+M5CfqskOGHBETcEhUWfFa0hJq3+i6w9lqKV+w== +"@swc/core-linux-x64-musl@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.41.tgz#146547ea3e62466ca971d71ebcc4cfeed3008bda" + integrity sha512-Z7c26i38378d0NT/dcz8qPSAXm41lqhNzykdhKhI+95mA9m4pskP18T/0I45rmyx1ywifypu+Ip+SXmKeVSPgQ== -"@swc/core-linux-arm64-musl@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.2.tgz#3b93f6ada83e09aaec3ca49fa08e13cabbc4a0a8" - integrity sha512-GhGM49GTzpjxKrzi8IpyHNlrJkOwiS6Pk4xhy3D7nrbB5KppU8O+lppkiRjiF9awD+mIzFq27TdokbmEoQcXaQ== +"@swc/core-win32-arm64-msvc@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.41.tgz#91e438c1ca102b52172294905821b43f9d429a32" + integrity sha512-I0CYnPc+ZGc912YeN0TykIOf/Q7yJQHRwDuhewwD6RkbiSEaVfSux5pAmmdoKw2aGMSq+cwLmgPe9HYLRNz+4w== -"@swc/core-linux-x64-gnu@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.2.tgz#704f2e8a15f571dbe765269d7ffb656612eca1b2" - integrity sha512-JgN5rGHAKe2hvtU1H1V9toxSDWKEAWbrrb+/Wp/6CrxBxNgexmgXuDGt0VP21jbRA2qTRNEhx9zzuzZK9ggNTQ== +"@swc/core-win32-ia32-msvc@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.41.tgz#77bdb6ab0ae942039756d41300c47315357bd814" + integrity sha512-EygN4CVDWF29/U2T5fXGfWyLvRbMd2hiUgkciAl7zHuyJ6nKl+kpodqV2A0Wd4sFtSNedU0gQEBEXEe7cqvmsA== -"@swc/core-linux-x64-musl@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.2.tgz#e24868f942fae2931cf1e619e2bfa17194972408" - integrity sha512-VpT6jgU7qqNjQmKt5RaOpkocv9MI5FTxWon4OQvTc+kHCoTAmXIndaW6aA+j4VEDSTJ/7DQAFWSXpSCffoQMsA== - -"@swc/core-win32-arm64-msvc@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.2.tgz#c7ebc460e900f8934f7ae10ec6c9364b0953bba3" - integrity sha512-bilVzxfq5upHsil1WwPSoArZLkhPJyqJJ+5EzbiDS3Y38BPkPYZuN0h6sKuEiXLMHGODXtzuAkSgQyy0VVQKIA== - dependencies: - "@swc/wasm" "1.2.130" - -"@swc/core-win32-ia32-msvc@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.2.tgz#b9e802cec1db078cacae1a913492e8fb61b684f4" - integrity sha512-UzHbZvJnfGZKvoEPiHoKtKehtuiDuNP/mKKBAaG5Cnu8m47z/cE5Mi0onR2iJi1p64GX0RhRIBcGa8x9PVHGjA== - dependencies: - "@swc/wasm" "1.2.130" - -"@swc/core-win32-x64-msvc@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.2.tgz#a6c061a98bf6c70c42ac1fdf27674b085b768285" - integrity sha512-RSFgS2imGONhdN8anvDI+8wL+sinmeKUy2SmSiy8hSmqke1bCslirULCckyGzQAIMf3qCjuaTXxOFiQrsoSoIA== +"@swc/core-win32-x64-msvc@1.3.41": + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.41.tgz#a8d766fc7a68752a3060276a90b7328d9f266631" + integrity sha512-Mfp8qD1hNwWWRy0ISdwQJu1g0UYoVTtuQlO0z3aGbXqL51ew9e56+8j3M1U9i95lXFyWkARgjDCcKkQi+WezyA== "@swc/core@^1.2.54": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.2.tgz#86b1138f9b51e8476f39e2894944fc45585971fc" - integrity sha512-p2nLRVgtaz/v5UkNW9Ur5WrQUKB5YH1X7mE15UD2kihiAMc/04wvo0SNLW0BIeGSqeFdoZQ45TX5uOIxhAvRSg== + version "1.3.41" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.41.tgz#8f10559db269da1a5df9863c92653f8afd0bd7c1" + integrity sha512-v6P2dfqJDpZ/7RXPvWge9oI6YgolDM0jtNhQZ2qdXrLBzaWQdDoBGBTJ8KN/nTgGhX3IkNvSB1fafXQ+nVnqAQ== optionalDependencies: - "@swc/core-android-arm-eabi" "1.3.2" - "@swc/core-android-arm64" "1.3.2" - "@swc/core-darwin-arm64" "1.3.2" - "@swc/core-darwin-x64" "1.3.2" - "@swc/core-freebsd-x64" "1.3.2" - "@swc/core-linux-arm-gnueabihf" "1.3.2" - "@swc/core-linux-arm64-gnu" "1.3.2" - "@swc/core-linux-arm64-musl" "1.3.2" - "@swc/core-linux-x64-gnu" "1.3.2" - "@swc/core-linux-x64-musl" "1.3.2" - "@swc/core-win32-arm64-msvc" "1.3.2" - "@swc/core-win32-ia32-msvc" "1.3.2" - "@swc/core-win32-x64-msvc" "1.3.2" + "@swc/core-darwin-arm64" "1.3.41" + "@swc/core-darwin-x64" "1.3.41" + "@swc/core-linux-arm-gnueabihf" "1.3.41" + "@swc/core-linux-arm64-gnu" "1.3.41" + "@swc/core-linux-arm64-musl" "1.3.41" + "@swc/core-linux-x64-gnu" "1.3.41" + "@swc/core-linux-x64-musl" "1.3.41" + "@swc/core-win32-arm64-msvc" "1.3.41" + "@swc/core-win32-ia32-msvc" "1.3.41" + "@swc/core-win32-x64-msvc" "1.3.41" -"@swc/wasm@1.2.122": - version "1.2.122" - resolved "https://registry.yarnpkg.com/@swc/wasm/-/wasm-1.2.122.tgz#87a5e654b26a71b2e84b801f41e45f823b856639" - integrity sha512-sM1VCWQxmNhFtdxME+8UXNyPNhxNu7zdb6ikWpz0YKAQQFRGT5ThZgJrubEpah335SUToNg8pkdDF7ibVCjxbQ== +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" -"@swc/wasm@1.2.130": - version "1.2.130" - resolved "https://registry.yarnpkg.com/@swc/wasm/-/wasm-1.2.130.tgz#88ac26433335d1f957162a9a92f1450b73c176a0" - integrity sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q== +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "18.15.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" + integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== + +"@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -262,18 +360,48 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -autoprefixer@^10.4.11: - version "10.4.12" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.12.tgz#183f30bf0b0722af54ee5ef257f7d4320bb33129" - integrity sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q== +arch@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +autoprefixer@^10.4.13: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001407" + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" +bin-check@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bin-check/-/bin-check-4.1.0.tgz#fc495970bdc88bb1d5a35fc17e65c4a149fc4a49" + integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== + dependencies: + execa "^0.7.0" + executable "^4.1.0" + +bin-version-check@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-5.0.0.tgz#958de30174d3fcedadbfc52f89f37bca62594877" + integrity sha512-Q3FMQnS5eZmrBGqmDXLs4dbAn/f+52voP6ykJYmweSA60t6DyH4UTSwZhtbK5UH+LBoWvDljILUQMLRUtsynsA== + dependencies: + bin-version "^6.0.0" + semver "^7.3.5" + semver-truncate "^2.0.0" + +bin-version@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-6.0.0.tgz#08ecbe5fc87898b441425e145f9e105064d00315" + integrity sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw== + dependencies: + execa "^5.0.0" + find-versions "^5.0.0" + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -286,15 +414,33 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.0.0, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.0.0, browserslist@^4.21.4, browserslist@^4.21.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" caniuse-api@^3.0.0: version "3.0.0" @@ -306,10 +452,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407: - version "1.0.30001409" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001409.tgz#6135da9dcab34cd9761d9cdb12a68e6740c5e96e" - integrity sha512-V0mnJ5dwarmhYv8/MzhJ//aW68UpvnQBXv8lJ2QUsvn2pHcmAuNtu8hQEDz37XnA1iE+lRR9CIfGWWpgJ5QedQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: + version "1.0.30001467" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001467.tgz#1afc9c16ed61f50dd87139da87ca43a3e0051c77" + integrity sha512-cEdN/5e+RPikvl9AHm4uuLXxeCNq8rFsQ+lPHTfe/OtypP3WwnVVbjn+6uBV7PaFL6xUFzTh+sSCOz1rKhcO+Q== chalk@^4.1.0: version "4.1.2" @@ -319,15 +465,22 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -351,9 +504,9 @@ commander@^7.1.0, commander@^7.2.0: integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== concurrently@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.4.0.tgz#bb0e344964bc172673577c420db21e963f2f7368" - integrity sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA== + version "7.6.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.6.0.tgz#531a6f5f30cf616f355a4afb8f8fcb2bba65a49a" + integrity sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw== dependencies: chalk "^4.1.0" date-fns "^2.29.1" @@ -365,29 +518,56 @@ concurrently@^7.4.0: tree-kill "^1.2.2" yargs "^17.3.1" -css-blank-pseudo@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" - integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== +content-disposition@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - postcss-selector-parser "^6.0.9" + safe-buffer "5.2.1" -css-declaration-sorter@^6.3.0: +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-blank-pseudo@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-5.0.2.tgz#3df5cd950f64de960974da05e76954fd3d7442f9" + integrity sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw== + dependencies: + postcss-selector-parser "^6.0.10" + +css-declaration-sorter@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== -css-has-pseudo@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" - integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== +css-has-pseudo@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-5.0.2.tgz#8798118c705d858b7aeb9d839a39edd901c1cc83" + integrity sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q== dependencies: - postcss-selector-parser "^6.0.9" + "@csstools/selector-specificity" "^2.0.1" + postcss-selector-parser "^6.0.10" + postcss-value-parser "^4.2.0" -css-prefers-color-scheme@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" - integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== +css-prefers-color-scheme@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-8.0.2.tgz#a0671f54eb19ed0d30b952574c0af11ec355fb6d" + integrity sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA== css-select@^4.1.3: version "4.3.0" @@ -413,35 +593,35 @@ css-what@^6.0.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== -cssdb@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.0.1.tgz#3810a0c67ae06362982dfe965dbedf57a0f26617" - integrity sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw== +cssdb@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.4.1.tgz#61d55c0173126689922a219e15e131e4b5caf422" + integrity sha512-0Q8NOMpXJ3iTDDbUv9grcmQAfdDx4qz+fN/+Md2FGbevT+6+bJNQ2LjB2YIUlLbpBTM32idU1Sb+tb/uGt6/XQ== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.2.12: - version "5.2.12" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" - integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== +cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== dependencies: - css-declaration-sorter "^6.3.0" + css-declaration-sorter "^6.3.1" cssnano-utils "^3.1.0" postcss-calc "^8.2.3" - postcss-colormin "^5.3.0" - postcss-convert-values "^5.1.2" + postcss-colormin "^5.3.1" + postcss-convert-values "^5.1.3" postcss-discard-comments "^5.1.2" postcss-discard-duplicates "^5.1.0" postcss-discard-empty "^5.1.1" postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.6" - postcss-merge-rules "^5.1.2" + postcss-merge-longhand "^5.1.7" + postcss-merge-rules "^5.1.4" postcss-minify-font-values "^5.1.0" postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.3" + postcss-minify-params "^5.1.4" postcss-minify-selectors "^5.2.1" postcss-normalize-charset "^5.1.0" postcss-normalize-display-values "^5.1.0" @@ -449,11 +629,11 @@ cssnano-preset-default@^5.2.12: postcss-normalize-repeat-style "^5.1.1" postcss-normalize-string "^5.1.0" postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.0" + postcss-normalize-unicode "^5.1.1" postcss-normalize-url "^5.1.0" postcss-normalize-whitespace "^5.1.1" postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.0" + postcss-reduce-initial "^5.1.2" postcss-reduce-transforms "^5.1.0" postcss-svgo "^5.1.0" postcss-unique-selectors "^5.1.1" @@ -464,11 +644,11 @@ cssnano-utils@^3.1.0: integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== cssnano@^5.0.1: - version "5.1.13" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" - integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== + version "5.1.15" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== dependencies: - cssnano-preset-default "^5.2.12" + cssnano-preset-default "^5.2.14" lilconfig "^2.0.3" yaml "^1.10.2" @@ -484,6 +664,18 @@ date-fns@^2.29.1: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + dom-serializer@^1.0.1: version "1.4.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" @@ -514,16 +706,23 @@ domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" -electron-to-chromium@^1.4.251: - version "1.4.257" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.257.tgz#895dc73c6bb58d1235dc80879ecbca0bcba96e2c" - integrity sha512-C65sIwHqNnPC2ADMfse/jWTtmhZMII+x6ADI9gENzrOiI7BpxmfKFE84WkIEl5wEg+7+SfIkwChDlsd1Erju2A== +electron-to-chromium@^1.4.284: + version "1.4.332" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.332.tgz#b981fcf61587abe03c24b301b2cfbdcc2b70e8a5" + integrity sha512-c1Vbv5tuUlBFp0mb3mCIjw+REEsgthRgNE8BlbEDKmvzb8rxjcVki6OkQP83vLN34s0XCxpSkq7AZNep1a6xhw== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -534,6 +733,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + exec-sh@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" @@ -541,6 +745,56 @@ exec-sh@^0.2.0: dependencies: merge "^1.2.0" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +executable@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + fast-glob@^3.2.5: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" @@ -553,12 +807,35 @@ fast-glob@^3.2.5: micromatch "^4.0.4" fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" +file-type@^17.1.6: + version "17.1.6" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.1.6.tgz#18669e0577a4849ef6e73a41f8bdf1ab5ae21023" + integrity sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw== + dependencies: + readable-web-to-node-stream "^3.0.2" + strtok3 "^7.0.0-alpha.9" + token-types "^5.0.0-alpha.2" + +filename-reserved-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz#3d5dd6d4e2d73a3fed2ebc4cd0b3448869a081f7" + integrity sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw== + +filenamify@^5.0.2: + version "5.1.1" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-5.1.1.tgz#a1ccc5ae678a5e34f578afcb9b72898264d166d2" + integrity sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA== + dependencies: + filename-reserved-regex "^3.0.0" + strip-outer "^2.0.0" + trim-repeated "^2.0.0" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -566,6 +843,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-versions@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-5.1.0.tgz#973f6739ce20f5e439a27eba8542a4b236c8e685" + integrity sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg== + dependencies: + semver-regex "^4.0.5" + fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" @@ -581,6 +865,23 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -588,6 +889,23 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -600,10 +918,38 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== dependencies: has "^1.0.3" @@ -629,10 +975,42 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +keyv@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" + integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== + dependencies: + json-buffer "3.0.1" + lilconfig@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lodash.memoize@^4.1.2: version "4.1.2" @@ -649,11 +1027,36 @@ lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -672,20 +1075,40 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +mime-db@^1.28.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimist@^1.2.0: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== normalize-range@^0.1.2: version "0.1.2" @@ -697,6 +1120,20 @@ normalize-url@^6.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -704,11 +1141,57 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +os-filter-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-filter-obj/-/os-filter-obj-2.0.0.tgz#1c0b62d5f3a2442749a2d139e6dddee6e81d8d16" + integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== + dependencies: + arch "^2.1.0" + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +peek-readable@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec" + integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -719,15 +1202,15 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.3.0: +pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== -postcss-attribute-case-insensitive@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" - integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== +postcss-attribute-case-insensitive@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-6.0.2.tgz#e843091859323342e461878d201ee70278809e01" + integrity sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw== dependencies: postcss-selector-parser "^6.0.10" @@ -746,70 +1229,79 @@ postcss-clamp@^4.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-color-functional-notation@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz#21a909e8d7454d3612d1659e471ce4696f28caec" - integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== +postcss-color-functional-notation@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-5.0.2.tgz#6d03c928aa3a13487703af86c301bdcd501e7430" + integrity sha512-M6ygxWOyd6eWf3sd1Lv8xi4SeF4iBPfJvkfMU4ITh8ExJc1qhbvh/U8Cv/uOvBgUVOMDdScvCdlg8+hREQzs7w== dependencies: postcss-value-parser "^4.2.0" -postcss-color-hex-alpha@^8.0.4: - version "8.0.4" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz#c66e2980f2fbc1a63f5b079663340ce8b55f25a5" - integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== +postcss-color-hex-alpha@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-9.0.2.tgz#6d3ed50342802469880981a1999515d003ff7d79" + integrity sha512-SfPjgr//VQ/DOCf80STIAsdAs7sbIbxATvVmd+Ec7JvR8onz9pjawhq3BJM3Pie40EE3TyB0P6hft16D33Nlyg== dependencies: postcss-value-parser "^4.2.0" -postcss-color-rebeccapurple@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz#63fdab91d878ebc4dd4b7c02619a0c3d6a56ced0" - integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== +postcss-color-rebeccapurple@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-8.0.2.tgz#c0f2dcf1ef4dd393314920aa181cca8c390a2648" + integrity sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw== dependencies: postcss-value-parser "^4.2.0" -postcss-colormin@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== +postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" colord "^2.9.1" postcss-value-parser "^4.2.0" -postcss-convert-values@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" - integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== +postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== dependencies: - browserslist "^4.20.3" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" -postcss-custom-media@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz#c8f9637edf45fef761b014c024cee013f80529ea" - integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== +postcss-custom-media@^9.1.0: + version "9.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-9.1.2.tgz#0e9c34b0b5325edc2c5f42f47543cb64d777764b" + integrity sha512-osM9g4UKq4XKimAC7RAXroqi3BXpxfwTswAJQiZdrBjWGFGEyxQrY5H2eDWI8F+MEvEUfYDxA8scqi3QWROCSw== dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.0" + "@csstools/css-parser-algorithms" "^2.0.0" + "@csstools/css-tokenizer" "^2.0.0" + "@csstools/media-query-list-parser" "^2.0.0" + +postcss-custom-properties@^13.1.0: + version "13.1.4" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-13.1.4.tgz#590e5770137011001602806da51243b6c82c1cde" + integrity sha512-iSAdaZrM3KMec8cOSzeTUNXPYDlhqsMJHpt62yrjwG6nAnMtRHPk5JdMzGosBJtqEahDolvD5LNbcq+EZ78o5g== + dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.0" + "@csstools/css-parser-algorithms" "^2.0.0" + "@csstools/css-tokenizer" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-custom-properties@^12.1.9: - version "12.1.9" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.9.tgz#0883429a7ef99f1ba239d1fea29ce84906daa8bd" - integrity sha512-/E7PRvK8DAVljBbeWrcEQJPG72jaImxF3vvCNFwv9cC8CzigVoNIpeyfnJzphnN3Fd8/auBf5wvkw6W9MfmTyg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-custom-selectors@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz#1ab4684d65f30fed175520f82d223db0337239d9" - integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== +postcss-custom-selectors@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-7.1.2.tgz#e100e9dd628d969a651d7d310cdfd25b27b58d4b" + integrity sha512-jX7VlE3jrgfBIOfxiGNRFq81xUoHSZhvxhQurzE7ZFRv+bUmMwB7/XnA0nNlts2CwNtbXm4Ozy0ZAYKHlCRmBQ== dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.0" + "@csstools/css-parser-algorithms" "^2.0.0" + "@csstools/css-tokenizer" "^2.0.0" postcss-selector-parser "^6.0.4" -postcss-dir-pseudo-class@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz#2bf31de5de76added44e0a25ecf60ae9f7c7c26c" - integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== +postcss-dir-pseudo-class@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-7.0.2.tgz#71618b7eb4abe067845d11b3c8f322760c9b3e88" + integrity sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w== dependencies: postcss-selector-parser "^6.0.10" @@ -833,56 +1325,49 @@ postcss-discard-overridden@^5.1.0: resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== -postcss-double-position-gradients@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz#b96318fdb477be95997e86edd29c6e3557a49b91" - integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== +postcss-double-position-gradients@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-4.0.2.tgz#855a23201f26be447210504e9b668429cbf4640c" + integrity sha512-GXL1RmFREDK4Q9aYvI2RhVrA6a6qqSMQQ5ke8gSH1xgV6exsqbcJpIumC7AOgooH6/WIG3/K/T8xxAiVHy/tJg== dependencies: - "@csstools/postcss-progressive-custom-properties" "^1.1.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-env-function@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" - integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== +postcss-focus-visible@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-8.0.2.tgz#a7ac26ffe3e9c2bd17d7200d75e2d79ee8110891" + integrity sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA== dependencies: - postcss-value-parser "^4.2.0" + postcss-selector-parser "^6.0.10" -postcss-focus-visible@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" - integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== +postcss-focus-within@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-7.0.2.tgz#5d2c866030e66ed22b204c9506de640943310b1c" + integrity sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w== dependencies: - postcss-selector-parser "^6.0.9" - -postcss-focus-within@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" - integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== - dependencies: - postcss-selector-parser "^6.0.9" + postcss-selector-parser "^6.0.10" postcss-font-variant@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== -postcss-gap-properties@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz#f7e3cddcf73ee19e94ccf7cb77773f9560aa2fff" - integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== +postcss-gap-properties@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-4.0.1.tgz#0347d6a84a46bfbe88bedc542cc4b354e04a8338" + integrity sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg== -postcss-image-set-function@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz#08353bd756f1cbfb3b6e93182c7829879114481f" - integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== +postcss-image-set-function@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-5.0.2.tgz#088e0f535f43e74d6ea8033ff7b0482e2735ea6e" + integrity sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg== dependencies: postcss-value-parser "^4.2.0" postcss-import@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.0.0.tgz#0b66c25fdd9c0d19576e63c803cf39e4bad08822" - integrity sha512-Y20shPQ07RitgBGv2zvkEAu9bqvrD77C9axhj/aA1BQj4czape2MdClCExvB27EwYEJdGgKZBpKanb0t1rK2Kg== + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" @@ -893,38 +1378,41 @@ postcss-initial@^4.0.1: resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-lab-function@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz#6fe4c015102ff7cd27d1bd5385582f67ebdbdc98" - integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== +postcss-lab-function@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-5.1.0.tgz#ed3822feb0f7ff229e6d185929583b16861f7753" + integrity sha512-iZApRTNcpc71uTn7PkzjHtj5cmuZpvu6okX4jHnM5OFi2fG97sodjxkq6SpL65xhW0NviQrAMSX97ntyGVRV0w== dependencies: - "@csstools/postcss-progressive-custom-properties" "^1.1.0" + "@csstools/color-helpers" "^1.0.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-logical@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" - integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== +postcss-logical@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-6.1.0.tgz#c33ae75d3edaea7eb821e76dc4e6d0ecedc3200d" + integrity sha512-qb1+LpClhYjxac8SfOcWotnY3unKZesDqIOm+jnGt8rTl7xaIWpE2bPGZHxflOip1E/4ETo79qlJyRL3yrHn1g== + dependencies: + postcss-value-parser "^4.2.0" postcss-media-minmax@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== -postcss-merge-longhand@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" - integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== +postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^5.1.0" + stylehacks "^5.1.1" -postcss-merge-rules@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" - integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== +postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" cssnano-utils "^3.1.0" postcss-selector-parser "^6.0.5" @@ -945,12 +1433,12 @@ postcss-minify-gradients@^5.1.1: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" -postcss-minify-params@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" - integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== +postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" @@ -961,10 +1449,10 @@ postcss-minify-selectors@^5.2.1: dependencies: postcss-selector-parser "^6.0.5" -postcss-nesting@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be" - integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== +postcss-nesting@^11.0.0: + version "11.2.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-11.2.1.tgz#260806f20971c82700d327468b49d1c1b44f1790" + integrity sha512-E6Jq74Jo/PbRAtZioON54NPhUNJYxVWhwxbweYl1vAoBYuGlDIts5yhtKiZFLvkvwT73e/9nFrW3oMqAtgG+GQ== dependencies: "@csstools/selector-specificity" "^2.0.0" postcss-selector-parser "^6.0.10" @@ -1009,12 +1497,12 @@ postcss-normalize-timing-functions@^5.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" - integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== +postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" postcss-normalize-url@^5.1.0: @@ -1032,10 +1520,10 @@ postcss-normalize-whitespace@^5.1.1: dependencies: postcss-value-parser "^4.2.0" -postcss-opacity-percentage@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" - integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== +postcss-opacity-percentage@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz#5b89b35551a556e20c5d23eb5260fbfcf5245da6" + integrity sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A== postcss-ordered-values@^5.1.3: version "5.1.3" @@ -1045,10 +1533,10 @@ postcss-ordered-values@^5.1.3: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" -postcss-overflow-shorthand@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz#7ed6486fec44b76f0eab15aa4866cda5d55d893e" - integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== +postcss-overflow-shorthand@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-4.0.1.tgz#cb61ca24d8c4e1dbf14d85181b017cfa6953aa34" + integrity sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg== dependencies: postcss-value-parser "^4.2.0" @@ -1057,81 +1545,85 @@ postcss-page-break@^3.0.4: resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== -postcss-place@^7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.5.tgz#95dbf85fd9656a3a6e60e832b5809914236986c4" - integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== +postcss-place@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-8.0.1.tgz#408d7a27e99192df51c95fe62a3a34def62aa66a" + integrity sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw== dependencies: postcss-value-parser "^4.2.0" -postcss-preset-env@^7.8.2: - version "7.8.2" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz#4c834d5cbd2e29df2abf59118947c456922b79ba" - integrity sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ== +postcss-preset-env@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-8.0.1.tgz#d249c137febc037dd5dbb97e18f94dba4dd0cda8" + integrity sha512-IUbymw0JlUbyVG+I85963PNWgPp3KhnFa1sxU7M/2dGthxV8e297P0VV5W9XcyypoH4hirH2fp1c6fmqh6YnSg== dependencies: - "@csstools/postcss-cascade-layers" "^1.1.0" - "@csstools/postcss-color-function" "^1.1.1" - "@csstools/postcss-font-format-keywords" "^1.0.1" - "@csstools/postcss-hwb-function" "^1.0.2" - "@csstools/postcss-ic-unit" "^1.0.1" - "@csstools/postcss-is-pseudo-class" "^2.0.7" - "@csstools/postcss-nested-calc" "^1.0.0" - "@csstools/postcss-normalize-display-values" "^1.0.1" - "@csstools/postcss-oklab-function" "^1.1.1" - "@csstools/postcss-progressive-custom-properties" "^1.3.0" - "@csstools/postcss-stepped-value-functions" "^1.0.1" - "@csstools/postcss-text-decoration-shorthand" "^1.0.0" - "@csstools/postcss-trigonometric-functions" "^1.0.2" - "@csstools/postcss-unset-value" "^1.0.2" - autoprefixer "^10.4.11" - browserslist "^4.21.3" - css-blank-pseudo "^3.0.3" - css-has-pseudo "^3.0.4" - css-prefers-color-scheme "^6.0.3" - cssdb "^7.0.1" - postcss-attribute-case-insensitive "^5.0.2" + "@csstools/postcss-cascade-layers" "^3.0.0" + "@csstools/postcss-color-function" "^2.0.0" + "@csstools/postcss-font-format-keywords" "^2.0.0" + "@csstools/postcss-hwb-function" "^2.0.0" + "@csstools/postcss-ic-unit" "^2.0.0" + "@csstools/postcss-is-pseudo-class" "^3.0.0" + "@csstools/postcss-logical-float-and-clear" "^1.0.0" + "@csstools/postcss-logical-resize" "^1.0.0" + "@csstools/postcss-logical-viewport-units" "^1.0.0" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^1.0.0" + "@csstools/postcss-nested-calc" "^2.0.0" + "@csstools/postcss-normalize-display-values" "^2.0.0" + "@csstools/postcss-oklab-function" "^2.0.0" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + "@csstools/postcss-scope-pseudo-class" "^2.0.0" + "@csstools/postcss-stepped-value-functions" "^2.0.0" + "@csstools/postcss-text-decoration-shorthand" "^2.0.0" + "@csstools/postcss-trigonometric-functions" "^2.0.0" + "@csstools/postcss-unset-value" "^2.0.0" + autoprefixer "^10.4.13" + browserslist "^4.21.4" + css-blank-pseudo "^5.0.0" + css-has-pseudo "^5.0.0" + css-prefers-color-scheme "^8.0.0" + cssdb "^7.4.0" + postcss-attribute-case-insensitive "^6.0.0" postcss-clamp "^4.1.0" - postcss-color-functional-notation "^4.2.4" - postcss-color-hex-alpha "^8.0.4" - postcss-color-rebeccapurple "^7.1.1" - postcss-custom-media "^8.0.2" - postcss-custom-properties "^12.1.9" - postcss-custom-selectors "^6.0.3" - postcss-dir-pseudo-class "^6.0.5" - postcss-double-position-gradients "^3.1.2" - postcss-env-function "^4.0.6" - postcss-focus-visible "^6.0.4" - postcss-focus-within "^5.0.4" + postcss-color-functional-notation "^5.0.0" + postcss-color-hex-alpha "^9.0.0" + postcss-color-rebeccapurple "^8.0.0" + postcss-custom-media "^9.1.0" + postcss-custom-properties "^13.1.0" + postcss-custom-selectors "^7.1.0" + postcss-dir-pseudo-class "^7.0.0" + postcss-double-position-gradients "^4.0.0" + postcss-focus-visible "^8.0.0" + postcss-focus-within "^7.0.0" postcss-font-variant "^5.0.0" - postcss-gap-properties "^3.0.5" - postcss-image-set-function "^4.0.7" + postcss-gap-properties "^4.0.0" + postcss-image-set-function "^5.0.0" postcss-initial "^4.0.1" - postcss-lab-function "^4.2.1" - postcss-logical "^5.0.4" + postcss-lab-function "^5.0.0" + postcss-logical "^6.0.0" postcss-media-minmax "^5.0.0" - postcss-nesting "^10.2.0" - postcss-opacity-percentage "^1.1.2" - postcss-overflow-shorthand "^3.0.4" + postcss-nesting "^11.0.0" + postcss-opacity-percentage "^1.1.3" + postcss-overflow-shorthand "^4.0.0" postcss-page-break "^3.0.4" - postcss-place "^7.0.5" - postcss-pseudo-class-any-link "^7.1.6" + postcss-place "^8.0.0" + postcss-pseudo-class-any-link "^8.0.0" postcss-replace-overflow-wrap "^4.0.0" - postcss-selector-not "^6.0.1" + postcss-selector-not "^7.0.0" postcss-value-parser "^4.2.0" -postcss-pseudo-class-any-link@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz#2693b221902da772c278def85a4d9a64b6e617ab" - integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== +postcss-pseudo-class-any-link@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-8.0.2.tgz#f5738503f2045de0c4dc216eca99bd835f74e42e" + integrity sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA== dependencies: postcss-selector-parser "^6.0.10" -postcss-reduce-initial@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" - integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== +postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" postcss-reduce-transforms@^5.1.0: @@ -1146,17 +1638,17 @@ postcss-replace-overflow-wrap@^4.0.0: resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== -postcss-selector-not@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz#8f0a709bf7d4b45222793fc34409be407537556d" - integrity sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ== +postcss-selector-not@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-7.0.1.tgz#8142e90c8eb6c8c5faecb3e9d96d4353d02e94fb" + integrity sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ== dependencies: postcss-selector-parser "^6.0.10" postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + version "6.0.11" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" + integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -1182,19 +1674,37 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.2.6: - version "8.4.16" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" - integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== + version "8.4.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" + integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" source-map-js "^1.0.2" +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + read-cache@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" @@ -1202,11 +1712,32 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve@^1.1.7: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -1216,6 +1747,13 @@ resolve@^1.1.7: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -1229,22 +1767,94 @@ run-parallel@^1.1.9: queue-microtask "^1.2.2" rxjs@^7.0.0: - version "7.5.6" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" - integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== + version "7.8.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" + integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== dependencies: tslib "^2.1.0" +safe-buffer@5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver-regex@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-4.0.5.tgz#fbfa36c7ba70461311f5debcb3928821eb4f9180" + integrity sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw== + +semver-truncate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-2.0.0.tgz#cce4c0af36dbd97e898b821be870d17fbfb67f56" + integrity sha512-Rh266MLDYNeML5h90ttdMwfXe1+Nc4LAWd9X1KdJe8pPHP4kFmvLZALtsMNHNdvTyQygbEC0D59sIz47DIaq8w== + dependencies: + semver "^6.0.0" + +semver@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.5, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shell-quote@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" + integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== + +signal-exit@^3.0.0, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== slash@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -1279,6 +1889,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -1286,12 +1903,35 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-outer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-2.0.0.tgz#c45c724ed9b1ff6be5f660503791404f4714084b" + integrity sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg== + +strtok3@^7.0.0-alpha.9: + version "7.0.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5" + integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== dependencies: - browserslist "^4.16.6" + "@tokenizer/token" "^0.3.0" + peek-readable "^5.0.0" + +stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== + dependencies: + browserslist "^4.21.4" postcss-selector-parser "^6.0.4" supports-color@^7.1.0: @@ -1333,25 +1973,40 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +token-types@^5.0.0-alpha.2: + version "5.0.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4" + integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -tslib@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +trim-repeated@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-2.0.0.tgz#5d60556d6d40d9461b7c7e06c3ac20b6b1d50090" + integrity sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg== + dependencies: + escape-string-regexp "^5.0.0" -update-browserslist-db@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" - integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== +tslib@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + +update-browserslist-db@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== dependencies: escalade "^3.1.1" picocolors "^1.0.0" -util-deprecate@^1.0.2: +util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -1364,6 +2019,20 @@ watch@^1.0.2: exec-sh "^0.2.0" minimist "^1.2.0" +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -1373,30 +2042,45 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^21.0.0: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.7.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" + integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" diff --git a/public/css/auto.min.css b/public/css/auto.min.css index 5e77357c..98c04f2f 100644 --- a/public/css/auto.min.css +++ b/public/css/auto.min.css @@ -1 +1 @@ -:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}} @media (prefers-color-scheme: dark) { a{color:#1978e2;text-shadow:var(--link-shadow)}a:hover{color:#9e34fd}body,legend,nav ul li a{background:#333;color:#eee}nav a:hover,nav li.selected a{border-color:#fff}header button{background:transparent}table{box-shadow:none}td,th{border-color:#111}thead td,thead th{background:#333;color:#eee}tbody>tr:nth-child(2n){background:#555;color:#eee}tbody>tr:nth-child(odd){background:#333}footer,hr,legend{border-color:#ddd}small{color:#fff}input,input[type],select,textarea{background:#333;border-color:#bbb;color:#bbb;padding:.8em}button{background:#444;background:linear-gradient(#666,#555,#444,#555,#666);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#ddd;color:#ddd}button:hover{background:#222;background:linear-gradient(#444,#333,#222,#333,#444)}button:active{background:#333;background:linear-gradient(#333,#333)}.media:hover button{background:linear-gradient(#666,#555,#444,#555,#666)}.media:hover button:hover{background:linear-gradient(#444,#555,#666,#555,#444)}.message,.static-message{text-shadow:var(--white-link-shadow)}.message.success,.static-message.success{background:#1f8454;border-color:#70dda9}.message.error,.static-message.error{background:#924949;border-color:#f3e6e6}.message.info,.static-message.info{background:#bfbe3a;border-color:#ffc}.invisible tbody>tr:nth-child(2n),.invisible tbody>tr:nth-child(odd),.invisible td,.invisible th,.invisible tr{background:transparent}#main-nav{border-bottom:.1rem solid #ddd}.tabs,.vertical-tabs{background:#333}.tabs>label,.vertical-tabs .tab label{background:#222;border:0;color:#eee}.vertical-tabs .tab label{width:100%}.tabs>label:hover,.vertical-tabs .tab>label:hover{background:#888}.tabs>label:active,.vertical-tabs .tab>label:active{background:#999}.single-tab,.tabs>[type=radio]:checked+label,.tabs>[type=radio]:checked+label+.content,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:checked~.content{background:#666;border:0;color:#eee}.vertical-tabs{background:#222;border:1px solid #444}.vertical-tabs .tab{background:#666;border-bottom:1px solid #444}.streaming-logo{filter:drop-shadow(0 0 2px #fff)} } \ No newline at end of file +:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{-webkit-text-decoration:none;text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;-webkit-text-decoration:none;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}} @media (prefers-color-scheme: dark) { a{color:#1978e2;text-shadow:var(--link-shadow)}a:hover{color:#9e34fd}body,legend,nav ul li a{background:#333;color:#eee}nav a:hover,nav li.selected a{border-color:#fff}header button{background:transparent}table{box-shadow:none}td,th{border-color:#111}thead td,thead th{background:#333;color:#eee}tbody>tr:nth-child(2n){background:#555;color:#eee}tbody>tr:nth-child(odd){background:#333}footer,hr,legend{border-color:#ddd}small{color:#fff}input,input[type],select,textarea{background:#333;border-color:#bbb;color:#bbb;padding:.8em}button{background:#444;background:linear-gradient(#666,#555,#444,#555,#666);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#ddd;color:#ddd}button:hover{background:#222;background:linear-gradient(#444,#333,#222,#333,#444)}button:active{background:#333;background:linear-gradient(#333,#333)}.media:hover button{background:linear-gradient(#666,#555,#444,#555,#666)}.media:hover button:hover{background:linear-gradient(#444,#555,#666,#555,#444)}.message,.static-message{text-shadow:var(--white-link-shadow)}.message.success,.static-message.success{background:#1f8454;border-color:#70dda9}.message.error,.static-message.error{background:#924949;border-color:#f3e6e6}.message.info,.static-message.info{background:#bfbe3a;border-color:#ffc}.invisible tbody>tr:nth-child(2n),.invisible tbody>tr:nth-child(odd),.invisible td,.invisible th,.invisible tr{background:transparent}#main-nav{border-bottom:.1rem solid #ddd}.tabs,.vertical-tabs{background:#333}.tabs>label,.vertical-tabs .tab label{background:#222;border:0;color:#eee}.vertical-tabs .tab label{width:100%}.tabs>label:hover,.vertical-tabs .tab>label:hover{background:#888}.tabs>label:active,.vertical-tabs .tab>label:active{background:#999}.single-tab,.tabs>[type=radio]:checked+label,.tabs>[type=radio]:checked+label+.content,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:checked~.content{background:#666;border:0;color:#eee}.vertical-tabs{background:#222;border:1px solid #444}.vertical-tabs .tab{background:#666;border-bottom:1px solid #444}.streaming-logo{filter:drop-shadow(0 0 2px #fff)} } \ No newline at end of file diff --git a/public/css/dark.min.css b/public/css/dark.min.css index 5493c3b4..2e0a38df 100644 --- a/public/css/dark.min.css +++ b/public/css/dark.min.css @@ -1 +1 @@ -:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd)}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}}a{color:#1978e2;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}a:hover{color:#9e34fd}body,legend,nav ul li a{background:#333;color:#eee}nav a:hover,nav li.selected a{border-color:#fff}header button{background:transparent}table{box-shadow:none}td,th{border-color:#111}thead td,thead th{background:#333;color:#eee}tbody>tr:nth-child(2n){background:#555;color:#eee}tbody>tr:nth-child(odd){background:#333}footer,hr,legend{border-color:#ddd}small{color:#fff}input,input[type],select,textarea{background:#333;border-color:#bbb;color:#bbb;padding:.8em}button{background:#444;background:linear-gradient(#666,#555,#444,#555,#666);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#ddd;color:#ddd}button:hover{background:#222;background:linear-gradient(#444,#333,#222,#333,#444)}button:active{background:#333;background:linear-gradient(#333,#333)}.media:hover button{background:linear-gradient(#666,#555,#444,#555,#666)}.media:hover button:hover{background:linear-gradient(#444,#555,#666,#555,#444)}.message,.static-message{text-shadow:1px 1px 1px #fff;text-shadow:var(--white-link-shadow)}.message.success,.static-message.success{background:#1f8454;border-color:#70dda9}.message.error,.static-message.error{background:#924949;border-color:#f3e6e6}.message.info,.static-message.info{background:#bfbe3a;border-color:#ffc}.invisible tbody>tr:nth-child(2n),.invisible tbody>tr:nth-child(odd),.invisible td,.invisible th,.invisible tr{background:transparent}#main-nav{border-bottom:.1rem solid #ddd}.tabs,.vertical-tabs{background:#333}.tabs>label,.vertical-tabs .tab label{background:#222;border:0;color:#eee}.vertical-tabs .tab label{width:100%}.tabs>label:hover,.vertical-tabs .tab>label:hover{background:#888}.tabs>label:active,.vertical-tabs .tab>label:active{background:#999}.single-tab,.tabs>[type=radio]:checked+label,.tabs>[type=radio]:checked+label+.content,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:checked~.content{background:#666;border:0;color:#eee}.vertical-tabs{background:#222;border:1px solid #444}.vertical-tabs .tab{background:#666;border-bottom:1px solid #444}.streaming-logo{filter:drop-shadow(0 0 2px #fff)} \ No newline at end of file +:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{-webkit-text-decoration:none;text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;-webkit-text-decoration:none;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd)}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}}a{color:#1978e2;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}a:hover{color:#9e34fd}body,legend,nav ul li a{background:#333;color:#eee}nav a:hover,nav li.selected a{border-color:#fff}header button{background:transparent}table{box-shadow:none}td,th{border-color:#111}thead td,thead th{background:#333;color:#eee}tbody>tr:nth-child(2n){background:#555;color:#eee}tbody>tr:nth-child(odd){background:#333}footer,hr,legend{border-color:#ddd}small{color:#fff}input,input[type],select,textarea{background:#333;border-color:#bbb;color:#bbb;padding:.8em}button{background:#444;background:linear-gradient(#666,#555,#444,#555,#666);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#ddd;color:#ddd}button:hover{background:#222;background:linear-gradient(#444,#333,#222,#333,#444)}button:active{background:#333;background:linear-gradient(#333,#333)}.media:hover button{background:linear-gradient(#666,#555,#444,#555,#666)}.media:hover button:hover{background:linear-gradient(#444,#555,#666,#555,#444)}.message,.static-message{text-shadow:1px 1px 1px #fff;text-shadow:var(--white-link-shadow)}.message.success,.static-message.success{background:#1f8454;border-color:#70dda9}.message.error,.static-message.error{background:#924949;border-color:#f3e6e6}.message.info,.static-message.info{background:#bfbe3a;border-color:#ffc}.invisible tbody>tr:nth-child(2n),.invisible tbody>tr:nth-child(odd),.invisible td,.invisible th,.invisible tr{background:transparent}#main-nav{border-bottom:.1rem solid #ddd}.tabs,.vertical-tabs{background:#333}.tabs>label,.vertical-tabs .tab label{background:#222;border:0;color:#eee}.vertical-tabs .tab label{width:100%}.tabs>label:hover,.vertical-tabs .tab>label:hover{background:#888}.tabs>label:active,.vertical-tabs .tab>label:active{background:#999}.single-tab,.tabs>[type=radio]:checked+label,.tabs>[type=radio]:checked+label+.content,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:checked~.content{background:#666;border:0;color:#eee}.vertical-tabs{background:#222;border:1px solid #444}.vertical-tabs .tab{background:#666;border-bottom:1px solid #444}.streaming-logo{filter:drop-shadow(0 0 2px #fff)} \ No newline at end of file diff --git a/public/css/light.min.css b/public/css/light.min.css index d8329115..804183cf 100644 --- a/public/css/light.min.css +++ b/public/css/light.min.css @@ -1 +1 @@ -:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}} \ No newline at end of file +:root{--default-font-list:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--monospace-font-list:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;--serif-font-list:Georgia,Times,"Times New Roman",serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);line-height:1.4;overflow-y:scroll;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);font-size:1.4em;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{color:#1271db;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}input,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list)}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:3rem}h3{font-size:2.4em;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:1.4rem}code{word-wrap:break-word;background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-family:var(--monospace-font-list);word-break:break-all}a:focus,a:hover{-webkit-text-decoration:none;text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif;font-family:var(--serif-font-list)}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-webkit-user-drag:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;-webkit-text-decoration:none;text-decoration:none;text-transform:uppercase;-webkit-transition:.25s ease;transition:.25s ease;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:.25s ease;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}:root{--blue-link:#1271db;--link-shadow:1px 1px 1px #000;--white-link-shadow:1px 1px 1px #fff;--shadow:2px 2px 2px #000;--title-overlay:rgba(0,0,0,.45);--title-overlay-fallback:#000;--text-color:#fff;--normal-padding:0.25em 0.125em;--link-hover-color:#7d12db;--edit-link-hover-color:#db7d12;--edit-link-color:#12db18;--radius:5px}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:#fff;background:linear-gradient(#ddd,#eee,#fff,#eee,#ddd);border-radius:.5em;margin:0;text-transform:none}button,button:hover{border-color:#555;color:#555}button:hover{background:#bbb;background:linear-gradient(#cfcfcf,#dfdfdf,#efefef,#dfdfdf,#cfcfcf)}button:active{background:#ddd;background:linear-gradient(#ddd,#ddd)}.media:hover button{background:linear-gradient(#bbb,#ccc,#ddd,#ccc,#bbb)}.media:hover button:hover{background:linear-gradient(#afafaf,#bfbfbf,#cfcfcf,#bfbfbf,#afafaf)}table{box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{min-width:0;width:4.5em}input[type=checkbox],input[type=radio]{min-width:auto;vertical-align:inherit}input,textarea{min-width:30em;min-width:30rem}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db;color:var(--link-hover-color)}iframe{border:0;display:block;margin:0 auto}.bracketed{color:#12db18;color:var(--edit-link-color)}#main-nav a,.bracketed{text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12;color:var(--edit-link-hover-color)}.grow-1{flex-grow:1}.flex-wrap{flex-wrap:wrap}.flex-no-wrap{flex-wrap:nowrap}.flex-align-start{align-content:flex-start}.flex-align-end{align-items:flex-end}.flex-align-space-around{align-content:space-around}.flex-justify-start{justify-content:flex-start}.flex-justify-space-around{justify-content:space-around}.flex-center{justify-content:center}.flex-self-center{align-self:center}.flex-space-evenly{justify-content:space-evenly}.flex{display:inline-block;display:flex}.small-font{font-size:1.6rem}.justify{text-align:justify}.align-center{text-align:center!important}.align-left{text-align:left!important}.align-right{text-align:right!important}.valign-top{vertical-align:top}.no-border{border:none}.media-wrap{margin:0 auto;position:relative;text-align:center}.media-wrap-flex{align-content:space-evenly;display:inline-block;display:flex;flex-wrap:wrap;justify-content:space-between;position:relative}td .media-wrap-flex{justify-content:center}.danger{background-color:#ff4136;border-color:#924949;color:#924949}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#ff4136}td.danger,td.danger:active,td.danger:hover{background-color:transparent;color:#924949}.user-btn{background:transparent;border-color:#12db18;border-color:var(--edit-link-color);color:#12db18;color:var(--edit-link-color);padding:0 .5rem;text-shadow:1px 1px 1px #000;text-shadow:var(--link-shadow)}.user-btn:active,.user-btn:hover{background:transparent;border-color:#db7d12;border-color:var(--edit-link-hover-color);color:#db7d12;color:var(--edit-link-hover-color)}.user-btn:active{background:#db7d12;background:var(--edit-link-hover-color);color:#fff}.full-width{width:100%}.full-height{max-height:none}.toph{margin-top:0}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;font-family:var(--default-font-list);font-size:3.6em;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.sorting,.sorting-asc,.sorting-desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting-asc:before{content:" ↑\00a0"}.sorting-desc:before{content:" ↓\00a0"}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left}.invisible tbody>tr:nth-child(odd){background:inherit}.borderless,.borderless td,.borderless th,.borderless tr,.invisible td,.invisible th,.invisible tr{border:0;box-shadow:none}.message,.static-message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small-character{background:rgba(0,0,0,.15);display:inline-block;height:312px;margin:.25em .125em;margin:var(--normal-padding);position:relative;text-align:center;vertical-align:top;width:220px;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small-character>img{width:100%}.media .edit-buttons>button{margin:.5em auto}.media-metadata>div,.medium-metadata>div,.name,.row{color:#fff;color:var(--text-color);padding:.25em .125em;padding:var(--normal-padding);text-align:right;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow);z-index:2}.age-rating,.media-type{text-align:left}.media>.media-metadata{bottom:0;position:absolute;right:0}.media>.medium-metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.media>.name a{display:inline-block;transition:none}.media .name a:before{content:"";display:block;height:312px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db;color:var(--blue-link)}.media:hover>.edit-buttons[hidden],.media:hover>button[hidden]{display:block;transition:.25s ease}.media:hover{transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small-character>.name a,.small-character>.name a small{background:none;color:#fff;text-shadow:2px 2px 2px #000;text-shadow:var(--shadow)}.anime .name,.manga .name{background:#000;background:var(--title-overlay-fallback);background:rgba(0,0,0,.45);background:var(--title-overlay);padding:.5em .25em;text-align:center;width:100%}.anime .age-rating,.anime .airing-status,.anime .completion,.anime .delete,.anime .edit,.anime .media-type,.anime .user-rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{align-content:space-around;display:inline-block;display:flex;justify-content:space-around;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left;z-index:2}.anime .row>div,.manga .row>div{align-self:center;display:inline-block;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle;z-index:2}.anime .media>button.plus-one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 57.8px);position:absolute;top:138px;top:calc(50% - 21.2px);z-index:50}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit-buttons{left:43.5px;left:calc(50% - 57.8px);position:absolute;top:86px;top:calc(50% - 21.2px);z-index:40}.manga .media>.edit-buttons button{border-color:hsla(0,0%,100%,.65)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35)}.media.search.disabled .name,.media.search>.name{background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search.disabled .name{background-color:#000;background-color:rgba(0,0,0,.75)}.media.search>.row{z-index:6}.big-check,.mal-check{display:none}.big-check:checked+label{background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:15rem;left:0;position:absolute;text-align:center;top:147px;width:100%;z-index:5}#series-list article.media{position:relative}#series-list .name,#series-list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series-list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.fixed{margin:0 auto;max-width:115em;max-width:115rem}.details .cover{display:block}.details .flex>*{margin:1rem}.details .media-details td{padding:0 1.5rem}.details p{text-align:justify}.details .media-details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media-details td:nth-child(2n){text-align:left}.details a h1,.details a h2{margin-top:0}.character,.person,.small-character{height:350px;position:relative;vertical-align:middle;white-space:nowrap;width:225px}.person{height:338px;width:225px}.small-person{height:300px;width:200px}.character a{height:350px}.character:hover .name,.small-character:hover .name{background:rgba(0,0,0,.8)}.small-character a{display:inline-block;height:100%;width:100%}.character .name,.small-character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.character picture,.person img,.person picture,.small-character img,.small-character picture{left:50%;max-height:350px;max-width:225px;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:5}.person img,.person picture{max-height:338px}.small-person img,.small-person picture{max-height:300px;max-width:200px}.min-table{margin-left:0;min-width:0}.max-table{margin:0;min-width:100%}aside.info{max-width:33%}.fixed aside{max-width:390px}aside img,aside picture{display:block;margin:0 auto}.small-character{height:250px;width:160px}.small-character img,.small-character picture{max-height:250px;max-width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}.streaming-logo{height:50px;vertical-align:middle;width:50px}.small-streaming-logo{height:25px;vertical-align:middle;width:25px}.cover-streaming-link{display:none}.media:hover .cover-streaming-link{display:block}.cover-streaming-link .streaming-logo{filter:drop-shadow(0 -1px 4px #fff);height:20px;width:20px}.history-img{height:156px;width:110px}.settings.form .content article{display:inline-block;margin:1em;width:auto}.responsive-iframe{height:0;margin-top:1em;overflow:hidden;padding-bottom:56.25%;position:relative}.responsive-iframe iframe{height:100%;left:0;position:absolute;top:0;width:100%}.cssload-loader{border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@keyframes cssload-rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{align-items:center;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:inline-block;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs>label{background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs>label:hover{background:#d8d8d8}.tabs>label:active{background:#ccc}.tabs>[type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs>[type=radio]{opacity:0;position:absolute}.tabs>[type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs>[type=radio]:checked+label+.content{display:block}.single-tab,.tabs .content,.tabs>[type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;margin:0 auto;overflow:auto;padding:15px;width:100%}.single-tab,.tabs .content{display:none;max-height:950px}.single-tab{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:block;margin-top:1.5em}.single-tab.full-height,.tabs .content.full-height{max-height:none}@media (min-width:800px){.tabs>label{width:auto}.tabs .content{order:99}}.vertical-tabs{border:1px solid #e5e5e5;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);margin:0 auto;position:relative;width:100%}.vertical-tabs input[type=radio]{opacity:0;position:absolute}.vertical-tabs .tab{align-items:center;display:inline-block;display:flex;flex-wrap:nowrap}.vertical-tabs .tab label{align-items:center;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:0 20px;width:28%}.vertical-tabs .tab label:hover{background:#d8d8d8}.vertical-tabs .tab label:active{background:#ccc}.vertical-tabs .tab .content{border:1px solid #e5e5e5;border-left:0;border-right:0;display:none;max-height:950px;overflow:auto}.vertical-tabs .tab .content.full-height{max-height:none}.vertical-tabs [type=radio]:checked+label{background:#fff;border:0;color:#000;width:38%}.vertical-tabs [type=radio]:focus+label{box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.vertical-tabs [type=radio]:checked~.content{display:block}@media screen and (max-width:1100px){.flex{flex-wrap:wrap}.fixed aside.info,.fixed aside.info+article,aside.info,aside.info+article{max-width:none;width:100%}}@media screen and (max-width:800px){*{max-width:none}table{box-shadow:none}.details .flex>*,body{margin:0}table,table .align-right,table td,table th,table.align-center{border:0;margin-left:auto;margin-right:auto;text-align:left;width:100%}table td{display:inline-block}table tbody,table.media-details{width:100%}table.media-details td{display:block;text-align:left!important;width:100%}table thead{display:none}.details .media-details td:nth-child(odd){font-weight:700;width:100%}table.streaming-links tr td:not(:first-child){display:none}}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}img,picture{width:100%}main{padding:0 .5rem .5rem}.media{margin:2px 0}.details{padding:.5rem}.tabs>[type=radio]:checked+label{background:#fff}.vertical-tabs .tab{flex-wrap:wrap}.tabs .content,.tabs>[type=radio]:checked+label+.content,.vertical-tabs .tab .content{border:0;display:block;max-height:none}.tabs>[type=radio]:checked+label,.tabs>label,.tabs>label:active,.tabs>label:hover,.vertical-tabs .tab label,.vertical-tabs .tab label:active,.vertical-tabs .tab label:hover,.vertical-tabs [type=radio]:checked+label,.vertical-tabs [type=radio]:focus+label{background:#fff;border:0;color:#000;cursor:default;width:100%}} \ No newline at end of file diff --git a/public/js/scripts.min.js b/public/js/scripts.min.js index e6e73ffd..abf4101f 100644 --- a/public/js/scripts.min.js +++ b/public/js/scripts.min.js @@ -1 +1,38 @@ -function _extends(){_extends=Object.assign||function(target){for(var i=1;i=0&&m.item(i)!==elm);return i>-1};var AnimeClient={noop:function(){},$:function $(selector,context){if(context===void 0)context=null;if(typeof selector!=="string")return selector;context=context!==null&&context.nodeType===1?context:document;var elements=[];if(selector.match(/^#([\w]+$)/))elements.push(document.getElementById(selector.split("#")[1]));else elements=[].slice.apply(context.querySelectorAll(selector));return elements},hasElement:function hasElement(selector){return AnimeClient.$(selector).length>0},scrollToTop:function scrollToTop(){var el=AnimeClient.$("header")[0];el.scrollIntoView(true)},hide:function hide(sel){if(typeof sel==="string")sel=AnimeClient.$(sel);if(Array.isArray(sel))sel.forEach(function(el){return el.setAttribute("hidden","hidden")});else sel.setAttribute("hidden","hidden")},show:function show(sel){if(typeof sel==="string")sel=AnimeClient.$(sel);if(Array.isArray(sel))sel.forEach(function(el){return el.removeAttribute("hidden")});else sel.removeAttribute("hidden")},showMessage:function showMessage(type,message){var template="
\n \n "+message+"\n \n
";var sel=AnimeClient.$(".message");if(sel[0]!==undefined)sel[0].remove();AnimeClient.$("header")[0].insertAdjacentHTML("beforeend",template)},closestParent:function closestParent(current,parentSelector){if(Element.prototype.closest!==undefined)return current.closest(parentSelector);while(current!==document.documentElement){if(matches(current,parentSelector))return current;current=current.parentElement}return null},url:function url(path){var uri="//"+document.location.host;uri+=path.charAt(0)==="/"?path:"/"+path;return uri},throttle:function throttle(interval,fn,scope){var wait=false;return function(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var context=scope||this;if(!wait){fn.apply(context,args);wait=true;setTimeout(function(){wait=false},interval)}}}};function addEvent(sel,event,listener){if(!event.match(/^([\w\-]+)$/))event.split(" ").forEach(function(evt){addEvent(sel,evt,listener)});sel.addEventListener(event,listener,false)}function delegateEvent(sel,target,event,listener){addEvent(sel,event,function(e){AnimeClient.$(target,sel).forEach(function(element){if(e.target==element){listener.call(element,e);e.stopPropagation()}})})}AnimeClient.on=function(sel,event,target,listener){if(listener===undefined){listener=target;AnimeClient.$(sel).forEach(function(el){addEvent(el,event,listener)})}else AnimeClient.$(sel).forEach(function(el){delegateEvent(el,target,event,listener)})};function ajaxSerialize(data){var pairs=[];Object.keys(data).forEach(function(name){var value=data[name].toString();name=encodeURIComponent(name);value=encodeURIComponent(value);pairs.push(name+"="+value)});return pairs.join("&")}AnimeClient.ajax=function(url,config){var defaultConfig={data:{},type:"GET",dataType:"",success:AnimeClient.noop,mimeType:"application/x-www-form-urlencoded",error:AnimeClient.noop};config=_extends({},defaultConfig,config);var request=new XMLHttpRequest;var method=String(config.type).toUpperCase();if(method==="GET")url+=url.match(/\?/)?ajaxSerialize(config.data):"?"+ajaxSerialize(config.data);request.open(method,url);request.onreadystatechange=function(){if(request.readyState===4){var responseText="";if(request.responseType==="json")responseText=JSON.parse(request.responseText);else responseText=request.responseText;if(request.status>299)config.error.call(null,request.status,responseText,request.response);else config.success.call(null,responseText,request.status)}};if(config.dataType==="json"){config.data=JSON.stringify(config.data);config.mimeType="application/json"}else config.data=ajaxSerialize(config.data);request.setRequestHeader("Content-Type",config.mimeType);if(method==="GET")request.send(null);else request.send(config.data);return request};AnimeClient.get=function(url,data,callback){if(callback===void 0)callback=null;if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data:data,success:callback})};AnimeClient.on("header","click",".message",hide);AnimeClient.on("form.js-delete","submit",confirmDelete);AnimeClient.on(".js-clear-cache","click",clearAPICache);AnimeClient.on(".vertical-tabs input","change",scrollToSection);AnimeClient.on(".media-filter","input",filterMedia);function hide(event){AnimeClient.hide(event.target)}function confirmDelete(event){var proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}}function clearAPICache(){AnimeClient.get("/cache_purge",function(){AnimeClient.showMessage("success","Successfully purged api cache")})}function scrollToSection(event){var el=event.currentTarget.parentElement;var rect=el.getBoundingClientRect();var top=rect.top+window.pageYOffset;window.scrollTo({top:top,behavior:"smooth"})}function filterMedia(event){var rawFilter=event.target.value;var filter=new RegExp(rawFilter,"i");if(rawFilter!==""){AnimeClient.$("article.media").forEach(function(article){var titleLink=AnimeClient.$(".name a",article)[0];var title=String(titleLink.textContent).trim();if(!filter.test(title))AnimeClient.hide(article);else AnimeClient.show(article)});AnimeClient.$("table.media-wrap tbody tr").forEach(function(tr){var titleCell=AnimeClient.$("td.align-left",tr)[0];var titleLink=AnimeClient.$("a",titleCell)[0];var linkTitle=String(titleLink.textContent).trim();var textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}(function(){var hidden=null;var visibilityChange=null;if(typeof document.hidden!=="undefined"){hidden="hidden";visibilityChange="visibilitychange"}else if(typeof document.msHidden!=="undefined"){hidden="msHidden";visibilityChange="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){hidden="webkitHidden";visibilityChange="webkitvisibilitychange"}function handleVisibilityChange(){if(!document[hidden])AnimeClient.get("/heartbeat",function(beat){var status=JSON.parse(beat);if(status.hasAuth!==true){document.removeEventListener(visibilityChange,handleVisibilityChange,false);location.reload()}})}if(hidden===null)console.info("Page visibility API not supported, JS session check will not work");else document.addEventListener(visibilityChange,handleVisibilityChange,false)})();AnimeClient.on("main","change",".big-check",function(e){var id=e.target.id;document.getElementById("mal_"+id).checked=true;document.getElementById("anilist_"+id).checked=true});function renderEditLink(type,item,isCollection){if(isCollection===void 0)isCollection=false;if(isCollection||item.libraryEntry===null)return"";return'\n
\n [ Already in List ]\n
\n
\n \n Edit\n \n
\n
 
\n '}function renderSearchResults(type,data,isCollection){if(isCollection===void 0)isCollection=false;return data.map(function(item){var titles=item.titles.join("
");var disabled=item.libraryEntry!==null?"disabled":"";var editLink=renderEditLink(type,item,isCollection);if(isCollection)disabled="";return'\n \n '}).join("")}var search=function(query,isCollection){if(isCollection===void 0)isCollection=false;AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("anime",searchResults,isCollection)})};if(AnimeClient.hasElement(".anime #search")){var prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}if(AnimeClient.hasElement("#search-anime-collection")){var prevRequest1=null;AnimeClient.on("#search-anime-collection","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest1!==null)prevRequest1.abort();prevRequest1=search(query,true)}))}AnimeClient.on("body.anime.list","click",".plus-one",function(e){var parentSel=AnimeClient.closestParent(e.target,"article");var watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;var totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);var title=AnimeClient.$(".name a",parentSel)[0].textContent;var data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};if(isNaN(watchedCount)||watchedCount===0)data.data.status="CURRENT";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="COMPLETED";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data:data,dataType:"json",type:"POST",success:function(res){var resData=JSON.parse(res);if(resData.error){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop();return}if(resData.data.libraryEntry.update.libraryEntry.status==="COMPLETED"){AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("success","Successfully completed "+title);AnimeClient.scrollToTop();return}AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("success","Successfully updated "+title);AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+title+". ");AnimeClient.scrollToTop()}})});var search1=function(query){AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query:query},function(searchResults,status){searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("manga",searchResults)})};if(AnimeClient.hasElement(".manga #search")){var prevRequest2=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,function(e){var query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest2!==null)prevRequest2.abort();prevRequest2=search1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",function(e){var thisSel=e.target;var parentSel=AnimeClient.closestParent(e.target,"article");var type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";var completed=parseInt(AnimeClient.$("."+type+"s_read",parentSel)[0].textContent,10)||0;var total=parseInt(AnimeClient.$("."+type+"_count",parentSel)[0].textContent,10);var mangaName=AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;var data={id:parentSel.dataset.kitsuId,mal_id:parentSel.dataset.malId,data:{progress:completed}};if(isNaN(completed)||completed===0)data.data.status="CURRENT";if(!isNaN(completed)&&completed+1===total)data.data.status="COMPLETED";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data:data,dataType:"json",type:"POST",mimeType:"application/json",success:function(res){var resData=JSON.parse(res);if(resData.error){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+mangaName+". ");AnimeClient.scrollToTop();return}if(String(data.data.status).toUpperCase()==="COMPLETED"){AnimeClient.hide(parentSel);AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("success","Successfully completed "+mangaName);AnimeClient.scrollToTop();return}AnimeClient.hide("#loading-shadow");AnimeClient.$("."+type+"s_read",parentSel)[0].textContent=String(completed);AnimeClient.showMessage("success","Successfully updated "+mangaName);AnimeClient.scrollToTop()},error:function(){AnimeClient.hide("#loading-shadow");AnimeClient.showMessage("error","Failed to update "+mangaName);AnimeClient.scrollToTop()}})}); \ No newline at end of file +function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _objectSpread(target){for(var i=1;i{console.log("Service worker registered",reg.scope)}).catch(error=>{console.error("Failed to register service worker",error)});const matches=(elm,selector)=>{let m=(elm.document||elm.ownerDocument).querySelectorAll(selector);let i=matches.length;while(--i>=0&&m.item(i)!==elm);return i>-1};const AnimeClient={noop:()=>{},$(selector,context=null){if(typeof selector!=="string")return selector;context=context!==null&&context.nodeType===1?context:document;let elements=[];if(selector.match(/^#([\w]+$)/))elements.push(document.getElementById(selector.split("#")[1]));else elements=[].slice.apply(context.querySelectorAll(selector));return elements},hasElement(selector){return AnimeClient.$(selector).length>0},scrollToTop(){const el=AnimeClient.$("header")[0];el.scrollIntoView(true)},hide(sel){if(typeof sel==="string")sel=AnimeClient.$(sel);if(Array.isArray(sel))sel.forEach(el=>el.setAttribute("hidden","hidden"));else sel.setAttribute("hidden","hidden")},show(sel){if(typeof sel==="string")sel=AnimeClient.$(sel);if(Array.isArray(sel))sel.forEach(el=>el.removeAttribute("hidden"));else sel.removeAttribute("hidden")},showMessage(type,message){let template=`
+ + ${message} + +
`;let sel=AnimeClient.$(".message");if(sel[0]!==undefined)sel[0].remove();AnimeClient.$("header")[0].insertAdjacentHTML("beforeend",template)},closestParent(current,parentSelector){if(Element.prototype.closest!==undefined)return current.closest(parentSelector);while(current!==document.documentElement){if(matches(current,parentSelector))return current;current=current.parentElement}return null},url(path){let uri=`//${document.location.host}`;uri+=path.charAt(0)==="/"?path:`/${path}`;return uri},throttle(interval,fn,scope){let wait=false;return function(...args){const context=scope||this;if(!wait){fn.apply(context,args);wait=true;setTimeout(function(){wait=false},interval)}}}};function addEvent(sel,event,listener){if(!event.match(/^([\w\-]+)$/))event.split(" ").forEach(evt=>{addEvent(sel,evt,listener)});sel.addEventListener(event,listener,false)}function delegateEvent(sel,target,event,listener){addEvent(sel,event,e=>{AnimeClient.$(target,sel).forEach(element=>{if(e.target==element){listener.call(element,e);e.stopPropagation()}})})}AnimeClient.on=(sel,event,target,listener)=>{if(listener===undefined){listener=target;AnimeClient.$(sel).forEach(el=>{addEvent(el,event,listener)})}else AnimeClient.$(sel).forEach(el=>{delegateEvent(el,target,event,listener)})};function ajaxSerialize(data){let pairs=[];Object.keys(data).forEach(name=>{let value=data[name].toString();name=encodeURIComponent(name);value=encodeURIComponent(value);pairs.push(`${name}=${value}`)});return pairs.join("&")}AnimeClient.ajax=(url,config)=>{const defaultConfig={data:{},type:"GET",dataType:"",success:AnimeClient.noop,mimeType:"application/x-www-form-urlencoded",error:AnimeClient.noop};config=_objectSpread({},defaultConfig,config);let request=new XMLHttpRequest;let method=String(config.type).toUpperCase();if(method==="GET")url+=url.match(/\?/)?ajaxSerialize(config.data):`?${ajaxSerialize(config.data)}`;request.open(method,url);request.onreadystatechange=()=>{if(request.readyState===4){let responseText="";if(request.responseType==="json")responseText=JSON.parse(request.responseText);else responseText=request.responseText;if(request.status>299)config.error.call(null,request.status,responseText,request.response);else config.success.call(null,responseText,request.status)}};if(config.dataType==="json"){config.data=JSON.stringify(config.data);config.mimeType="application/json"}else config.data=ajaxSerialize(config.data);request.setRequestHeader("Content-Type",config.mimeType);if(method==="GET")request.send(null);else request.send(config.data);return request};AnimeClient.get=(url,data,callback=null)=>{if(callback===null){callback=data;data={}}return AnimeClient.ajax(url,{data,success:callback})};AnimeClient.on("header","click",".message",hide);AnimeClient.on("form.js-delete","submit",confirmDelete);AnimeClient.on(".js-clear-cache","click",clearAPICache);AnimeClient.on(".vertical-tabs input","change",scrollToSection);AnimeClient.on(".media-filter","input",filterMedia);function hide(event){AnimeClient.hide(event.target)}function confirmDelete(event){const proceed=confirm("Are you ABSOLUTELY SURE you want to delete this item?");if(proceed===false){event.preventDefault();event.stopPropagation()}}function clearAPICache(){AnimeClient.get("/cache_purge",()=>{AnimeClient.showMessage("success","Successfully purged api cache")})}function scrollToSection(event){const el=event.currentTarget.parentElement;const rect=el.getBoundingClientRect();const top=rect.top+window.pageYOffset;window.scrollTo({top,behavior:"smooth"})}function filterMedia(event){const rawFilter=event.target.value;const filter=new RegExp(rawFilter,"i");if(rawFilter!==""){AnimeClient.$("article.media").forEach(article=>{const titleLink=AnimeClient.$(".name a",article)[0];const title=String(titleLink.textContent).trim();if(!filter.test(title))AnimeClient.hide(article);else AnimeClient.show(article)});AnimeClient.$("table.media-wrap tbody tr").forEach(tr=>{const titleCell=AnimeClient.$("td.align-left",tr)[0];const titleLink=AnimeClient.$("a",titleCell)[0];const linkTitle=String(titleLink.textContent).trim();const textTitle=String(titleCell.textContent).trim();if(!(filter.test(linkTitle)||filter.test(textTitle)))AnimeClient.hide(tr);else AnimeClient.show(tr)})}else{AnimeClient.show("article.media");AnimeClient.show("table.media-wrap tbody tr")}}(()=>{let hidden=null;let visibilityChange=null;if(typeof document.hidden!=="undefined"){hidden="hidden";visibilityChange="visibilitychange"}else if(typeof document.msHidden!=="undefined"){hidden="msHidden";visibilityChange="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){hidden="webkitHidden";visibilityChange="webkitvisibilitychange"}function handleVisibilityChange(){if(!document[hidden])AnimeClient.get("/heartbeat",beat=>{const status=JSON.parse(beat);if(status.hasAuth!==true){document.removeEventListener(visibilityChange,handleVisibilityChange,false);location.reload()}})}if(hidden===null)console.info("Page visibility API not supported, JS session check will not work");else document.addEventListener(visibilityChange,handleVisibilityChange,false)})();AnimeClient.on("main","change",".big-check",e=>{const id=e.target.id;document.getElementById(`mal_${id}`).checked=true;document.getElementById(`anilist_${id}`).checked=true});function renderEditLink(type,item,isCollection=false){if(isCollection||item.libraryEntry===null)return"";return` +
+ [ Already in List ] +
+
+ + Edit + +
+
 
+ `}function renderSearchResults(type,data,isCollection=false){return data.map(item=>{const titles=item.titles.join("
");let disabled=item.libraryEntry!==null?"disabled":"";const editLink=renderEditLink(type,item,isCollection);if(isCollection)disabled="";return` + + `}).join("")}function _normalizeProperty(props,sep="."){return props.replace(/\[(.*?)]/g,sep+"$1")}function hasNestedProperty(object,property){if(object&&typeof object==="object"){if(typeof property==="string"&&property!==""){property=_normalizeProperty(property);let split=property.split(".");return split.reduce((obj,prop,idx,array)=>{if(idx===array.length-1)return!!(obj&&obj.hasOwnProperty(prop));return obj&&obj[prop]},object)}else if(typeof property==="number")return property in object}return false}function getNestedProperty(object,property,sep="."){if(isType("string",property)&&property!==""){property=_normalizeProperty(property,sep);const levels=property.split(sep);try{return levels.reduce((obj,prop)=>obj[prop],object)}catch(e){return undefined}}return null}function getType(x){if(Array.isArray(x))return"array";if(typeof x!=="object")return(typeof x).toLowerCase();const type=function(){return Object.prototype.toString.call(this).slice(8,-1)};return type.call(x).toLowerCase()}function isType(type,val){return getType(val)===String(type).toLowerCase()}const search=(query,isCollection=false)=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("anime",searchResults,isCollection)})};if(AnimeClient.hasElement(".anime #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}if(AnimeClient.hasElement("#search-anime-collection")){let prevRequest=null;AnimeClient.on("#search-anime-collection","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query,true)}))}AnimeClient.on("body.anime.list","click",".plus-one",e=>{let parentSel=AnimeClient.closestParent(e.target,"article");let watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;let totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);let title=AnimeClient.$(".name a",parentSel)[0].textContent;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}.`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(watchedCount)||watchedCount===0)data.data.status="CURRENT";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="COMPLETED";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data,dataType:"json",type:"POST",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;displayMessage("success","Updated")}catch(_){showError()}},error:showError})});const search1=query=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("manga",searchResults)})};if(AnimeClient.hasElement(".manga #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{let query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",e=>{let thisSel=e.target;let parentSel=AnimeClient.closestParent(e.target,"article");let type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";let completed=parseInt(AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent,10)||0;let total=parseInt(AnimeClient.$(`.${type}_count`,parentSel)[0].textContent,10);let title=AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:completed}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}.`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(completed)||completed===0)data.data.status="CURRENT";if(!isNaN(completed)&&completed+1===total)data.data.status="COMPLETED";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data,dataType:"json",type:"POST",mimeType:"application/json",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent=String(completed);displayMessage("success","Updated")}catch(_){showError()}},error:showError})}); \ No newline at end of file diff --git a/public/js/scripts.min.js.map b/public/js/scripts.min.js.map index 82032548..24a2ad88 100644 --- a/public/js/scripts.min.js.map +++ b/public/js/scripts.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/sw.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime-client.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/events.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/session-check.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/template-helpers.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/manga.js"],"sourcesContent":["// Start the service worker, if you can\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}","// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nconst AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {Element} [context]\n\t * @return array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {Element} current - the current Element\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {Element|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|Element} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|Element|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import _ from './anime-client.js';\n\n(() => {\n\tlet hidden = null;\n\tlet visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tdocument.removeEventListener(visibilityChange, handleVisibilityChange, false);\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n\tdocument.getElementById(`anilist_${id}`).checked = true;\n});\n\n/**\n * On search results with an existing library entry, this shows that fact, with an edit link for the existing\n * library entry\n *\n * @param {'anime'|'manga'} type\n * @param {Object} item\n * @param isCollection\n * @returns {String}\n */\nfunction renderEditLink (type, item, isCollection = false) {\n\tif (isCollection || item.libraryEntry === null) {\n\t\treturn '';\n\t}\n\n\treturn `\n\t\t
\n\t\t\t[ Already in List ]\n\t\t
\n\t\t
\n\t\t\t\n\t\t\t\tEdit\n\t\t\t\n\t\t
\n\t\t
 
\n\t`\n}\n\n/**\n * Show the search results for a media item\n *\n * @param {'anime'|'manga'} type\n * @param {Object} data\n * @param {boolean} isCollection\n * @returns {String}\n */\nexport function renderSearchResults (type, data, isCollection = false) {\n\treturn data.map(item => {\n\t\tconst titles = item.titles.join('
');\n\t\tlet disabled = item.libraryEntry !== null ? 'disabled' : '';\n\t\tconst editLink = renderEditLink(type, item, isCollection);\n\n\t\tif (isCollection) {\n\t\t\tdisabled = '';\n\t\t}\n\n\t\treturn `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t${editLink}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`;\n\t}).join('');\n}","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\n\nconst search = (query, isCollection = false) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults, isCollection);\n\t});\n};\n\n// Anime list search\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Anime collection search\nif (_.hasElement('#search-anime-collection')) {\n\tlet prevRequest = null;\n\n\t_.on('#search-anime-collection', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query, true);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res);\n\n\t\t\tif (resData.error) {\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t\t_.scrollToTop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// We've completed the series\n\t\t\tif (resData.data.libraryEntry.update.libraryEntry.status === 'COMPLETED') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('success', `Successfully completed ${title}`);\n\t\t\t\t_.scrollToTop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.showMessage('success', `Successfully updated ${title}`);\n\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${title}. `);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet mangaName = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: (res) => {\n\t\t\tconst resData = JSON.parse(res)\n\t\t\tif (resData.error) {\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('error', `Failed to update ${mangaName}. `);\n\t\t\t\t_.scrollToTop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (String(data.data.status).toUpperCase() === 'COMPLETED') {\n\t\t\t\t_.hide(parentSel);\n\t\t\t\t_.hide('#loading-shadow');\n\t\t\t\t_.showMessage('success', `Successfully completed ${mangaName}`);\n\t\t\t\t_.scrollToTop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t_.hide('#loading-shadow');\n\n\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed);\n\t\t\t_.showMessage('success', `Successfully updated ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t},\n\t\terror: () => {\n\t\t\t_.hide('#loading-shadow');\n\t\t\t_.showMessage('error', `Failed to update ${mangaName}`);\n\t\t\t_.scrollToTop();\n\t\t}\n\t});\n});"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/sw.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime-client.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/events.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/session-check.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/template-helpers.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/fns.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/manga.js"],"sourcesContent":["// Start the service worker, if you can\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}","// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nconst AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {Element} [context]\n\t * @return array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {Element} current - the current Element\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {Element|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|Element} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|Element|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import _ from './anime-client.js';\n\n(() => {\n\tlet hidden = null;\n\tlet visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tdocument.removeEventListener(visibilityChange, handleVisibilityChange, false);\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n\tdocument.getElementById(`anilist_${id}`).checked = true;\n});\n\n/**\n * On search results with an existing library entry, this shows that fact, with an edit link for the existing\n * library entry\n *\n * @param {'anime'|'manga'} type\n * @param {Object} item\n * @param isCollection\n * @returns {String}\n */\nfunction renderEditLink (type, item, isCollection = false) {\n\tif (isCollection || item.libraryEntry === null) {\n\t\treturn '';\n\t}\n\n\treturn `\n\t\t
\n\t\t\t[ Already in List ]\n\t\t
\n\t\t
\n\t\t\t\n\t\t\t\tEdit\n\t\t\t\n\t\t
\n\t\t
 
\n\t`\n}\n\n/**\n * Show the search results for a media item\n *\n * @param {'anime'|'manga'} type\n * @param {Object} data\n * @param {boolean} isCollection\n * @returns {String}\n */\nexport function renderSearchResults (type, data, isCollection = false) {\n\treturn data.map(item => {\n\t\tconst titles = item.titles.join('
');\n\t\tlet disabled = item.libraryEntry !== null ? 'disabled' : '';\n\t\tconst editLink = renderEditLink(type, item, isCollection);\n\n\t\tif (isCollection) {\n\t\t\tdisabled = '';\n\t\t}\n\n\t\treturn `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t${editLink}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`;\n\t}).join('');\n}","/**\n * Make sure properties are in an easily splittable format\n *\n * @private\n * @param {String} props\n * @param {String} [sep='.'] The default separator\n * @return {String}\n */\nfunction _normalizeProperty(props, sep = '.') {\n\t// Since we split by period, and property lookup\n\t// is the same by dot or [], replace bracket lookups\n\t// with periods\n\treturn props.replace(/\\[(.*?)]/g, sep + '$1');\n}\n\n/**\n * Tell if a nested object has a given property (or array a given index)\n * given an object such as a.b.c.d = 5, hasNestedProperty(a, 'b.c.d') will return true.\n *\n * @param {Object} object the object to get the property from\n * @param {String} property the path to the property as a string\n * @returns {boolean} true when property in object, false otherwise\n */\nexport function hasNestedProperty(object, property) {\n\tif (object && typeof object === 'object') {\n\t\tif (typeof property === 'string' && property !== '') {\n\t\t\tproperty = _normalizeProperty(property);\n\n\t\t\tlet split = property.split('.');\n\t\t\treturn split.reduce((obj, prop, idx, array) => {\n\t\t\t\tif (idx === array.length - 1) {\n\t\t\t\t\treturn !!(obj && obj.hasOwnProperty(prop));\n\t\t\t\t}\n\n\t\t\t\treturn obj && obj[prop];\n\t\t\t}, object);\n\t\t} else if (typeof property === 'number') {\n\t\t\treturn property in object;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Get the value of a deeply nested property in an object\n *\n * @param {Object} object the object to get the property\n * @param {string} property the path to the property as a string\n * @param {string} [sep='.'] The default separator to split on\n * @return {*} the value of the property\n */\nexport function getNestedProperty(object, property, sep = '.') {\n\tif (isType('string', property) && property !== '') {\n\t\t// convert numbers to dot syntax\n\t\tproperty = _normalizeProperty(property, sep);\n\t\tconst levels = property.split(sep);\n\n\t\ttry {\n\t\t\treturn levels.reduce((obj, prop) => obj[prop], object);\n\t\t} catch (e) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Reliably get the type of the value of a variable\n *\n * @param {*} x The variable to get the type of\n * @return {string} The name of the type\n */\nexport function getType(x) {\n\t// is it an array?\n\tif (Array.isArray(x)) {\n\t\treturn 'array';\n\t}\n\n\t// Use typeof for truthy primitives\n\tif (typeof x !== 'object') {\n\t\treturn (typeof x).toLowerCase();\n\t}\n\n\tconst type = function () {\n\t\treturn Object.prototype.toString.call(this).slice(8, -1);\n\t}\n\n\t// Otherwise, strip the type out of the '[Object x]' toString value\n\treturn type.call(x).toLowerCase();\n}\n\n/**\n * Check whether the value matches the passed type name\n *\n * @param {string} type Javascript type name\n * @param {*} val The value to type check\n * @return {boolean}\n */\nexport function isType(type, val) {\n\treturn getType(val) === String(type).toLowerCase();\n}","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query, isCollection = false) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults, isCollection);\n\t});\n};\n\n// Anime list search\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Anime collection search\nif (_.hasElement('#search-anime-collection')) {\n\tlet prevRequest = null;\n\n\t_.on('#search-anime-collection', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query, true);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}.`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t\tdisplayMessage('success', 'Updated');\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}.`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed);\n\t\t\t\tdisplayMessage('success', 'Updated');\n\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/public/js/tables.min.js b/public/js/tables.min.js index 11c03a86..143d272e 100644 --- a/public/js/tables.min.js +++ b/public/js/tables.min.js @@ -1 +1 @@ -var LightTableSorter=function(){var th=null;var cellIndex=null;var order="";var text=function(row){return row.cells.item(cellIndex).textContent.toLowerCase()};var sort=function(a,b){var textA=text(a);var textB=text(b);console.log("Comparing "+textA+" and "+textB);if(th.classList.contains("numeric")){var arrayA=textA.replace("episodes: ","").replace("-",0).split("/");var arrayB=textB.replace("episodes: ","").replace("-",0).split("/");if(arrayA.length>1){textA=parseInt(arrayA[0],10)/parseInt(arrayA[1],10);textB=parseInt(arrayB[0],10)/parseInt(arrayB[1],10)}else{textA=parseInt(arrayA[0],10);textB=parseInt(arrayB[0],10)}}else if(parseInt(textA,10)){textA=parseInt(textA,10);textB=parseInt(textB,10)}if(textA>textB)return 1;if(textA{let th=null;let cellIndex=null;let order="";const text=row=>row.cells.item(cellIndex).textContent.toLowerCase();const sort=(a,b)=>{let textA=text(a);let textB=text(b);console.log("Comparing "+textA+" and "+textB);if(th.classList.contains("numeric")){let arrayA=textA.replace("episodes: ","").replace("-",0).split("/");let arrayB=textB.replace("episodes: ","").replace("-",0).split("/");if(arrayA.length>1){textA=parseInt(arrayA[0],10)/parseInt(arrayA[1],10);textB=parseInt(arrayB[0],10)/parseInt(arrayB[1],10)}else{textA=parseInt(arrayA[0],10);textB=parseInt(arrayB[0],10)}}else if(parseInt(textA,10)){textA=parseInt(textA,10);textB=parseInt(textB,10)}if(textA>textB)return 1;if(textA{const c=order!=="sorting-asc"?"sorting-asc":"sorting-desc";th.className=(th.className.replace(order,"")+" "+c).trim();return order=c};const reset=()=>{th.classList.remove("sorting-asc","sorting-desc");th.classList.add("sorting");return order=""};const onClickEvent=e=>{if(th&&cellIndex!==e.target.cellIndex)reset();th=e.target;if(th.nodeName.toLowerCase()==="th"){cellIndex=th.cellIndex;const tbody=th.offsetParent.getElementsByTagName("tbody")[0];let rows=Array.from(tbody.rows);if(rows){rows.sort(sort);if(order==="sorting-asc")rows.reverse();toggle();tbody.innerHtml="";rows.forEach(row=>{tbody.appendChild(row)})}}};return{init:()=>{let ths=document.getElementsByTagName("th");let results=[];for(let i=0,len=ths.length;i {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconsole.log(\"Comparing \" + textA + \" and \" + textB)\n\n\t\tif(th.classList.contains(\"numeric\")){\n\t\t\tlet arrayA = textA.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tlet arrayB = textB.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tif(arrayA.length > 1) {\n\t\t\t\ttextA = parseInt(arrayA[0],10) / parseInt(arrayA[1],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10) / parseInt(arrayB[1],10);\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextA = parseInt(arrayA[0],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10);\n\t\t\t}\n\t\t}\n\t\telse if (parseInt(textA, 10)) {\n\t\t\ttextA = parseInt(textA, 10);\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting-asc' ? 'sorting-asc' : 'sorting-desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting-asc', 'sorting-desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting-asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tth.classList.add('testing');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/base/sort-tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconsole.log(\"Comparing \" + textA + \" and \" + textB)\n\n\t\tif(th.classList.contains(\"numeric\")){\n\t\t\tlet arrayA = textA.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tlet arrayB = textB.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tif(arrayA.length > 1) {\n\t\t\t\ttextA = parseInt(arrayA[0],10) / parseInt(arrayA[1],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10) / parseInt(arrayB[1],10);\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextA = parseInt(arrayA[0],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10);\n\t\t\t}\n\t\t}\n\t\telse if (parseInt(textA, 10)) {\n\t\t\ttextA = parseInt(textA, 10);\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting-asc' ? 'sorting-asc' : 'sorting-desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting-asc', 'sorting-desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting-asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tth.classList.add('testing');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"AAAA,MAAM,iBAAmB,AAAC,CAAA,IAAM,CAC/B,IAAI,GAAK,IAAI,CACb,IAAI,UAAY,IAAI,CACpB,IAAI,MAAQ,GACZ,MAAM,KAAO,AAAC,KAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,CAAC,WAAW,GACvE,MAAM,KAAO,CAAC,EAAG,IAAM,CACtB,IAAI,MAAQ,KAAK,GACjB,IAAI,MAAQ,KAAK,GACjB,QAAQ,GAAG,CAAC,aAAe,MAAQ,QAAU,OAE7C,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,WAAW,CACnC,IAAI,OAAS,MAAM,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,KAClE,IAAI,OAAS,MAAM,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,KAClE,GAAG,OAAO,MAAM,CAAG,EAAG,CACrB,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,IACpD,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,GACrD,KACI,CACH,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAC3B,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,GAC5B,CAAC,AACF,MACK,GAAI,SAAS,MAAO,IAAK,CAC7B,MAAQ,SAAS,MAAO,IACxB,MAAQ,SAAS,MAAO,GACzB,CAAC,AACD,GAAI,MAAQ,MACX,OAAO,CACP,CACD,GAAI,MAAQ,MACX,OAAO,EACP,CACD,OAAO,CACR,EACA,MAAM,OAAS,IAAM,CACpB,MAAM,EAAI,QAAU,cAAgB,cAAgB,cAAc,AAClE,CAAA,GAAG,SAAS,CAAG,AAAC,CAAA,GAAG,SAAS,CAAC,OAAO,CAAC,MAAO,IAAM,IAAM,CAAA,EAAG,IAAI,GAC/D,OAAO,MAAQ,CAChB,EACA,MAAM,MAAQ,IAAM,CACnB,GAAG,SAAS,CAAC,MAAM,CAAC,cAAe,gBACnC,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,OAAO,MAAQ,EAChB,EACA,MAAM,aAAe,AAAC,GAAM,CAC3B,GAAI,IAAO,YAAc,EAAE,MAAM,CAAC,SAAS,CAC1C,OACA,CACD,GAAK,EAAE,MAAM,CACb,GAAI,GAAG,QAAQ,CAAC,WAAW,KAAO,KAAM,CACvC,UAAY,GAAG,SAAS,CACxB,MAAM,MAAQ,GAAG,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAC9D,IAAI,KAAO,MAAM,IAAI,CAAC,MAAM,IAAI,EAChC,GAAI,KAAM,CACT,KAAK,IAAI,CAAC,MACV,GAAI,QAAU,cACb,KAAK,OAAO,EACZ,CACD,QACA,CAAA,MAAM,SAAS,CAAG,GAElB,KAAK,OAAO,CAAC,KAAO,CACnB,MAAM,WAAW,CAAC,IACnB,EACD,CAAC,AACF,CAAC,AACF,EACA,MAAO,CACN,KAAM,IAAM,CACX,IAAI,IAAM,SAAS,oBAAoB,CAAC,MACxC,IAAI,QAAU,EAAE,CAChB,IAAK,IAAI,EAAI,EAAG,IAAM,IAAI,MAAM,CAAE,EAAI,IAAK,IAAK,CAC/C,IAAI,GAAK,GAAG,CAAC,EAAE,CACf,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,QAAQ,IAAI,CAAC,GAAG,OAAO,CAAG,aAC3B,CACA,OAAO,OACR,CACD,CACD,CAAA,IAEA,iBAAiB,IAAI"} \ No newline at end of file From 62d1647c0a551027064cd82ad8481db789240748 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 17 Mar 2023 16:38:41 -0400 Subject: [PATCH 02/18] Update aviat/query to fix PHP 8.2 deprecation notice --- composer.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 2667d963..626d2003 100644 --- a/composer.json +++ b/composer.json @@ -30,13 +30,12 @@ "lock": false }, "require": { - "amphp/amp": "^2.5.0", "amphp/http-client": "^4.5.0", "aura/html": "^2.5.0", "aura/router": "^3.1.0", "aura/session": "^2.1.0", "aviat/banker": "^4.1.2", - "aviat/query": "^4.0.0", + "aviat/query": "^4.1.0", "ext-dom": "*", "ext-gd": "*", "ext-intl": "*", @@ -56,9 +55,9 @@ }, "require-dev": { "phpstan/phpstan": "^1.2.0", - "phpunit/phpunit": "^9.5.0", + "phpunit/phpunit": "^10.0.0", "roave/security-advisories": "dev-master", - "spatie/phpunit-snapshot-assertions": "^4.1.0" + "spatie/phpunit-snapshot-assertions": "^5.0.1" }, "scripts": { "build:css": "cd public && npm run build:css && cd ..", From c78bccc56df2f714f6f0d71cbabace92fc181f16 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Tue, 9 May 2023 12:46:52 -0400 Subject: [PATCH 03/18] Style and tool updates --- CHANGELOG.md | 5 +- justfile | 6 +- src/Ion/Attribute/Controller.php | 9 +- src/Ion/Attribute/DefaultController.php | 4 +- src/Ion/Attribute/Route.php | 7 +- src/Ion/Di/Container.php | 4 +- src/Ion/Type/ArrayType.php | 4 +- src/Ion/Type/Stringy.php | 384 ++++++++++-------- src/Ion/View/HttpView.php | 3 +- .../Transformer/AnimeListTransformerTest.php | 16 +- tests/AnimeClient/DispatcherTest.php | 137 +++---- .../AnimeClient/Helper/PictureHelperTest.php | 12 +- tests/AnimeClient/KitsuTest.php | 32 +- tests/AnimeClient/RoutingBaseTest.php | 38 +- tests/AnimeClient/UrlGeneratorTest.php | 11 +- tests/AnimeClient/UtilTest.php | 57 ++- tests/Ion/ConfigTest.php | 10 +- tests/Ion/Di/ContainerTest.php | 11 +- tests/Ion/EnumTest.php | 28 +- tests/Ion/JsonTest.php | 28 +- .../Transformer/AbstractTransformerTest.php | 62 ++- tests/Ion/Type/ArrayTypeTest.php | 24 +- tests/Ion/Type/StringTypeTest.php | 7 +- tools/composer.json | 2 +- tools/header_comment.txt | 6 +- tools/offline-db-update.php | 0 tools/rector.php | 76 ++-- tools/update_header_comments.php | 6 +- 28 files changed, 514 insertions(+), 475 deletions(-) create mode 100644 tools/offline-db-update.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 12ceddbc..da8195a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # Changelog ## Version 5.2 -* Updated PHP requirement to 8 -* Updated to support PHP 8.1 +* Updated PHP requirement to 8.1 +* Updated to support PHP 8.2 +* Improve Anilist <-> Kitsu mappings to be more reliable ## Version 5.1 * Added session check, so when coming back to a page, if the session is expired, the page will refresh. diff --git a/justfile b/justfile index b154948d..9954e4b9 100644 --- a/justfile +++ b/justfile @@ -4,11 +4,11 @@ default: # Runs rector, showing what changes will be make rector-dry-run: - tools/vendor/bin/rector process --config=tools/rector.php --dry-run src + tools/vendor/bin/rector process --config=tools/rector.php --dry-run src tests -# Runs rector, and updates the files +# Runs rector, and updates the source files rector: - tools/vendor/bin/rector process --config=tools/rector.php src + tools/vendor/bin/rector process --config=tools/rector.php src tests # Check code formatting check-fmt: diff --git a/src/Ion/Attribute/Controller.php b/src/Ion/Attribute/Controller.php index c060323a..0adba4df 100644 --- a/src/Ion/Attribute/Controller.php +++ b/src/Ion/Attribute/Controller.php @@ -17,6 +17,9 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -class Controller { - public function __construct(public string $prefix = '') {} -} \ No newline at end of file +class Controller +{ + public function __construct(public string $prefix = '') + { + } +} diff --git a/src/Ion/Attribute/DefaultController.php b/src/Ion/Attribute/DefaultController.php index 830a79d1..4aea3e41 100644 --- a/src/Ion/Attribute/DefaultController.php +++ b/src/Ion/Attribute/DefaultController.php @@ -17,4 +17,6 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_CLASS)] -class DefaultController {} \ No newline at end of file +class DefaultController +{ +} diff --git a/src/Ion/Attribute/Route.php b/src/Ion/Attribute/Route.php index 21e771a2..a6cfbd58 100644 --- a/src/Ion/Attribute/Route.php +++ b/src/Ion/Attribute/Route.php @@ -17,7 +17,8 @@ namespace Aviat\Ion\Attribute; use Attribute; #[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] -class Route { +class Route +{ public const GET = 'get'; public const POST = 'post'; @@ -25,8 +26,6 @@ class Route { public string $name, public string $path, public string $verb = self::GET, - ) - { - + ) { } } diff --git a/src/Ion/Di/Container.php b/src/Ion/Di/Container.php index cf79e0d7..12f5a3d3 100644 --- a/src/Ion/Di/Container.php +++ b/src/Ion/Di/Container.php @@ -39,8 +39,8 @@ class Container implements ContainerInterface */ public function __construct( /** - * Array of container Generator functions - */ + * Array of container Generator functions + */ protected array $container = [] ) { $this->loggers = []; diff --git a/src/Ion/Type/ArrayType.php b/src/Ion/Type/ArrayType.php index 01529049..4766c48f 100644 --- a/src/Ion/Type/ArrayType.php +++ b/src/Ion/Type/ArrayType.php @@ -156,7 +156,7 @@ class ArrayType /** * Find an array key by its associated value */ - public function search(mixed $value, bool $strict = TRUE): int|string|FALSE|null + public function search(mixed $value, bool $strict = TRUE): int|string|false|null { return array_search($value, $this->arr, $strict); } @@ -172,7 +172,7 @@ class ArrayType /** * Return the array, or a key */ - public function &get(string|int|NULL $key = NULL): mixed + public function &get(string|int|null $key = NULL): mixed { $value = NULL; if ($key === NULL) diff --git a/src/Ion/Type/Stringy.php b/src/Ion/Type/Stringy.php index 1305d6ba..2aab130a 100644 --- a/src/Ion/Type/Stringy.php +++ b/src/Ion/Type/Stringy.php @@ -21,7 +21,22 @@ use Exception; use InvalidArgumentException; use IteratorAggregate; use OutOfBoundsException; +use RuntimeException; use Traversable; +use function mb_convert_case; +use function mb_ereg_match; +use function mb_ereg_replace; +use function mb_internal_encoding; +use function mb_regex_encoding; +use function mb_split; +use function mb_stripos; +use function mb_strlen; +use function mb_strrpos; +use function mb_strtolower; +use function mb_strtoupper; +use function mb_substr; +use function mb_substr_count; +use const MB_CASE_TITLE; /** * Vendored, slightly modernized version of Stringy @@ -29,16 +44,12 @@ use Traversable; abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { /** * An instance's string. - * - * @var string */ protected string $str; /** * The string's encoding, which should be one of the mbstring module's * supported encodings. - * - * @var string */ protected string $encoding; @@ -51,8 +62,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param mixed $str Value to modify, after being cast to string * @param string|null $encoding The character encoding - * @throws \InvalidArgumentException if an array or object without a - * __toString method is passed as the first argument + * @throws InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public function __construct(mixed $str = '', ?string $encoding = NULL) { @@ -61,7 +72,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { throw new InvalidArgumentException( 'Passed value cannot be an array' ); - } elseif (is_object($str) && ! method_exists($str, '__toString')) + } + if (is_object($str) && ! method_exists($str, '__toString')) { throw new InvalidArgumentException( 'Passed object must have a __toString method' @@ -69,7 +81,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } $this->str = (string)$str; - $this->encoding = $encoding ?: \mb_internal_encoding(); + $this->encoding = $encoding ?: mb_internal_encoding(); } /** @@ -82,8 +94,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param mixed $str Value to modify, after being cast to string * @param string|null $encoding The character encoding * @return static A Stringy object - * @throws \InvalidArgumentException if an array or object without a - * __toString method is passed as the first argument + * @throws InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument */ public static function create(mixed $str = '', ?string $encoding = NULL): self { @@ -140,7 +152,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return static::create('', $this->encoding); } - $substrIndex = $startIndex + \mb_strlen($start, $this->encoding); + $substrIndex = $startIndex + mb_strlen($start, $this->encoding); $endIndex = $this->indexOf($end, $substrIndex); if ($endIndex === FALSE) { @@ -165,10 +177,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[-_\s]+(.)?/u', - function ($match) use ($encoding) { + static function ($match) use ($encoding): string { if (isset($match[1])) { - return \mb_strtoupper($match[1], $encoding); + return mb_strtoupper($match[1], $encoding); } return ''; @@ -178,9 +190,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[\d]+(.)?/u', - function ($match) use ($encoding) { - return \mb_strtoupper($match[0], $encoding); - }, + static fn($match) => mb_strtoupper($match[0], $encoding), $stringy->str ); @@ -195,6 +205,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function chars(): array { $chars = []; + for ($i = 0, $l = $this->length(); $i < $l; $i++) { $chars[] = $this->at($i)->str; @@ -222,7 +233,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function contains(string $needle, bool $caseSensitive = TRUE): bool { @@ -230,10 +241,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($caseSensitive) { - return (\mb_strpos($this->str, $needle, 0, $encoding) !== FALSE); + return \mb_strpos($this->str, $needle, 0, $encoding) !== FALSE; } - return (\mb_stripos($this->str, $needle, 0, $encoding) !== FALSE); + return mb_stripos($this->str, $needle, 0, $encoding) !== FALSE; } /** @@ -243,7 +254,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $needles Substrings to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function containsAll(array $needles, bool $caseSensitive = TRUE): bool { @@ -270,7 +281,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $needles Substrings to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str contains $needle + * @return bool Whether or not $str contains $needle */ public function containsAny(array $needles, bool $caseSensitive = TRUE): bool { @@ -307,19 +318,19 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to search for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return int The number of $substring occurrences + * @return int The number of $substring occurrences */ public function countSubstr(string $substring, bool $caseSensitive = TRUE): int { if ($caseSensitive) { - return \mb_substr_count($this->str, $substring, $this->encoding); + return mb_substr_count($this->str, $substring, $this->encoding); } - $str = \mb_strtoupper($this->str, $this->encoding); - $substring = \mb_strtoupper($substring, $this->encoding); + $str = mb_strtoupper($this->str, $this->encoding); + $substring = mb_strtoupper($substring, $this->encoding); - return \mb_substr_count($str, $substring, $this->encoding); + return mb_substr_count($str, $substring, $this->encoding); } /** @@ -349,7 +360,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $this->regexEncoding($this->encoding); $str = $this->eregReplace('\B([A-Z])', '-\1', $this->trim()->__toString()); - $str = \mb_strtolower($str, $this->encoding); + $str = mb_strtolower($str, $this->encoding); $str = $this->eregReplace('[-_\s]+', $delimiter, $str); $this->regexEncoding($regexEncoding); @@ -364,20 +375,24 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to look for * @param bool $caseSensitive Whether or not to enforce case-sensitivity - * @return bool Whether or not $str ends with $substring + * @return bool Whether or not $str ends with $substring */ public function endsWith(string $substring, bool $caseSensitive = TRUE): bool { - $substringLength = \mb_strlen($substring, $this->encoding); + $substringLength = mb_strlen($substring, $this->encoding); $strLength = $this->length(); - $endOfStr = \mb_substr($this->str, $strLength - $substringLength, - $substringLength, $this->encoding); + $endOfStr = mb_substr( + $this->str, + $strLength - $substringLength, + $substringLength, + $this->encoding + ); if ( ! $caseSensitive) { - $substring = \mb_strtolower($substring, $this->encoding); - $endOfStr = \mb_strtolower($endOfStr, $this->encoding); + $substring = mb_strtolower($substring, $this->encoding); + $endOfStr = mb_strtolower($endOfStr, $this->encoding); } return (string)$substring === $endOfStr; @@ -390,8 +405,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $substrings Substrings to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str ends with $substring + * case-sensitivity + * @return bool Whether or not $str ends with $substring */ public function endsWithAny(array $substrings, bool $caseSensitive = TRUE): bool { @@ -462,6 +477,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($n < 0) { $stringy->str = ''; + return $stringy; } @@ -513,14 +529,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $this->matchesPattern('.*[[:upper:]]'); } - /** * Convert all HTML entities to their applicable characters. An alias of * html_entity_decode. For a list of flags, refer to * http://php.net/manual/en/function.html-entity-decode.php * * @param int|null $flags Optional flags - * @return static Object with the resulting $str after being html decoded. + * @return static Object with the resulting $str after being html decoded. */ public function htmlDecode(?int $flags = ENT_COMPAT): self { @@ -535,7 +550,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * for a list of flags. * * @param int|null $flags Optional flags - * @return static Object with the resulting $str after being html encoded. + * @return static Object with the resulting $str after being html encoded. */ public function htmlEncode(?int $flags = ENT_COMPAT): self { @@ -564,12 +579,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param int $offset Offset from which to search - * @return int|bool The occurrence's index if found, otherwise false + * @return bool|int The occurrence's index if found, otherwise false */ public function indexOf(string $needle, int $offset = 0): int|false { - return \mb_strpos($this->str, (string)$needle, - (int)$offset, $this->encoding); + return \mb_strpos( + $this->str, + (string)$needle, + (int)$offset, + $this->encoding + ); } /** @@ -580,12 +599,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $needle Substring to look for * @param int $offset Offset from which to search - * @return int|bool The last occurrence's index if found, otherwise false + * @return bool|int The last occurrence's index if found, otherwise false */ public function indexOfLast(string $needle, int $offset = 0): int|false { - return \mb_strrpos($this->str, (string)$needle, - (int)$offset, $this->encoding); + return mb_strrpos( + $this->str, + (string)$needle, + (int)$offset, + $this->encoding + ); } /** @@ -603,9 +626,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - $start = \mb_substr($stringy->str, 0, $index, $stringy->encoding); - $end = \mb_substr($stringy->str, $index, $stringy->length(), - $stringy->encoding); + $start = mb_substr($stringy->str, 0, $index, $stringy->encoding); + $end = mb_substr( + $stringy->str, + $index, + $stringy->length(), + $stringy->encoding + ); $stringy->str = $start . $substring . $end; @@ -672,7 +699,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { json_decode($this->str); - return (json_last_error() === JSON_ERROR_NONE); + return json_last_error() === JSON_ERROR_NONE; } /** @@ -696,7 +723,6 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $this->str === 'b:0;' || @unserialize($this->str) !== FALSE; } - /** * Returns true if the string is base64 encoded, false otherwise. * @@ -704,7 +730,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function isBase64(): bool { - return (base64_encode(base64_decode($this->str, TRUE)) === $this->str); + return base64_encode(base64_decode($this->str, TRUE)) === $this->str; } /** @@ -731,6 +757,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($n <= 0) { $stringy->str = ''; + return $stringy; } @@ -744,7 +771,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function length(): int { - return \mb_strlen($this->str, $this->encoding); + return mb_strlen($this->str, $this->encoding); } /** @@ -756,7 +783,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function lines(): array { $array = $this->split('[\r\n]{1,2}', $this->str); - for ($i = 0; $i < count($array); $i++) + $arrayCount = count($array); + + for ($i = 0; $i < $arrayCount; $i++) { $array[$i] = static::create($array[$i], $this->encoding); } @@ -773,14 +802,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function longestCommonPrefix(string $otherStr): self { $encoding = $this->encoding; - $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding)); + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); $longestCommonPrefix = ''; + for ($i = 0; $i < $maxLength; $i++) { - $char = \mb_substr($this->str, $i, 1, $encoding); + $char = mb_substr($this->str, $i, 1, $encoding); - if ($char == \mb_substr($otherStr, $i, 1, $encoding)) + if ($char === mb_substr($otherStr, $i, 1, $encoding)) { $longestCommonPrefix .= $char; } else @@ -801,14 +831,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function longestCommonSuffix(string $otherStr): self { $encoding = $this->encoding; - $maxLength = min($this->length(), \mb_strlen($otherStr, $encoding)); + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); $longestCommonSuffix = ''; + for ($i = 1; $i <= $maxLength; $i++) { - $char = \mb_substr($this->str, -$i, 1, $encoding); + $char = mb_substr($this->str, -$i, 1, $encoding); - if ($char == \mb_substr($otherStr, -$i, 1, $encoding)) + if ($char === mb_substr($otherStr, -$i, 1, $encoding)) { $longestCommonSuffix = $char . $longestCommonSuffix; } else @@ -834,28 +865,32 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $encoding = $this->encoding; $stringy = static::create($this->str, $encoding); $strLength = $stringy->length(); - $otherLength = \mb_strlen($otherStr, $encoding); + $otherLength = mb_strlen($otherStr, $encoding); // Return if either string is empty - if ($strLength == 0 || $otherLength == 0) + if ($strLength === 0 || $otherLength === 0) { $stringy->str = ''; + return $stringy; } $len = 0; $end = 0; - $table = array_fill(0, $strLength + 1, - array_fill(0, $otherLength + 1, 0)); + $table = array_fill( + 0, + $strLength + 1, + array_fill(0, $otherLength + 1, 0) + ); for ($i = 1; $i <= $strLength; $i++) { for ($j = 1; $j <= $otherLength; $j++) { - $strChar = \mb_substr($stringy->str, $i - 1, 1, $encoding); - $otherChar = \mb_substr($otherStr, $j - 1, 1, $encoding); + $strChar = mb_substr($stringy->str, $i - 1, 1, $encoding); + $otherChar = mb_substr($otherStr, $j - 1, 1, $encoding); - if ($strChar == $otherChar) + if ($strChar === $otherChar) { $table[$i][$j] = $table[$i - 1][$j - 1] + 1; if ($table[$i][$j] > $len) @@ -870,7 +905,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } } - $stringy->str = \mb_substr($stringy->str, $end - $len, $len, $encoding); + $stringy->str = mb_substr($stringy->str, $end - $len, $len, $encoding); return $stringy; } @@ -882,11 +917,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function lowerCaseFirst(): self { - $first = \mb_substr($this->str, 0, 1, $this->encoding); - $rest = \mb_substr($this->str, 1, $this->length() - 1, - $this->encoding); + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr( + $this->str, + 1, + $this->length() - 1, + $this->encoding + ); - $str = \mb_strtolower($first, $this->encoding) . $rest; + $str = mb_strtolower($first, $this->encoding) . $rest; return static::create($str, $this->encoding); } @@ -897,7 +936,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * part of the ArrayAccess interface. * * @param mixed $offset The index to check - * @return boolean Whether or not the index exists + * @return bool Whether or not the index exists */ public function offsetExists(mixed $offset): bool { @@ -906,10 +945,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($offset >= 0) { - return ($length > $offset); + return $length > $offset; } - return ($length >= abs($offset)); + return $length >= abs($offset); } /** @@ -919,9 +958,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * does not exist. * * @param mixed $offset The index from which to retrieve the char - * @return string The character at the specified index - * @throws \OutOfBoundsException If the positive or negative offset does - * not exist + * @return string The character at the specified index + * @throws OutOfBoundsException If the positive or negative offset does + * not exist */ public function offsetGet(mixed $offset): string { @@ -933,7 +972,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { throw new OutOfBoundsException('No character exists at the index'); } - return \mb_substr($this->str, $offset, 1, $this->encoding); + return mb_substr($this->str, $offset, 1, $this->encoding); } /** @@ -942,7 +981,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param mixed $offset The index of the character * @param mixed $value Value to set - * @throws \Exception When called + * @throws Exception When called */ public function offsetSet(mixed $offset, mixed $value): void { @@ -955,7 +994,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * when called. This maintains the immutability of Stringy objects. * * @param mixed $offset The index of the character - * @throws \Exception When called + * @throws Exception When called */ public function offsetUnset(mixed $offset): void { @@ -979,7 +1018,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self { - if ( ! in_array($padType, ['left', 'right', 'both'])) + if ( ! in_array($padType, ['left', 'right', 'both'], TRUE)) { throw new InvalidArgumentException('Pad expects $padType ' . "to be one of 'left', 'right' or 'both'"); @@ -989,8 +1028,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { case 'left': return $this->padLeft($length, $padStr); + case 'right': return $this->padRight($length, $padStr); + default: return $this->padBoth($length, $padStr); } @@ -1008,8 +1049,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $padding = $length - $this->length(); - return $this->applyPadding(floor($padding / 2), ceil($padding / 2), - $padStr); + return $this->applyPadding( + floor($padding / 2), + ceil($padding / 2), + $padStr + ); } /** @@ -1084,7 +1128,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($stringy->startsWith($substring)) { - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr($substringLength); } @@ -1103,7 +1148,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($stringy->endsWith($substring)) { - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr(0, $stringy->length() - $substringLength); } @@ -1148,7 +1194,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // Loop from last index of string to first for ($i = $strLength - 1; $i >= 0; $i--) { - $reversed .= \mb_substr($this->str, $i, 1, $this->encoding); + $reversed .= mb_substr($this->str, $i, 1, $this->encoding); } return static::create($reversed, $this->encoding); @@ -1174,19 +1220,19 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // Need to further trim the string so we can append the substring $encoding = $stringy->encoding; - $substringLength = \mb_strlen($substring, $encoding); + $substringLength = mb_strlen($substring, $encoding); $length = $length - $substringLength; - $truncated = \mb_substr($stringy->str, 0, $length, $encoding); + $truncated = mb_substr($stringy->str, 0, $length, $encoding); // If the last word was truncated - if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) != $length) + if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) !== $length) { // Find pos of the last occurrence of a space, get up to that - $lastPos = \mb_strrpos($truncated, ' ', 0, $encoding); + $lastPos = mb_strrpos($truncated, ' ', 0, $encoding); if ($lastPos !== FALSE) { - $truncated = \mb_substr($truncated, 0, $lastPos, $encoding); + $truncated = mb_substr($truncated, 0, $lastPos, $encoding); } } @@ -1195,7 +1241,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - /* + /** * A multibyte str_shuffle() function. It returns a string with its * characters in random order. * @@ -1207,9 +1253,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { shuffle($indexes); $shuffledStr = ''; + foreach ($indexes as $i) { - $shuffledStr .= \mb_substr($this->str, $i, 1, $this->encoding); + $shuffledStr .= mb_substr($this->str, $i, 1, $this->encoding); } return static::create($shuffledStr, $this->encoding); @@ -1233,7 +1280,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = str_replace('@', $replacement, $stringy); $quotedReplacement = preg_quote($replacement); - $pattern = "/[^a-zA-Z\d\s-_$quotedReplacement]/u"; + $pattern = "/[^a-zA-Z\\d\\s-_{$quotedReplacement}]/u"; $stringy->str = preg_replace($pattern, '', $stringy); return $stringy->toLowerCase()->delimit($replacement) @@ -1247,19 +1294,23 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str starts with $substring + * case-sensitivity + * @return bool Whether or not $str starts with $substring */ public function startsWith(string $substring, bool $caseSensitive = TRUE): bool { - $substringLength = \mb_strlen($substring, $this->encoding); - $startOfStr = \mb_substr($this->str, 0, $substringLength, - $this->encoding); + $substringLength = mb_strlen($substring, $this->encoding); + $startOfStr = mb_substr( + $this->str, + 0, + $substringLength, + $this->encoding + ); if ( ! $caseSensitive) { - $substring = \mb_strtolower($substring, $this->encoding); - $startOfStr = \mb_strtolower($startOfStr, $this->encoding); + $substring = mb_strtolower($substring, $this->encoding); + $startOfStr = mb_strtolower($startOfStr, $this->encoding); } return (string)$substring === $startOfStr; @@ -1272,8 +1323,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string[] $substrings Substrings to look for * @param bool $caseSensitive Whether or not to enforce - * case-sensitivity - * @return bool Whether or not $str starts with $substring + * case-sensitivity + * @return bool Whether or not $str starts with $substring */ public function startsWithAny(array $substrings, bool $caseSensitive = TRUE): bool { @@ -1303,7 +1354,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param int $end Optional index at which to end extraction * @return static Object with its $str being the extracted substring */ - public function slice(int $start, int $end = NULL): self + public function slice(int $start, ?int $end = NULL): self { if ($end === NULL) { @@ -1331,7 +1382,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param int $limit Optional maximum number of results to return * @return static[] An array of Stringy objects */ - public function split(string $pattern, int $limit = NULL): array + public function split(string $pattern, ?int $limit = NULL): array { if ($limit === 0) { @@ -1350,7 +1401,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { // mb_split returns the remaining unsplit string in the last index when // supplying a limit - $limit = ($limit > 0) ? $limit += 1 : -1; + $limit = ($limit > 0) ? ++$limit : -1; static $functionExists; if ($functionExists === NULL) @@ -1360,10 +1411,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { - $array = \mb_split($pattern, $this->str, $limit); - } else if ($this->supportsEncoding()) + $array = mb_split($pattern, $this->str, $limit); + } elseif ($this->supportsEncoding()) { - $array = \preg_split("/$pattern/", $this->str, $limit); + $array = \preg_split("/{$pattern}/", $this->str, $limit); } $this->regexEncoding($regexEncoding); @@ -1372,8 +1423,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { array_pop($array); } + $arrayCount = count($array); - for ($i = 0; $i < count($array); $i++) + for ($i = 0; $i < $arrayCount; $i++) { $array[$i] = static::create($array[$i], $this->encoding); } @@ -1405,7 +1457,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function substr(int $start, ?int $length = NULL): self { $length = $length === NULL ? $this->length() : $length; - $str = \mb_substr($this->str, $start, $length, $this->encoding); + $str = mb_substr($this->str, $start, $length, $this->encoding); return static::create($str, $this->encoding); } @@ -1415,7 +1467,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $substring The substring to add to both sides * @return static Object whose $str had the substring both prepended and - * appended + * appended */ public function surround(string $substring): self { @@ -1436,13 +1488,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[\S]/u', - function ($match) use ($encoding) { - if ($match[0] == \mb_strtoupper($match[0], $encoding)) + static function ($match) use ($encoding): string { + if ($match[0] === mb_strtoupper($match[0], $encoding)) { - return \mb_strtolower($match[0], $encoding); + return mb_strtolower($match[0], $encoding); } - return \mb_strtoupper($match[0], $encoding); + return mb_strtoupper($match[0], $encoding); }, $stringy->str ); @@ -1489,8 +1541,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/([\S]+)/u', - function ($match) use ($encoding, $ignore) { - if ($ignore && in_array($match[0], $ignore)) + static function ($match) use ($encoding, $ignore): string { + if ($ignore && in_array($match[0], $ignore, TRUE)) { return $match[0]; } @@ -1515,7 +1567,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param string $language Language of the source string * @param bool $removeUnsupported Whether or not to remove the - * unsupported characters + * unsupported characters * @return static Object whose $str contains only ASCII characters */ public function toAscii(string $language = 'en', bool $removeUnsupported = TRUE): self @@ -1563,15 +1615,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { 'false' => FALSE, '0' => FALSE, 'off' => FALSE, - 'no' => FALSE + 'no' => FALSE, ]; if (array_key_exists($key, $map)) { return $map[$key]; - } elseif (is_numeric($this->str)) + } + if (is_numeric($this->str)) { - return (intval($this->str) > 0); + return (int)($this->str) > 0; } return (bool)$this->regexReplace('[[:space:]]', '')->str; @@ -1585,7 +1638,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toLowerCase(): self { - $str = \mb_strtolower($this->str, $this->encoding); + $str = mb_strtolower($this->str, $this->encoding); return static::create($str, $this->encoding); } @@ -1628,7 +1681,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toTitleCase(): self { - $str = \mb_convert_case($this->str, \MB_CASE_TITLE, $this->encoding); + $str = mb_convert_case($this->str, MB_CASE_TITLE, $this->encoding); return static::create($str, $this->encoding); } @@ -1641,7 +1694,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function toUpperCase(): self { - $str = \mb_strtoupper($this->str, $this->encoding); + $str = mb_strtoupper($this->str, $this->encoding); return static::create($str, $this->encoding); } @@ -1658,7 +1711,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("^[$chars]+|[$chars]+\$", ''); + return $this->regexReplace("^[{$chars}]+|[{$chars}]+\$", ''); } /** @@ -1673,7 +1726,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("^[$chars]+", ''); + return $this->regexReplace("^[{$chars}]+", ''); } /** @@ -1688,7 +1741,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { $chars = ($chars) ? preg_quote($chars) : '[:space:]'; - return $this->regexReplace("[$chars]+\$", ''); + return $this->regexReplace("[{$chars}]+\$", ''); } /** @@ -1709,10 +1762,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } // Need to further trim the string so we can append the substring - $substringLength = \mb_strlen($substring, $stringy->encoding); + $substringLength = mb_strlen($substring, $stringy->encoding); $length = $length - $substringLength; - $truncated = \mb_substr($stringy->str, 0, $length, $stringy->encoding); + $truncated = mb_substr($stringy->str, 0, $length, $stringy->encoding); $stringy->str = $truncated . $substring; return $stringy; @@ -1750,11 +1803,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { */ public function upperCaseFirst(): self { - $first = \mb_substr($this->str, 0, 1, $this->encoding); - $rest = \mb_substr($this->str, 1, $this->length() - 1, - $this->encoding); + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr( + $this->str, + 1, + $this->length() - 1, + $this->encoding + ); - $str = \mb_strtoupper($first, $this->encoding) . $rest; + $str = mb_strtoupper($first, $this->encoding) . $rest; return static::create($str, $this->encoding); } @@ -1767,7 +1824,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { protected function charsArray(): array { static $charsArray; - if (isset($charsArray)) return $charsArray; + if (isset($charsArray)) + { + return $charsArray; + } return $charsArray = [ '0' => ['°', '₀', '۰', '0'], @@ -1940,7 +2000,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * will simply return 'a'. * * @param string $language Language of the source string - * @return array An array of replacements. + * @return array An array of replacements. */ protected static function langSpecificCharsArray(string $language = 'en'): array { @@ -1960,17 +2020,11 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { ], 'bg' => [ ['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'], - ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'] - ] + ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'], + ], ]; - if (isset($languageSpecific[$language])) - { - $charsArray[$language] = $languageSpecific[$language]; - } else - { - $charsArray[$language] = []; - } + $charsArray[$language] = isset($languageSpecific[$language]) ? $languageSpecific[$language] : []; return $charsArray[$language]; } @@ -1987,7 +2041,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { protected function applyPadding(int $left = 0, int $right = 0, string $padStr = ' '): self { $stringy = static::create($this->str, $this->encoding); - $length = \mb_strlen($padStr, $stringy->encoding); + $length = mb_strlen($padStr, $stringy->encoding); $strLength = $stringy->length(); $paddedLength = $strLength + $left + $right; @@ -1997,10 +2051,18 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { return $stringy; } - $leftPadding = \mb_substr(str_repeat($padStr, ceil($left / $length)), 0, - $left, $stringy->encoding); - $rightPadding = \mb_substr(str_repeat($padStr, ceil($right / $length)), - 0, $right, $stringy->encoding); + $leftPadding = mb_substr( + str_repeat($padStr, ceil($left / $length)), + 0, + $left, + $stringy->encoding + ); + $rightPadding = mb_substr( + str_repeat($padStr, ceil($right / $length)), + 0, + $right, + $stringy->encoding + ); $stringy->str = $leftPadding . $stringy->str . $rightPadding; @@ -2011,14 +2073,14 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * Returns true if $str matches the supplied pattern, false otherwise. * * @param string $pattern Regex pattern to match against - * @return bool Whether or not $str matches the pattern + * @return bool Whether or not $str matches the pattern */ protected function matchesPattern(string $pattern): bool { $regexEncoding = $this->regexEncoding(); $this->regexEncoding($this->encoding); - $match = \mb_ereg_match($pattern, $this->str); + $match = mb_ereg_match($pattern, $this->str); $this->regexEncoding($regexEncoding); return $match; @@ -2038,11 +2100,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { - return \mb_ereg_replace($pattern, $replacement, $string, $option); - } else if ($this->supportsEncoding()) + return mb_ereg_replace($pattern, $replacement, $string, $option); + } + if ($this->supportsEncoding()) { $option = str_replace('r', '', (string)$option); - return \preg_replace("/$pattern/u$option", $replacement, $string); + + return \preg_replace("/{$pattern}/u{$option}", $replacement, $string); } } @@ -2062,7 +2126,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { $args = func_get_args(); - return call_user_func_array('\mb_regex_encoding', $args); + + return mb_regex_encoding(...$args); } } @@ -2073,11 +2138,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if (isset($supported[$this->encoding])) { return TRUE; - } else - { - throw new \RuntimeException('Stringy method requires the ' . - 'mbstring module for encodings other than ASCII and UTF-8. ' . - 'Encoding used: ' . $this->encoding); } + + throw new RuntimeException('Stringy method requires the ' . + 'mbstring module for encodings other than ASCII and UTF-8. ' . + 'Encoding used: ' . $this->encoding); } } diff --git a/src/Ion/View/HttpView.php b/src/Ion/View/HttpView.php index 36f57653..f02076eb 100644 --- a/src/Ion/View/HttpView.php +++ b/src/Ion/View/HttpView.php @@ -20,6 +20,7 @@ use InvalidArgumentException; use Laminas\Diactoros\Response; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; +use PHPUnit\Framework\Attributes\CodeCoverageIgnore; use Psr\Http\Message\ResponseInterface; use Stringable; @@ -168,10 +169,10 @@ class HttpView implements HttpViewInterface, Stringable /** * Send the appropriate response * - * @codeCoverageIgnore * @throws DoubleRenderException * @throws InvalidArgumentException */ + #[CodeCoverageIgnore] protected function output(): void { if ($this->hasRendered) diff --git a/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php b/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php index b54673b4..4b5e45e1 100644 --- a/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php +++ b/tests/AnimeClient/API/Kitsu/Transformer/AnimeListTransformerTest.php @@ -46,7 +46,7 @@ final class AnimeListTransformerTest extends AnimeClientTestCase $this->assertMatchesSnapshot($actual); } - public function dataUntransform(): array + public static function dataUntransform(): array { return [[ 'input' => [ @@ -87,12 +87,10 @@ final class AnimeListTransformerTest extends AnimeClientTestCase ]]; } - /** - * @dataProvider dataUntransform - */ - public function testUntransform(array $input): void - { - $actual = $this->transformer->untransform($input); - $this->assertMatchesSnapshot($actual); - } + #[\PHPUnit\Framework\Attributes\DataProvider('dataUntransform')] + public function testUntransform(array $input): void + { + $actual = $this->transformer->untransform($input); + $this->assertMatchesSnapshot($actual); + } } diff --git a/tests/AnimeClient/DispatcherTest.php b/tests/AnimeClient/DispatcherTest.php index cb5e9839..d3a02428 100644 --- a/tests/AnimeClient/DispatcherTest.php +++ b/tests/AnimeClient/DispatcherTest.php @@ -71,7 +71,7 @@ final class DispatcherTest extends AnimeClientTestCase $this->assertIsObject($this->router); } - public function dataRoute(): array + public static function dataRoute(): array { $defaultConfig = [ 'routes' => [ @@ -141,35 +141,32 @@ final class DispatcherTest extends AnimeClientTestCase return $data; } - /** - * @dataProvider dataRoute - * @param mixed $config - * @param mixed $controller - * @param mixed $host - * @param mixed $uri - */ - public function testRoute($config, $controller, $host, $uri): void - { - $this->doSetUp($config, $uri, $host); + /** + * @param mixed $config + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataRoute')] + public function testRoute($config, mixed $controller, mixed $host, mixed $uri): void + { + $this->doSetUp($config, $uri, $host); - $request = $this->container->get('request'); + $request = $this->container->get('request'); - // Check route setup - $this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path'); - $this->assertIsArray($this->router->getOutputRoutes()); + // Check route setup + $this->assertSame($config['routes'], $this->config->get('routes'), 'Incorrect route path'); + $this->assertIsArray($this->router->getOutputRoutes()); - // Check environment variables - $this->assertSame($uri, $request->getServerParams()['REQUEST_URI']); - $this->assertSame($host, $request->getServerParams()['HTTP_HOST']); + // Check environment variables + $this->assertSame($uri, $request->getServerParams()['REQUEST_URI']); + $this->assertSame($host, $request->getServerParams()['HTTP_HOST']); - // Make sure the route is an anime type - //$this->assertTrue($matcher->count() > 0, '0 routes'); - $this->assertSame($controller, $this->router->getController(), 'Incorrect Route type'); + // Make sure the route is an anime type + //$this->assertTrue($matcher->count() > 0, '0 routes'); + $this->assertSame($controller, $this->router->getController(), 'Incorrect Route type'); - // Make sure the route matches, by checking that it is actually an object - $route = $this->router->getRoute(); - $this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched'); - } + // Make sure the route matches, by checking that it is actually an object + $route = $this->router->getRoute(); + $this->assertInstanceOf(Route::class, $route, 'Route is invalid, not matched'); + } public function testDefaultRoute(): void { @@ -209,53 +206,51 @@ final class DispatcherTest extends AnimeClientTestCase } #[ArrayShape(['controller_list_sanity_check' => 'array', 'empty_controller_list' => 'array'])] - public function dataGetControllerList(): array - { - $expectedList = [ - 'anime' => Controller\Anime::class, - 'anime-collection' => Controller\AnimeCollection::class, - 'character' => Controller\Character::class, - 'misc' => Controller\Misc::class, - 'manga' => Controller\Manga::class, - 'people' => Controller\People::class, - 'settings' => Controller\Settings::class, - 'user' => Controller\User::class, - 'images' => Controller\Images::class, - 'history' => Controller\History::class, - ]; +public static function dataGetControllerList(): array +{ + $expectedList = [ + 'anime' => Controller\Anime::class, + 'anime-collection' => Controller\AnimeCollection::class, + 'character' => Controller\Character::class, + 'misc' => Controller\Misc::class, + 'manga' => Controller\Manga::class, + 'people' => Controller\People::class, + 'settings' => Controller\Settings::class, + 'user' => Controller\User::class, + 'images' => Controller\Images::class, + 'history' => Controller\History::class, + ]; - return [ - 'controller_list_sanity_check' => [ - 'config' => [ - 'anime_path' => 'anime', - 'manga_path' => 'manga', - 'default_anime_list_path' => 'watching', - 'default_manga_list_path' => 'all', - 'default_list' => 'manga', - 'routes' => [], - ], - 'expected' => $expectedList, + return [ + 'controller_list_sanity_check' => [ + 'config' => [ + 'anime_path' => 'anime', + 'manga_path' => 'manga', + 'default_anime_list_path' => 'watching', + 'default_manga_list_path' => 'all', + 'default_list' => 'manga', + 'routes' => [], ], - 'empty_controller_list' => [ - 'config' => [ - 'anime_path' => 'anime', - 'manga_path' => 'manga', - 'default_anime_path' => '/anime/watching', - 'default_manga_path' => '/manga/all', - 'default_list' => 'manga', - 'routes' => [], - ], - 'expected' => $expectedList, + 'expected' => $expectedList, + ], + 'empty_controller_list' => [ + 'config' => [ + 'anime_path' => 'anime', + 'manga_path' => 'manga', + 'default_anime_path' => '/anime/watching', + 'default_manga_path' => '/manga/all', + 'default_list' => 'manga', + 'routes' => [], ], - ]; - } - - /** - * @dataProvider dataGetControllerList - */ - public function testGetControllerList(array $config, array $expected): void - { - $this->doSetUp($config, '/', 'localhost'); - $this->assertEquals($expected, $this->router->getControllerList()); - } + 'expected' => $expectedList, + ], + ]; +} + + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetControllerList')] + public function testGetControllerList(array $config, array $expected): void + { + $this->doSetUp($config, '/', 'localhost'); + $this->assertEquals($expected, $this->router->getControllerList()); + } } diff --git a/tests/AnimeClient/Helper/PictureHelperTest.php b/tests/AnimeClient/Helper/PictureHelperTest.php index 39f5a427..e8f2ed24 100644 --- a/tests/AnimeClient/Helper/PictureHelperTest.php +++ b/tests/AnimeClient/Helper/PictureHelperTest.php @@ -22,9 +22,7 @@ use Aviat\AnimeClient\Tests\AnimeClientTestCase; */ final class PictureHelperTest extends AnimeClientTestCase { - /** - * @dataProvider dataPictureCase - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataPictureCase')] public function testPictureHelper(array $params): void { $helper = new PictureHelper(); @@ -35,9 +33,7 @@ final class PictureHelperTest extends AnimeClientTestCase $this->assertMatchesSnapshot($actual); } - /** - * @dataProvider dataSimpleImageCase - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataSimpleImageCase')] public function testSimpleImage(string $ext, bool $isSimple, string $fallbackExt = 'jpg'): void { $helper = new PictureHelper(); @@ -61,7 +57,7 @@ final class PictureHelperTest extends AnimeClientTestCase $this->assertTrue( ! str_contains($actual, ' [ @@ -119,7 +115,7 @@ final class PictureHelperTest extends AnimeClientTestCase ]; } - public function dataSimpleImageCase(): array + public static function dataSimpleImageCase(): array { return [ 'avif' => [ diff --git a/tests/AnimeClient/KitsuTest.php b/tests/AnimeClient/KitsuTest.php index ccc216c4..2cd88eeb 100644 --- a/tests/AnimeClient/KitsuTest.php +++ b/tests/AnimeClient/KitsuTest.php @@ -77,7 +77,7 @@ final class KitsuTest extends TestCase $this->assertSame(AnimeAiringStatus::AIRING, Kitsu::getAiringStatus('yesterday')); } - public function getPublishingStatus(): array + public static function getPublishingStatus(): array { return [ 'current' => [ @@ -91,16 +91,14 @@ final class KitsuTest extends TestCase ]; } - /** - * @dataProvider getPublishingStatus - */ - public function testGetPublishingStatus(string $kitsuStatus, string $expected): void - { - $actual = Kitsu::getPublishingStatus($kitsuStatus); - $this->assertSame($expected, $actual); - } + #[\PHPUnit\Framework\Attributes\DataProvider('getPublishingStatus')] + public function testGetPublishingStatus(string $kitsuStatus, string $expected): void + { + $actual = Kitsu::getPublishingStatus($kitsuStatus); + $this->assertSame($expected, $actual); + } - public function getFriendlyTime(): array + public static function getFriendlyTime(): array { $SECONDS_IN_DAY = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_DAY; $SECONDS_IN_HOUR = Kitsu::SECONDS_IN_MINUTE * Kitsu::MINUTES_IN_HOUR; @@ -121,15 +119,13 @@ final class KitsuTest extends TestCase ]]; } - /** - * @dataProvider getFriendlyTime - */ - public function testGetFriendlyTime(int $seconds, string $expected): void - { - $actual = Kitsu::friendlyTime($seconds); + #[\PHPUnit\Framework\Attributes\DataProvider('getFriendlyTime')] + public function testGetFriendlyTime(int $seconds, string $expected): void + { + $actual = Kitsu::friendlyTime($seconds); - $this->assertSame($expected, $actual); - } + $this->assertSame($expected, $actual); + } public function testFilterLocalizedTitles(): void { diff --git a/tests/AnimeClient/RoutingBaseTest.php b/tests/AnimeClient/RoutingBaseTest.php index 0cabf77a..2669330d 100644 --- a/tests/AnimeClient/RoutingBaseTest.php +++ b/tests/AnimeClient/RoutingBaseTest.php @@ -23,7 +23,7 @@ use JetBrains\PhpStorm\ArrayShape; final class RoutingBaseTest extends AnimeClientTestCase { #[ArrayShape(['empty_segment' => 'array', 'three_segments' => 'array'])] - public function dataSegments() + public static function dataSegments() { return [ 'empty_segment' => [ @@ -41,26 +41,24 @@ final class RoutingBaseTest extends AnimeClientTestCase ]; } - /** - * @dataProvider dataSegments - */ - public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $requestUri, - ], - ]); + #[\PHPUnit\Framework\Attributes\DataProvider('dataSegments')] + public function testSegments(string $requestUri, string $path, array $segments, ?string $lastSegment): void + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $requestUri, + ], + ]); - $routingBase = new RoutingBase($this->container); + $routingBase = new RoutingBase($this->container); - $this->assertSame($path, $routingBase->path(), 'Path is invalid'); - $this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid'); - $this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid'); + $this->assertSame($path, $routingBase->path(), 'Path is invalid'); + $this->assertSame($segments, $routingBase->segments(), 'Segments array is invalid'); + $this->assertEquals($lastSegment, $routingBase->lastSegment(), 'Last segment is invalid'); - foreach ($segments as $i => $value) - { - $this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid"); - } - } + foreach ($segments as $i => $value) + { + $this->assertEquals($value, $routingBase->getSegment($i), "Segment {$i} is invalid"); + } + } } diff --git a/tests/AnimeClient/UrlGeneratorTest.php b/tests/AnimeClient/UrlGeneratorTest.php index 6e3d9fe2..715b2e7a 100644 --- a/tests/AnimeClient/UrlGeneratorTest.php +++ b/tests/AnimeClient/UrlGeneratorTest.php @@ -16,13 +16,14 @@ namespace Aviat\AnimeClient\Tests; use Aviat\AnimeClient\UrlGenerator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal */ final class UrlGeneratorTest extends AnimeClientTestCase { - public function assetUrlProvider() + public static function assetUrlProvider(): array { return [ 'single argument' => [ @@ -40,12 +41,8 @@ final class UrlGeneratorTest extends AnimeClientTestCase ]; } - /** - * @dataProvider assetUrlProvider - * @param mixed $args - * @param mixed $expected - */ - public function testAssetUrl($args, $expected) + #[DataProvider('assetUrlProvider')] + public function testAssetUrl(mixed $args, string $expected): void { $urlGenerator = new UrlGenerator($this->container); diff --git a/tests/AnimeClient/UtilTest.php b/tests/AnimeClient/UtilTest.php index 8aca3700..8b4c1658 100644 --- a/tests/AnimeClient/UtilTest.php +++ b/tests/AnimeClient/UtilTest.php @@ -47,7 +47,7 @@ final class UtilTest extends AnimeClientTestCase $this->assertSame('', Util::isNotSelected('foo', 'foo')); } - public function dataIsViewPage() + public static function dataIsViewPage() { return [ [ @@ -69,35 +69,34 @@ final class UtilTest extends AnimeClientTestCase ]; } - /** - * @dataProvider dataIsViewPage - * @param mixed $uri - * @param mixed $expected - */ - public function testIsViewPage($uri, $expected) - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $uri, - ], - ]); - $this->assertSame($expected, $this->util->isViewPage()); - } + /** + * @param mixed $uri + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')] + public function testIsViewPage($uri, mixed $expected) + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $uri, + ], + ]); + $this->assertSame($expected, $this->util->isViewPage()); + } - /** - * @dataProvider dataIsViewPage - * @param mixed $uri - * @param mixed $expected - */ - public function testIsFormPage($uri, $expected) - { - $this->setSuperGlobals([ - '_SERVER' => [ - 'REQUEST_URI' => $uri, - ], - ]); - $this->assertSame( ! $expected, $this->util->isFormPage()); - } + /** + * @param mixed $uri + * @param mixed $expected + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsViewPage')] + public function testIsFormPage($uri, $expected) + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $uri, + ], + ]); + $this->assertSame( ! $expected, $this->util->isFormPage()); + } public function testAriaCurrent(): void { diff --git a/tests/Ion/ConfigTest.php b/tests/Ion/ConfigTest.php index 203bb1b1..6bc26181 100644 --- a/tests/Ion/ConfigTest.php +++ b/tests/Ion/ConfigTest.php @@ -15,6 +15,7 @@ namespace Aviat\Ion\Tests; use Aviat\Ion\Config; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal @@ -67,7 +68,7 @@ final class ConfigTest extends IonTestCase $this->assertSame('great', $this->config->get(['apple', 'sauce', 'is']), 'Array argument get for config failed.'); } - public function dataConfigDelete(): array + public static function dataConfigDelete(): array { return [ 'top level delete' => [ @@ -124,11 +125,8 @@ final class ConfigTest extends IonTestCase ]; } - /** - * @dataProvider dataConfigDelete - * @param mixed $key - */ - public function testConfigDelete($key, array $assertKeys): void + #[DataProvider('dataConfigDelete')] + public function testConfigDelete(string|array $key, array $assertKeys): void { $config = new Config([]); $config->set(['apple', 'sauce', 'is'], 'great'); diff --git a/tests/Ion/Di/ContainerTest.php b/tests/Ion/Di/ContainerTest.php index d90d1aaf..2ae8130e 100644 --- a/tests/Ion/Di/ContainerTest.php +++ b/tests/Ion/Di/ContainerTest.php @@ -20,6 +20,7 @@ use Aviat\Ion\Di\{Container, ContainerAware}; use Aviat\Ion\Tests\IonTestCase; use Monolog\Handler\{NullHandler, TestHandler}; use Monolog\Logger; +use PHPUnit\Framework\Attributes\DataProvider; use Throwable; use TypeError; @@ -51,7 +52,7 @@ final class ContainerTest extends IonTestCase $this->container = new Container(); } - public function dataGetWithException(): array + public static function dataGetWithException(): array { return [ 'Bad index type: number' => [ @@ -71,9 +72,9 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataGetWithException * @param mixed $exception */ + #[DataProvider('dataGetWithException')] public function testGetWithException(mixed $id, $exception, ?string $message = NULL): void { try @@ -92,9 +93,9 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataGetWithException * @param mixed $exception */ + #[DataProvider('dataGetWithException')] public function testGetNewWithException(mixed $id, $exception, ?string $message = NULL): void { $this->expectException($exception); @@ -106,7 +107,7 @@ final class ContainerTest extends IonTestCase $this->container->getNew($id); } - public function dataSetInstanceWithException(): array + public static function dataSetInstanceWithException(): array { return [ 'Non-existent id' => [ @@ -123,11 +124,11 @@ final class ContainerTest extends IonTestCase } /** - * @dataProvider dataSetInstanceWithException * @param mixed $id * @param mixed $exception * @param mixed $message */ + #[DataProvider('dataSetInstanceWithException')] public function testSetInstanceWithException($id, $exception, $message): void { try diff --git a/tests/Ion/EnumTest.php b/tests/Ion/EnumTest.php index 382bd820..f5d9a5bf 100644 --- a/tests/Ion/EnumTest.php +++ b/tests/Ion/EnumTest.php @@ -19,6 +19,7 @@ namespace Aviat\Ion\Tests; */ final class EnumTest extends IonTestCase { + public $enum; protected $expectedConstList = [ 'FOO' => 'bar', 'BAR' => 'foo', @@ -43,7 +44,7 @@ final class EnumTest extends IonTestCase $this->assertSame($this->expectedConstList, $actual); } - public function dataIsValid() + public static function dataIsValid() { return [ 'Valid' => [ @@ -69,18 +70,17 @@ final class EnumTest extends IonTestCase ]; } - /** - * @dataProvider dataIsValid - * @param mixed $value - * @param mixed $expected - * @param mixed $static - */ - public function testIsValid($value, $expected, $static) - { - $actual = ($static) - ? TestEnum::isValid($value) - : $this->enum->isValid($value); + /** + * @param mixed $value + * @param mixed $static + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsValid')] + public function testIsValid($value, mixed $expected, $static) + { + $actual = ($static) + ? TestEnum::isValid($value) + : $this->enum->isValid($value); - $this->assertSame($expected, $actual); - } + $this->assertSame($expected, $actual); + } } diff --git a/tests/Ion/JsonTest.php b/tests/Ion/JsonTest.php index 48a14037..d58e24a8 100644 --- a/tests/Ion/JsonTest.php +++ b/tests/Ion/JsonTest.php @@ -32,7 +32,7 @@ final class JsonTest extends IonTestCase $this->assertSame($expected, Json::encode($data)); } - public function dataEncodeDecode(): array + public static function dataEncodeDecode(): array { return [ 'set1' => [ @@ -47,24 +47,22 @@ final class JsonTest extends IonTestCase ]; } - /** - * @dataProvider dataEncodeDecode - */ - public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void - { - $target_file = _dir(self::TEST_DATA_DIR, 'json_write.json'); + #[\PHPUnit\Framework\Attributes\DataProvider('dataEncodeDecode')] + public function testEncodeDecodeFile(array $data, int $expected_size, string $expected_json): void + { + $target_file = _dir(self::TEST_DATA_DIR, 'json_write.json'); - $actual_size = Json::encodeFile($target_file, $data); - $actual_json = file_get_contents($target_file); + $actual_size = Json::encodeFile($target_file, $data); + $actual_json = file_get_contents($target_file); - $this->assertTrue(Json::isJson($actual_json)); - $this->assertSame($expected_size, $actual_size); - $this->assertSame($expected_json, $actual_json); + $this->assertTrue(Json::isJson($actual_json)); + $this->assertSame($expected_size, $actual_size); + $this->assertSame($expected_json, $actual_json); - $this->assertEquals($data, Json::decodeFile($target_file)); + $this->assertEquals($data, Json::decodeFile($target_file)); - unlink($target_file); - } + unlink($target_file); + } public function testDecode() { diff --git a/tests/Ion/Transformer/AbstractTransformerTest.php b/tests/Ion/Transformer/AbstractTransformerTest.php index bb185151..bca18325 100644 --- a/tests/Ion/Transformer/AbstractTransformerTest.php +++ b/tests/Ion/Transformer/AbstractTransformerTest.php @@ -32,7 +32,7 @@ final class AbstractTransformerTest extends IonTestCase $this->untransformer = new TestTransformerUntransform(); } - public function dataTransformCollection() + public static function dataTransformCollection() { return [ 'object' => [ @@ -90,7 +90,7 @@ final class AbstractTransformerTest extends IonTestCase ]; } - public function dataUnTransformCollection() + public static function dataUnTransformCollection() { return [ 'object' => [ @@ -130,36 +130,34 @@ final class AbstractTransformerTest extends IonTestCase $this->assertSame($expected, $actual); } - /** - * @dataProvider dataTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testTransformCollection($original, $expected) - { - $actual = $this->transformer->transformCollection($original); - $this->assertSame($expected, $actual); - } + /** + * @param mixed $original + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataTransformCollection')] + public function testTransformCollection($original, mixed $expected) + { + $actual = $this->transformer->transformCollection($original); + $this->assertSame($expected, $actual); + } - /** - * @dataProvider dataUnTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testUntransformCollection($original, $expected) - { - $actual = $this->untransformer->untransformCollection($original); - $this->assertSame($expected, $actual); - } + /** + * @param mixed $original + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')] + public function testUntransformCollection($original, mixed $expected) + { + $actual = $this->untransformer->untransformCollection($original); + $this->assertSame($expected, $actual); + } - /** - * @dataProvider dataUnTransformCollection - * @param mixed $original - * @param mixed $expected - */ - public function testUntransformCollectionWithException($original, $expected) - { - $this->expectException(BadMethodCallException::class); - $this->transformer->untransformCollection($original); - } + /** + * @param mixed $original + * @param mixed $expected + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataUnTransformCollection')] + public function testUntransformCollectionWithException($original, $expected) + { + $this->expectException(BadMethodCallException::class); + $this->transformer->untransformCollection($original); + } } diff --git a/tests/Ion/Type/ArrayTypeTest.php b/tests/Ion/Type/ArrayTypeTest.php index b67a8667..027eb711 100644 --- a/tests/Ion/Type/ArrayTypeTest.php +++ b/tests/Ion/Type/ArrayTypeTest.php @@ -22,7 +22,7 @@ use Aviat\Ion\Type\ArrayType; */ final class ArrayTypeTest extends IonTestCase { - public function dataCall() + public static function dataCall() { $method_map = [ 'chunk' => 'array_chunk', @@ -80,18 +80,16 @@ final class ArrayTypeTest extends IonTestCase ]; } - /** - * Test the array methods defined for the __Call method - * - * @dataProvider dataCall - * @param $expected - */ - public function testCall(string $method, array $array, array $args, $expected): void - { - $obj = ArrayType::from($array); - $actual = $obj->__call($method, $args); - $this->assertSame($expected, $actual); - } + /** + * Test the array methods defined for the __Call method + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataCall')] + public function testCall(string $method, array $array, array $args, mixed $expected): void + { + $obj = ArrayType::from($array); + $actual = $obj->__call($method, $args); + $this->assertSame($expected, $actual); + } public function testSet(): void { diff --git a/tests/Ion/Type/StringTypeTest.php b/tests/Ion/Type/StringTypeTest.php index 869bca1f..8535e342 100644 --- a/tests/Ion/Type/StringTypeTest.php +++ b/tests/Ion/Type/StringTypeTest.php @@ -16,13 +16,14 @@ namespace Aviat\Ion\Tests\Type; use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Type\StringType; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal */ final class StringTypeTest extends IonTestCase { - public function dataFuzzyCaseMatch(): array + public static function dataFuzzyCaseMatch(): array { return [ 'space separated' => [ @@ -53,9 +54,7 @@ final class StringTypeTest extends IonTestCase ]; } - /** - * @dataProvider dataFuzzyCaseMatch - */ + #[DataProvider('dataFuzzyCaseMatch')] public function testFuzzyCaseMatch(string $str1, string $str2, bool $expected): void { $actual = StringType::from($str1)->fuzzyCaseMatch($str2); diff --git a/tools/composer.json b/tools/composer.json index 3e6d249f..d1d3c047 100644 --- a/tools/composer.json +++ b/tools/composer.json @@ -1,6 +1,6 @@ { "require": { "friendsofphp/php-cs-fixer": "^3.6", - "rector/rector": "^0.12.16" + "rector/rector": "^0.15.21" } } diff --git a/tools/header_comment.txt b/tools/header_comment.txt index b6560506..5e445e2b 100644 --- a/tools/header_comment.txt +++ b/tools/header_comment.txt @@ -3,11 +3,11 @@ * * An API client for Kitsu to manage anime and manga watch lists * - * PHP version 8 + * PHP version 8.1 * - * @copyright 2015 - 2022 Timothy J. Warren + * @copyright 2015 - 2023 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 5.2 - * @link https://git.timshome.page/timw4mail/HummingBirdAnimeClient + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient */ diff --git a/tools/offline-db-update.php b/tools/offline-db-update.php new file mode 100644 index 00000000..e69de29b diff --git a/tools/rector.php b/tools/rector.php index 23483ee0..e7bf177b 100644 --- a/tools/rector.php +++ b/tools/rector.php @@ -1,65 +1,54 @@ importNames(); + $config->importShortClasses(false); -return static function (ContainerConfigurator $config): void { - $parameters = $config->parameters(); - $parameters->set(Option::AUTO_IMPORT_NAMES, FALSE); - $parameters->set(Option::IMPORT_SHORT_CLASSES, FALSE); - $parameters->set(Option::SKIP, [ - ReadOnlyPropertyRector::class, - RestoreDefaultNullToNullableTypePropertyRector::class, + $config->sets([ + LevelSetList::UP_TO_PHP_81, + PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES, + PHPUnitSetList::PHPUNIT_100, ]); - walk_array([$config, 'import'], [ - LevelSetList::UP_TO_PHP_80, - ]); - - $services = $config->services(); - walk_array([$services, 'set'], [ + $config->rules([ AddArrayDefaultToArrayPropertyRector::class, - AddArrayParamDocTypeRector::class, - AddArrayReturnDocTypeRector::class, AddClosureReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, CallUserFuncArrayToVariadicRector::class, CallUserFuncToMethodCallRector::class, + CountArrayToEmptyArrayComparisonRector::class, ChangeIfElseValueAssignToEarlyReturnRector::class, ChangeNestedForeachIfsToEarlyContinueRector::class, CompleteDynamicPropertiesRector::class, @@ -67,7 +56,6 @@ return static function (ContainerConfigurator $config): void { CountArrayToEmptyArrayComparisonRector::class, ForRepeatedCountToOwnVariableRector::class, ForToForeachRector::class, - // MakeTypedPropertyNullableIfCheckedRector::class, // NewlineAfterStatementRector::class, NewlineBeforeNewAssignSetRector::class, ParamTypeByMethodCallTypeRector::class, @@ -79,13 +67,23 @@ return static function (ContainerConfigurator $config): void { RemoveUselessParamTagRector::class, RemoveUselessReturnTagRector::class, RemoveUselessVarTagRector::class, - // SimplifyDeMorganBinaryRector::class, - SimplifyDuplicatedTernaryRector::class, SimplifyIfElseToTernaryRector::class, SimplifyIfReturnBoolRector::class, SimplifyTautologyTernaryRector::class, + SymplifyQuoteEscapeRector::class, + StaticArrowFunctionRector::class, SwitchNegatedTernaryRector::class, TypedPropertyFromAssignsRector::class, + VersionCompareFuncCallToConstantRector::class, WrapEncapsedVariableInCurlyBracesRector::class, ]); + + $config->ruleWithConfiguration(OrderAttributesRector::class, [ + 'alphabetically', + ]); + + $config->skip([ + ReadOnlyPropertyRector::class, + RestoreDefaultNullToNullableTypePropertyRector::class, + ]); }; diff --git a/tools/update_header_comments.php b/tools/update_header_comments.php index 4850413c..72f5ca6b 100644 --- a/tools/update_header_comments.php +++ b/tools/update_header_comments.php @@ -39,7 +39,7 @@ function get_text_to_replace(array $tokens): string // [0] => token type constant // [1] => raw syntax parsed to that token // [2] => line number - foreach($tokens as $token) + foreach ($tokens as $token) { // Since we only care about opening docblocks, // bail out when we get to the namespace token @@ -81,9 +81,9 @@ function replace_file(string $file, string $template): void $files = array_filter( glob_recursive('*.php'), - fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/')) + static fn (string $file) => ! (str_contains($file, '/vendor/') || str_contains($file, '/tmp/')) ); -array_walk($files, fn (string $file) => replace_file($file, '/header_comment.txt')); +array_walk($files, static fn (string $file) => replace_file($file, '/header_comment.txt')); echo json_encode(array_values($files), JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . "\n"; printf("Successfully updated header comments in %d files\n", count($files)); From 0cff22099385fe265b321e3510a21ed59b9171a3 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Tue, 9 May 2023 12:49:36 -0400 Subject: [PATCH 04/18] Code style updates --- src/AnimeClient/API/Anilist/Model.php | 6 +- src/AnimeClient/API/Kitsu/Auth.php | 2 +- src/AnimeClient/API/Kitsu/Model.php | 1 + src/AnimeClient/API/Kitsu/MutationTrait.php | 3 - src/AnimeClient/API/ParallelAPIRequest.php | 2 +- src/AnimeClient/AnimeClient.php | 27 +--- src/AnimeClient/Command/BaseCommand.php | 4 +- src/AnimeClient/Command/SyncLists.php | 12 +- src/AnimeClient/Controller.php | 150 +++++++++--------- src/AnimeClient/Controller/Anime.php | 3 +- .../Controller/AnimeCollection.php | 5 +- src/AnimeClient/Controller/Character.php | 3 +- src/AnimeClient/Controller/History.php | 3 +- src/AnimeClient/Controller/Images.php | 3 +- src/AnimeClient/Controller/Manga.php | 7 +- src/AnimeClient/Controller/Misc.php | 6 +- src/AnimeClient/Controller/People.php | 3 +- src/AnimeClient/Controller/Settings.php | 3 +- src/AnimeClient/Controller/User.php | 3 +- src/AnimeClient/Dispatcher.php | 9 +- src/AnimeClient/Model/Settings.php | 9 +- src/AnimeClient/Types/AbstractType.php | 6 +- 22 files changed, 113 insertions(+), 157 deletions(-) diff --git a/src/AnimeClient/API/Anilist/Model.php b/src/AnimeClient/API/Anilist/Model.php index d5833c84..383ba619 100644 --- a/src/AnimeClient/API/Anilist/Model.php +++ b/src/AnimeClient/API/Anilist/Model.php @@ -189,7 +189,7 @@ final class Model */ public function deleteItem(FormItem $data, string $type): ?Request { - $mediaId = $this->getMediaId((array)$data, $type); + $mediaId = $this->getMediaId((array) $data, $type); if ($mediaId === NULL) { return NULL; @@ -209,7 +209,7 @@ final class Model */ public function getListIdFromData(FormItem $data, string $type = 'ANIME'): ?string { - $mediaId = $this->getMediaId((array)$data, $type); + $mediaId = $this->getMediaId((array) $data, $type); if ($mediaId === NULL) { return NULL; @@ -244,7 +244,7 @@ final class Model /** * Find the id to update by */ - private function getMediaId (array $data, string $type = 'ANIME'): ?string + private function getMediaId(array $data, string $type = 'ANIME'): ?string { if (isset($data['anilist_id'])) { diff --git a/src/AnimeClient/API/Kitsu/Auth.php b/src/AnimeClient/API/Kitsu/Auth.php index 342ee77f..8e302696 100644 --- a/src/AnimeClient/API/Kitsu/Auth.php +++ b/src/AnimeClient/API/Kitsu/Auth.php @@ -133,7 +133,7 @@ final class Auth /** * Save the new authentication information */ - private function storeAuth(array|FALSE $auth): bool + private function storeAuth(array|false $auth): bool { if (FALSE !== $auth) { diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index 6c72a635..b4cf554f 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -34,6 +34,7 @@ use Aviat\AnimeClient\API\{ use Aviat\AnimeClient\Enum\MediaType; use Aviat\AnimeClient\Kitsu as K; use Aviat\AnimeClient\Types\{Anime, MangaPage}; +use Aviat\AnimeClient\Types\{AnimeListItem, MangaListItem}; use Aviat\Ion\{ Di\ContainerAware, Json diff --git a/src/AnimeClient/API/Kitsu/MutationTrait.php b/src/AnimeClient/API/Kitsu/MutationTrait.php index 52cb84ea..1660a5ea 100644 --- a/src/AnimeClient/API/Kitsu/MutationTrait.php +++ b/src/AnimeClient/API/Kitsu/MutationTrait.php @@ -67,9 +67,6 @@ trait MutationTrait /** * Remove a list item - * - * @param FormItem $data - * @return Request */ public function deleteItem(FormItem $data): Request { diff --git a/src/AnimeClient/API/ParallelAPIRequest.php b/src/AnimeClient/API/ParallelAPIRequest.php index 6af3b7b2..b2a3cf4f 100644 --- a/src/AnimeClient/API/ParallelAPIRequest.php +++ b/src/AnimeClient/API/ParallelAPIRequest.php @@ -35,7 +35,7 @@ final class ParallelAPIRequest /** * Add a request */ - public function addRequest(string|Request $request, string|int|NULL $key = NULL): self + public function addRequest(string|Request $request, string|int|null $key = NULL): self { if ($key !== NULL) { diff --git a/src/AnimeClient/AnimeClient.php b/src/AnimeClient/AnimeClient.php index 819eb4dd..2a07674e 100644 --- a/src/AnimeClient/AnimeClient.php +++ b/src/AnimeClient/AnimeClient.php @@ -17,6 +17,7 @@ namespace Aviat\AnimeClient; use Amp\Http\Client\{HttpClient, HttpClientBuilder, Request, Response}; use Aviat\Ion\{ConfigInterface, ImageBuilder}; +use PHPUnit\Framework\Attributes\CodeCoverageIgnore; use Psr\SimpleCache\CacheInterface; use Throwable; @@ -31,9 +32,9 @@ use function Aviat\Ion\_dir; /** * Load configuration options from .toml files * - * @codeCoverageIgnore * @param string $path - Path to load config */ +#[CodeCoverageIgnore] function loadConfig(string $path): array { $output = []; @@ -72,9 +73,8 @@ function loadConfig(string $path): array /** * Load config from one specific TOML file - * - * @codeCoverageIgnore */ +#[CodeCoverageIgnore] function loadTomlFile(string $filename): array { return Toml::parseFile($filename); @@ -131,19 +131,6 @@ function tomlToArray(string $toml): array //! Misc Functions // ---------------------------------------------------------------------------- -if ( ! function_exists('array_is_list')) -{ - /** - * Polyfill for PHP 8 - * - * @see https://www.php.net/manual/en/function.array-is-list - */ - function array_is_list(array $a): bool - { - return $a === [] || (array_keys($a) === range(0, count($a) - 1)); - } -} - /** * Is the array sequential, not associative? */ @@ -256,9 +243,8 @@ function getLocalImg(string $kitsuUrl, bool $webp = TRUE): string /** * Create a transparent placeholder image - * - * @codeCoverageIgnore */ +#[CodeCoverageIgnore] function createPlaceholderImage(string $path, int $width = 200, int $height = 200, string $text = 'Image Unavailable'): bool { $img = ImageBuilder::new($width, $height) @@ -303,16 +289,15 @@ function clearCache(CacheInterface $cache): bool $cleared = $cache->clear(); - $saved = (empty($userData)) ? TRUE : $cache->setMultiple($userData); + $saved = empty($userData) || $cache->setMultiple($userData); return $cleared && $saved; } /** * Render a PHP code template as a string - * - * @codeCoverageIgnore */ +#[CodeCoverageIgnore] function renderTemplate(string $path, array $data): string { ob_start(); diff --git a/src/AnimeClient/Command/BaseCommand.php b/src/AnimeClient/Command/BaseCommand.php index 6da5f206..62e73846 100644 --- a/src/AnimeClient/Command/BaseCommand.php +++ b/src/AnimeClient/Command/BaseCommand.php @@ -44,7 +44,7 @@ abstract class BaseCommand extends Command /** * Echo text in a box */ - public function echoBox(string|array $message, string|int|NULL $fgColor = NULL, string|int|NULL $bgColor = NULL): void + public function echoBox(string|array $message, string|int|null $fgColor = NULL, string|int|null $bgColor = NULL): void { if (is_array($message)) { @@ -131,7 +131,7 @@ abstract class BaseCommand extends Command return $this->_di($configArray, $APP_DIR); } - private function _line(string $message, int|string|NULL $fgColor = NULL, int|string|NULL $bgColor = NULL): void + private function _line(string $message, int|string|null $fgColor = NULL, int|string|null $bgColor = NULL): void { if ($fgColor !== NULL) { diff --git a/src/AnimeClient/Command/SyncLists.php b/src/AnimeClient/Command/SyncLists.php index d73ba1b8..d2d897d3 100644 --- a/src/AnimeClient/Command/SyncLists.php +++ b/src/AnimeClient/Command/SyncLists.php @@ -98,21 +98,23 @@ final class SyncLists extends BaseCommand if ( ! $anilistEnabled) { $this->echoErrorBox('Anlist API is not enabled. Can not sync.'); - return false; + + return FALSE; } // Authentication is required to update Kitsu $isKitsuAuthenticated = $this->container->get('auth')->isAuthenticated(); - if ( !$isKitsuAuthenticated) + if ( ! $isKitsuAuthenticated) { $this->echoErrorBox('Kitsu is not authenticated. Kitsu list can not be updated.'); - return false; + + return FALSE; } $this->anilistModel = $this->container->get('anilist-model'); $this->kitsuModel = $this->container->get('kitsu-model'); - return true; + return TRUE; } /** @@ -148,7 +150,7 @@ final class SyncLists extends BaseCommand */ protected function fetch(string $type): array { - $this->echo("Fetching $type List Data"); + $this->echo("Fetching {$type} List Data"); $progress = new Widgets\ProgressBar($this->getConsole(), 2, 50, FALSE); $anilist = $this->fetchAnilist($type); diff --git a/src/AnimeClient/Controller.php b/src/AnimeClient/Controller.php index b0beb7e0..b7363d9d 100644 --- a/src/AnimeClient/Controller.php +++ b/src/AnimeClient/Controller.php @@ -121,13 +121,13 @@ class Controller } /** - * Set the current url in the session as the target of a future redirect - * - * @codeCoverageIgnore - * @throws ContainerException - * @throws NotFoundException - */ - public function setSessionRedirect(?string $url = NULL): void + * Set the current url in the session as the target of a future redirect + * + * @throws ContainerException + * @throws NotFoundException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function setSessionRedirect(?string $url = NULL): void { $serverParams = $this->request->getServerParams(); @@ -159,14 +159,14 @@ class Controller } /** - * Redirect to the url previously set in the session - * - * If one is not set, redirect to default url - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - public function sessionRedirect(): void + * Redirect to the url previously set in the session + * + * If one is not set, redirect to default url + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function sessionRedirect(): void { $target = $this->session->get('redirect_url') ?? '/'; @@ -175,10 +175,10 @@ class Controller } /** - * Check if the current user is authenticated, else error and exit - * @codeCoverageIgnore - */ - protected function checkAuth(): void + * Check if the current user is authenticated, else error and exit + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function checkAuth(): void { if ( ! $this->auth->isAuthenticated()) { @@ -191,11 +191,10 @@ class Controller } /** - * Get the string output of a partial template - * - * @codeCoverageIgnore - */ - protected function loadPartial(HtmlView $view, string $template, array $data = []): string + * Get the string output of a partial template + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function loadPartial(HtmlView $view, string $template, array $data = []): string { $router = $this->container->get('dispatcher'); @@ -218,11 +217,10 @@ class Controller } /** - * Render a template with header and footer - * - * @codeCoverageIgnore - */ - protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView + * Render a template with header and footer + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView { $csp = [ "default-src 'self' media.kitsu.io kitsu-production-media.s3.us-west-002.backblazeb2.com", @@ -245,12 +243,12 @@ class Controller } /** - * 404 action - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - public function notFound( + * 404 action + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function notFound( string $title = 'Sorry, page not found', string $message = 'Page Not Found' ): void { @@ -263,12 +261,12 @@ class Controller } /** - * Display a generic error page - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - public function errorPage(int $httpCode, string $title, string $message, string $longMessage = ''): void + * Display a generic error page + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function errorPage(int $httpCode, string $title, string $message, string $longMessage = ''): void { $this->outputHTML('error', [ 'title' => $title, @@ -278,24 +276,23 @@ class Controller } /** - * Redirect to the default controller/url from an empty path - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - public function redirectToDefaultRoute(): void + * Redirect to the default controller/url from an empty path + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function redirectToDefaultRoute(): void { $defaultType = $this->config->get('default_list'); $this->redirect($this->urlGenerator->defaultUrl($defaultType), 303); } /** - * Set a session flash variable to display a message on - * next page load - * - * @codeCoverageIgnore - */ - public function setFlashMessage(string $message, string $type = 'info'): void + * Set a session flash variable to display a message on + * next page load + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + public function setFlashMessage(string $message, string $type = 'info'): void { static $messages; @@ -323,12 +320,12 @@ class Controller } /** - * Add a message box to the page - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - protected function showMessage(HtmlView $view, string $type, string $message): string + * Add a message box to the page + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function showMessage(HtmlView $view, string $type, string $message): string { return $this->loadPartial($view, 'message', [ 'message_type' => $type, @@ -337,12 +334,12 @@ class Controller } /** - * Output a template to HTML, using the provided data - * - * @codeCoverageIgnore - * @throws InvalidArgumentException - */ - protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void + * Output a template to HTML, using the provided data + * + * @throws InvalidArgumentException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void { if (NULL === $view) { @@ -354,13 +351,13 @@ class Controller } /** - * Output a JSON Response - * - * @codeCoverageIgnore - * @param int $code - the http status code - * @throws DoubleRenderException - */ - protected function outputJSON(mixed $data, int $code): void + * Output a JSON Response + * + * @param int $code - the http status code + * @throws DoubleRenderException + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function outputJSON(mixed $data, int $code): void { JsonView::new() ->setOutput($data) @@ -369,11 +366,10 @@ class Controller } /** - * Redirect to the selected page - * - * @codeCoverageIgnore - */ - protected function redirect(string $url, int $code): void + * Redirect to the selected page + */ + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + protected function redirect(string $url, int $code): void { HttpView::new() ->redirect($url, $code) diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index a29e1abd..be4c807d 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -21,8 +21,7 @@ use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Model\Anime as AnimeModel; use Aviat\AnimeClient\Types\FormItem; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Json; diff --git a/src/AnimeClient/Controller/AnimeCollection.php b/src/AnimeClient/Controller/AnimeCollection.php index 5577eda9..26400a64 100644 --- a/src/AnimeClient/Controller/AnimeCollection.php +++ b/src/AnimeClient/Controller/AnimeCollection.php @@ -20,11 +20,9 @@ use Aviat\AnimeClient\Model\{ Anime as AnimeModel, AnimeCollection as AnimeCollectionModel }; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; -use Aviat\Ion\Json; use Aviat\Ion\Exception\DoubleRenderException; use InvalidArgumentException; @@ -114,7 +112,6 @@ final class AnimeCollection extends BaseController /** * Show the anime collection add/edit form * - * @param int|null $id * @throws ContainerException * @throws InvalidArgumentException * @throws NotFoundException diff --git a/src/AnimeClient/Controller/Character.php b/src/AnimeClient/Controller/Character.php index 1bb5466e..cc0685e6 100644 --- a/src/AnimeClient/Controller/Character.php +++ b/src/AnimeClient/Controller/Character.php @@ -18,8 +18,7 @@ use Aviat\AnimeClient\API\Kitsu\Model; use Aviat\AnimeClient\API\Kitsu\Transformer\CharacterTransformer; use Aviat\AnimeClient\Controller as BaseController; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; diff --git a/src/AnimeClient/Controller/History.php b/src/AnimeClient/Controller/History.php index 9f654ea4..583c35b8 100644 --- a/src/AnimeClient/Controller/History.php +++ b/src/AnimeClient/Controller/History.php @@ -14,9 +14,8 @@ namespace Aviat\AnimeClient\Controller; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; use Aviat\AnimeClient\{Controller as BaseController, Model}; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; diff --git a/src/AnimeClient/Controller/Images.php b/src/AnimeClient/Controller/Images.php index 20c9eccd..0abbb1ec 100644 --- a/src/AnimeClient/Controller/Images.php +++ b/src/AnimeClient/Controller/Images.php @@ -15,8 +15,7 @@ namespace Aviat\AnimeClient\Controller; use Aviat\AnimeClient\Controller as BaseController; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Throwable; use function Amp\Promise\wait; use function Aviat\AnimeClient\{createPlaceholderImage, getResponse}; diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index 5ab92bc2..cd69a825 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -14,21 +14,16 @@ namespace Aviat\AnimeClient\Controller; -use Aura\Router\Exception\RouteNotFound; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Model\Manga as MangaModel; use Aviat\AnimeClient\Types\FormItem; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Json; -use InvalidArgumentException; -use Throwable; - /** * Controller for manga list */ diff --git a/src/AnimeClient/Controller/Misc.php b/src/AnimeClient/Controller/Misc.php index 1f4ac47d..f4ba9fe2 100644 --- a/src/AnimeClient/Controller/Misc.php +++ b/src/AnimeClient/Controller/Misc.php @@ -15,12 +15,10 @@ namespace Aviat\AnimeClient\Controller; use Aviat\AnimeClient\API\Kitsu\Model; -use Aviat\AnimeClient\API\Kitsu\Transformer\CharacterTransformer; -use Aviat\AnimeClient\API\Kitsu\Transformer\PersonTransformer; +use Aviat\AnimeClient\API\Kitsu\Transformer\{CharacterTransformer, PersonTransformer}; use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Enum\EventType; -use Aviat\Ion\Attribute\DefaultController; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{DefaultController, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Event; use Aviat\Ion\View\HtmlView; diff --git a/src/AnimeClient/Controller/People.php b/src/AnimeClient/Controller/People.php index e142c0e6..5e7db3db 100644 --- a/src/AnimeClient/Controller/People.php +++ b/src/AnimeClient/Controller/People.php @@ -18,8 +18,7 @@ use Aviat\AnimeClient\API\Kitsu\Model; use Aviat\AnimeClient\API\Kitsu\Transformer\PersonTransformer; use Aviat\AnimeClient\Controller as BaseController; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; diff --git a/src/AnimeClient/Controller/Settings.php b/src/AnimeClient/Controller/Settings.php index 325f0861..a5ffe601 100644 --- a/src/AnimeClient/Controller/Settings.php +++ b/src/AnimeClient/Controller/Settings.php @@ -18,8 +18,7 @@ use Aura\Router\Exception\RouteNotFound; use Aviat\AnimeClient\API\Anilist\Model as AnilistModel; use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\Model\Settings as SettingsModel; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; diff --git a/src/AnimeClient/Controller/User.php b/src/AnimeClient/Controller/User.php index 3bc6ad20..4a0268d6 100644 --- a/src/AnimeClient/Controller/User.php +++ b/src/AnimeClient/Controller/User.php @@ -18,8 +18,7 @@ use Aviat\AnimeClient\API\Kitsu\Model; use Aviat\AnimeClient\API\Kitsu\Transformer\UserTransformer; use Aviat\AnimeClient\Controller as BaseController; -use Aviat\Ion\Attribute\Controller; -use Aviat\Ion\Attribute\Route; +use Aviat\Ion\Attribute\{Controller, Route}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php index 3d0ab117..b278091d 100644 --- a/src/AnimeClient/Dispatcher.php +++ b/src/AnimeClient/Dispatcher.php @@ -317,14 +317,15 @@ final class Dispatcher extends RoutingBase $params = []; - switch ($failure->failedRule) { + switch ($failure->failedRule) + { case Rule\Allows::class: $params = [ 'http_code' => 405, 'title' => '405 Method Not Allowed', 'message' => 'Invalid HTTP Verb', ]; - break; + break; case Rule\Accepts::class: $params = [ @@ -332,12 +333,12 @@ final class Dispatcher extends RoutingBase 'title' => '406 Not Acceptable', 'message' => 'Unacceptable content type', ]; - break; + break; default: // Fall back to a 404 message $actionMethod = NOT_FOUND_METHOD; - break; + break; } return [ diff --git a/src/AnimeClient/Model/Settings.php b/src/AnimeClient/Model/Settings.php index 83d10832..40df895e 100644 --- a/src/AnimeClient/Model/Settings.php +++ b/src/AnimeClient/Model/Settings.php @@ -95,14 +95,7 @@ final class Settings } } - if (array_key_exists($key, $values) && is_scalar($values[$key])) - { - $value['value'] = $values[$key]; - } - else - { - $value['value'] = $value['default'] ?? ''; - } + $value['value'] = array_key_exists($key, $values) && is_scalar($values[$key]) ? $values[$key] : $value['default'] ?? ''; foreach (['readonly', 'disabled'] as $flag) { diff --git a/src/AnimeClient/Types/AbstractType.php b/src/AnimeClient/Types/AbstractType.php index dce78ad0..a49d532d 100644 --- a/src/AnimeClient/Types/AbstractType.php +++ b/src/AnimeClient/Types/AbstractType.php @@ -201,10 +201,8 @@ abstract class AbstractType implements ArrayAccess, Countable, Stringable return TRUE; } - /** - * @codeCoverageIgnore - */ - final protected function fromObject(mixed $parent = NULL): float|NULL|bool|int|array|string + #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] + final protected function fromObject(mixed $parent = NULL): float|null|bool|int|array|string { $object = $parent ?? $this; From b13c35eaec36f06674034a0cf485c0e3b3a35a9f Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Tue, 9 May 2023 12:52:11 -0400 Subject: [PATCH 05/18] More code style updates --- .php-cs-fixer.dist.php | 42 ++-- src/AnimeClient/Controller.php | 290 ++++++++++++------------- src/AnimeClient/Dispatcher.php | 62 +++--- src/AnimeClient/FormGenerator.php | 6 +- src/AnimeClient/MenuGenerator.php | 26 +-- src/AnimeClient/Types/AbstractType.php | 92 ++++---- src/Ion/Type/ArrayType.php | 16 +- src/Ion/Type/Stringy.php | 80 ++++--- tools/rector.php | 10 +- 9 files changed, 314 insertions(+), 310 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 37df8f9a..c00fa4d1 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -5,22 +5,12 @@ use PhpCsFixer\{Config, Finder}; $finder = Finder::create() ->in([ - __DIR__, - __DIR__ . '/app', + __DIR__ . '/src', + __DIR__ . '/tests', __DIR__ . '/tools', ]) ->exclude([ - 'apidocs', - 'build', - 'coverage', - 'frontEndSrc', - 'phinx', - 'public', - 'tools', - 'tmp', 'vendor', - 'views', - 'templates', ]); return (new Config()) @@ -45,7 +35,7 @@ return (new Config()) 'blank_line_after_opening_tag' => false, 'blank_line_before_statement' => [ 'statements' => [ - 'case', + // 'case', 'continue', 'declare', 'default', @@ -128,12 +118,12 @@ return (new Config()) 'noise_remaining_usages_exclude' => [], ], 'escape_implicit_backslashes' => [ - 'double_quoted' => true, - 'heredoc_syntax' => true, + 'double_quoted' => false, + 'heredoc_syntax' => false, 'single_quoted' => false, ], - 'explicit_indirect_variable' => true, - 'explicit_string_variable' => true, + 'explicit_indirect_variable' => false, + 'explicit_string_variable' => false, 'final_class' => false, 'final_internal_class' => [ 'annotation_exclude' => ['@no-final'], @@ -167,7 +157,7 @@ return (new Config()) ], 'group_import' => true, 'header_comment' => false, // false by default - 'heredoc_indentation' => ['indentation' => 'start_plus_one'], + // 'heredoc_indentation' => ['indentation' => 'start_plus_one'], 'heredoc_to_nowdoc' => true, 'implode_call' => true, 'include' => true, @@ -232,8 +222,7 @@ return (new Config()) 'allow_unused_params' => true, 'remove_inheritdoc' => false, ], - 'no_trailing_comma_in_list_call' => true, - 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_comma_in_singleline' => true, 'no_trailing_whitespace' => true, 'no_trailing_whitespace_in_comment' => true, 'no_trailing_whitespace_in_string' => true, @@ -270,9 +259,16 @@ return (new Config()) 'ordered_class_elements' => [ 'order' => [ 'use_trait', - 'constant', - 'property', - 'method', + 'case', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public', + 'property_protected', + 'property_private', + 'construct', + 'destruct', + 'magic', ], 'sort_algorithm' => 'none', ], diff --git a/src/AnimeClient/Controller.php b/src/AnimeClient/Controller.php index b7363d9d..275076e6 100644 --- a/src/AnimeClient/Controller.php +++ b/src/AnimeClient/Controller.php @@ -42,6 +42,11 @@ class Controller { use ContainerAware; + /** + * The global configuration object + */ + public ConfigInterface $config; + /** * The authentication object */ @@ -52,11 +57,6 @@ class Controller */ protected CacheInterface $cache; - /** - * The global configuration object - */ - public ConfigInterface $config; - /** * Request object */ @@ -120,7 +120,7 @@ class Controller Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->cache->delete($key)); } - /** + /** * Set the current url in the session as the target of a future redirect * * @throws ContainerException @@ -128,37 +128,37 @@ class Controller */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function setSessionRedirect(?string $url = NULL): void - { - $serverParams = $this->request->getServerParams(); + { + $serverParams = $this->request->getServerParams(); - if ( ! array_key_exists('HTTP_REFERER', $serverParams)) - { - return; - } + if ( ! array_key_exists('HTTP_REFERER', $serverParams)) + { + return; + } - $util = $this->container->get('util'); - $doubleFormPage = $serverParams['HTTP_REFERER'] === $this->request->getUri(); - $isLoginPage = str_contains($serverParams['HTTP_REFERER'], 'login'); + $util = $this->container->get('util'); + $doubleFormPage = $serverParams['HTTP_REFERER'] === $this->request->getUri(); + $isLoginPage = str_contains($serverParams['HTTP_REFERER'], 'login'); - // Don't attempt to set the redirect url if - // the page is one of the form type pages, - // and the previous page is also a form type - if ($doubleFormPage || $isLoginPage) - { - return; - } + // Don't attempt to set the redirect url if + // the page is one of the form type pages, + // and the previous page is also a form type + if ($doubleFormPage || $isLoginPage) + { + return; + } - if (NULL === $url) - { - $url = $util->isViewPage() - ? (string) $this->request->getUri() - : $serverParams['HTTP_REFERER']; - } + if (NULL === $url) + { + $url = $util->isViewPage() + ? (string) $this->request->getUri() + : $serverParams['HTTP_REFERER']; + } - $this->session->set('redirect_url', $url); - } + $this->session->set('redirect_url', $url); + } - /** + /** * Redirect to the url previously set in the session * * If one is not set, redirect to default url @@ -167,147 +167,147 @@ class Controller */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function sessionRedirect(): void - { - $target = $this->session->get('redirect_url') ?? '/'; + { + $target = $this->session->get('redirect_url') ?? '/'; - $this->redirect($target, 303); - $this->session->set('redirect_url', NULL); - } + $this->redirect($target, 303); + $this->session->set('redirect_url', NULL); + } - /** + /** * Check if the current user is authenticated, else error and exit */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function checkAuth(): void - { - if ( ! $this->auth->isAuthenticated()) - { - $this->errorPage( - 403, - 'Forbidden', - 'You must log in to perform this action.' - ); - } - } + { + if ( ! $this->auth->isAuthenticated()) + { + $this->errorPage( + 403, + 'Forbidden', + 'You must log in to perform this action.' + ); + } + } - /** + /** * Get the string output of a partial template */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function loadPartial(HtmlView $view, string $template, array $data = []): string - { - $router = $this->container->get('dispatcher'); + { + $router = $this->container->get('dispatcher'); - if (isset($this->baseData)) - { - $data = array_merge($this->baseData, $data); - } + if (isset($this->baseData)) + { + $data = array_merge($this->baseData, $data); + } - $route = $router->getRoute(); - $data['route_path'] = $route !== FALSE ? $route->path : ''; + $route = $router->getRoute(); + $data['route_path'] = $route !== FALSE ? $route->path : ''; - $templatePath = _dir($this->config->get('view_path'), "{$template}.php"); + $templatePath = _dir($this->config->get('view_path'), "{$template}.php"); - if ( ! is_file($templatePath)) - { - throw new InvalidArgumentException("Invalid template : {$template}"); - } + if ( ! is_file($templatePath)) + { + throw new InvalidArgumentException("Invalid template : {$template}"); + } - return $view->renderTemplate($templatePath, $data); - } + return $view->renderTemplate($templatePath, $data); + } - /** + /** * Render a template with header and footer */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function renderFullPage(HtmlView $view, string $template, array $data): HtmlView - { - $csp = [ - "default-src 'self' media.kitsu.io kitsu-production-media.s3.us-west-002.backblazeb2.com", - "object-src 'none'", - "child-src 'self' *.youtube.com polyfill.io", - ]; + { + $csp = [ + "default-src 'self' media.kitsu.io kitsu-production-media.s3.us-west-002.backblazeb2.com", + "object-src 'none'", + "child-src 'self' *.youtube.com polyfill.io", + ]; - $view->addHeader('Content-Security-Policy', implode('; ', $csp)); - $view->appendOutput($this->loadPartial($view, 'header', $data)); + $view->addHeader('Content-Security-Policy', implode('; ', $csp)); + $view->appendOutput($this->loadPartial($view, 'header', $data)); - if (array_key_exists('message', $data) && is_array($data['message'])) - { - $view->appendOutput($this->loadPartial($view, 'message', $data['message'])); - } + if (array_key_exists('message', $data) && is_array($data['message'])) + { + $view->appendOutput($this->loadPartial($view, 'message', $data['message'])); + } - $view->appendOutput($this->loadPartial($view, $template, $data)); - $view->appendOutput($this->loadPartial($view, 'footer', $data)); + $view->appendOutput($this->loadPartial($view, $template, $data)); + $view->appendOutput($this->loadPartial($view, 'footer', $data)); - return $view; - } + return $view; + } - /** + /** * 404 action * * @throws InvalidArgumentException */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function notFound( - string $title = 'Sorry, page not found', - string $message = 'Page Not Found' - ): void { - $this->outputHTML('404', [ - 'title' => $title, - 'message' => $message, - ], NULL, 404); + string $title = 'Sorry, page not found', + string $message = 'Page Not Found' + ): void { + $this->outputHTML('404', [ + 'title' => $title, + 'message' => $message, + ], NULL, 404); - exit(); - } + exit(); + } - /** + /** * Display a generic error page * * @throws InvalidArgumentException */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function errorPage(int $httpCode, string $title, string $message, string $longMessage = ''): void - { - $this->outputHTML('error', [ - 'title' => $title, - 'message' => $message, - 'long_message' => $longMessage, - ], NULL, $httpCode); - } + { + $this->outputHTML('error', [ + 'title' => $title, + 'message' => $message, + 'long_message' => $longMessage, + ], NULL, $httpCode); + } - /** + /** * Redirect to the default controller/url from an empty path * * @throws InvalidArgumentException */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function redirectToDefaultRoute(): void - { - $defaultType = $this->config->get('default_list'); - $this->redirect($this->urlGenerator->defaultUrl($defaultType), 303); - } + { + $defaultType = $this->config->get('default_list'); + $this->redirect($this->urlGenerator->defaultUrl($defaultType), 303); + } - /** + /** * Set a session flash variable to display a message on * next page load */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] public function setFlashMessage(string $message, string $type = 'info'): void - { - static $messages; + { + static $messages; - if ( ! $messages) - { - $messages = []; - } + if ( ! $messages) + { + $messages = []; + } - $messages[] = [ - 'message_type' => $type, - 'message' => $message, - ]; + $messages[] = [ + 'message_type' => $type, + 'message' => $message, + ]; - $this->session->setFlash('message', $messages); - } + $this->session->setFlash('message', $messages); + } /** * Helper for consistent page titles @@ -319,38 +319,38 @@ class Controller return implode(' · ', $parts); } - /** + /** * Add a message box to the page * * @throws InvalidArgumentException */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function showMessage(HtmlView $view, string $type, string $message): string - { - return $this->loadPartial($view, 'message', [ - 'message_type' => $type, - 'message' => $message, - ]); - } + { + return $this->loadPartial($view, 'message', [ + 'message_type' => $type, + 'message' => $message, + ]); + } - /** + /** * Output a template to HTML, using the provided data * * @throws InvalidArgumentException */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function outputHTML(string $template, array $data = [], ?HtmlView $view = NULL, int $code = 200): void - { - if (NULL === $view) - { - $view = new HtmlView($this->container); - } + { + if (NULL === $view) + { + $view = new HtmlView($this->container); + } - $view->setStatusCode($code); - $this->renderFullPage($view, $template, $data)->send(); - } + $view->setStatusCode($code); + $this->renderFullPage($view, $template, $data)->send(); + } - /** + /** * Output a JSON Response * * @param int $code - the http status code @@ -358,23 +358,23 @@ class Controller */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function outputJSON(mixed $data, int $code): void - { - JsonView::new() - ->setOutput($data) - ->setStatusCode($code) - ->send(); - } + { + JsonView::new() + ->setOutput($data) + ->setStatusCode($code) + ->send(); + } - /** + /** * Redirect to the selected page */ #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] protected function redirect(string $url, int $code): void - { - HttpView::new() - ->redirect($url, $code) - ->send(); - } + { + HttpView::new() + ->redirect($url, $code) + ->send(); + } } // End of BaseController.php diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php index b278091d..230a0a61 100644 --- a/src/AnimeClient/Dispatcher.php +++ b/src/AnimeClient/Dispatcher.php @@ -69,37 +69,6 @@ final class Dispatcher extends RoutingBase $this->outputRoutes = $this->setupRoutes(); } - /** - * Get the current route object, if one matches - */ - public function getRoute(): Route|false - { - $logger = $this->container->getLogger(); - - $rawRoute = $this->request->getUri()->getPath(); - $routePath = '/' . trim($rawRoute, '/'); - - if ($logger !== NULL) - { - $logger->info('Dispatcher - Routing data from get_route method'); - $logger->info(print_r([ - 'route_path' => $routePath, - ], TRUE)); - } - - return $this->matcher->match($this->request); - } - - /** - * Get list of routes applied - * - * @return mixed[] - */ - public function getOutputRoutes(): array - { - return $this->outputRoutes; - } - /** * Handle the current route * @@ -141,6 +110,37 @@ final class Dispatcher extends RoutingBase $this->call($controllerName, $actionMethod, $params); } + /** + * Get the current route object, if one matches + */ + public function getRoute(): Route|false + { + $logger = $this->container->getLogger(); + + $rawRoute = $this->request->getUri()->getPath(); + $routePath = '/' . trim($rawRoute, '/'); + + if ($logger !== NULL) + { + $logger->info('Dispatcher - Routing data from get_route method'); + $logger->info(print_r([ + 'route_path' => $routePath, + ], TRUE)); + } + + return $this->matcher->match($this->request); + } + + /** + * Get list of routes applied + * + * @return mixed[] + */ + public function getOutputRoutes(): array + { + return $this->outputRoutes; + } + /** * Parse out the arguments for the appropriate controller for * the current route diff --git a/src/AnimeClient/FormGenerator.php b/src/AnimeClient/FormGenerator.php index 182476a7..ccf67960 100644 --- a/src/AnimeClient/FormGenerator.php +++ b/src/AnimeClient/FormGenerator.php @@ -83,16 +83,16 @@ final class FormGenerator ]; $params['strict'] = TRUE; unset($params['attribs']['id']); - break; + break; case 'string': $params['type'] = 'text'; - break; + break; case 'select': $params['type'] = 'select'; $params['options'] = array_flip($form['options']); - break; + break; default: break; diff --git a/src/AnimeClient/MenuGenerator.php b/src/AnimeClient/MenuGenerator.php index 5941e228..9d43d62a 100644 --- a/src/AnimeClient/MenuGenerator.php +++ b/src/AnimeClient/MenuGenerator.php @@ -36,6 +36,19 @@ final class MenuGenerator extends UrlGenerator */ protected ServerRequestInterface $request; + /** + * MenuGenerator constructor. + * + * @throws ContainerException + * @throws NotFoundException + */ + private function __construct(ContainerInterface $container) + { + parent::__construct($container); + $this->helper = $container->get('html-helper'); + $this->request = $container->get('request'); + } + public static function new(ContainerInterface $container): self { return new self($container); @@ -80,19 +93,6 @@ final class MenuGenerator extends UrlGenerator return (string) $this->helper->ul(); } - /** - * MenuGenerator constructor. - * - * @throws ContainerException - * @throws NotFoundException - */ - private function __construct(ContainerInterface $container) - { - parent::__construct($container); - $this->helper = $container->get('html-helper'); - $this->request = $container->get('request'); - } - /** * Generate the full menu structure from the config files * diff --git a/src/AnimeClient/Types/AbstractType.php b/src/AnimeClient/Types/AbstractType.php index a49d532d..81ddca5c 100644 --- a/src/AnimeClient/Types/AbstractType.php +++ b/src/AnimeClient/Types/AbstractType.php @@ -20,37 +20,6 @@ use Stringable; abstract class AbstractType implements ArrayAccess, Countable, Stringable { - /** - * Populate values for un-serializing data - */ - public static function __set_state(mixed $properties): self - { - return new static($properties); - } - - /** - * Check the shape of the object, and return the array equivalent - */ - final public static function check(array $data = []): ?array - { - $currentClass = static::class; - - if (get_parent_class($currentClass) !== FALSE) - { - return static::class::from($data)->toArray(); - } - - return NULL; - } - - /** - * Static constructor - */ - final public static function from(mixed $data): static - { - return new static($data); - } - /** * Sets the properties by using the constructor */ @@ -73,6 +42,14 @@ abstract class AbstractType implements ArrayAccess, Countable, Stringable } } + /** + * Populate values for un-serializing data + */ + public static function __set_state(mixed $properties): self + { + return new static($properties); + } + /** * See if a property is set */ @@ -123,6 +100,29 @@ abstract class AbstractType implements ArrayAccess, Countable, Stringable return print_r($this, TRUE); } + /** + * Check the shape of the object, and return the array equivalent + */ + final public static function check(array $data = []): ?array + { + $currentClass = static::class; + + if (get_parent_class($currentClass) !== FALSE) + { + return static::class::from($data)->toArray(); + } + + return NULL; + } + + /** + * Static constructor + */ + final public static function from(mixed $data): static + { + return new static($data); + } + /** * Implementing ArrayAccess */ @@ -203,23 +203,23 @@ abstract class AbstractType implements ArrayAccess, Countable, Stringable #[\PHPUnit\Framework\Attributes\CodeCoverageIgnore] final protected function fromObject(mixed $parent = NULL): float|null|bool|int|array|string - { - $object = $parent ?? $this; + { + $object = $parent ?? $this; - if (is_scalar($object) || $object === NULL) - { - return $object; - } + if (is_scalar($object) || $object === NULL) + { + return $object; + } - $output = []; + $output = []; - foreach ($object as $key => $value) - { - $output[$key] = (is_scalar($value) || empty($value)) - ? $value - : $this->fromObject((array) $value); - } + foreach ($object as $key => $value) + { + $output[$key] = (is_scalar($value) || empty($value)) + ? $value + : $this->fromObject((array) $value); + } - return $output; - } + return $output; + } } diff --git a/src/Ion/Type/ArrayType.php b/src/Ion/Type/ArrayType.php index 4766c48f..27e3b712 100644 --- a/src/Ion/Type/ArrayType.php +++ b/src/Ion/Type/ArrayType.php @@ -65,14 +65,6 @@ class ArrayType 'pop' => 'array_pop', ]; - /** - * Create an ArrayType wrapper class from an array - */ - public static function from(array $arr): ArrayType - { - return new ArrayType($arr); - } - /** * Create an ArrayType wrapper class */ @@ -108,6 +100,14 @@ class ArrayType throw new InvalidArgumentException("Method '{$method}' does not exist"); } + /** + * Create an ArrayType wrapper class from an array + */ + public static function from(array $arr): ArrayType + { + return new ArrayType($arr); + } + /** * Does the passed key exist in the current array? */ diff --git a/src/Ion/Type/Stringy.php b/src/Ion/Type/Stringy.php index 2aab130a..5491b6db 100644 --- a/src/Ion/Type/Stringy.php +++ b/src/Ion/Type/Stringy.php @@ -41,7 +41,8 @@ use const MB_CASE_TITLE; /** * Vendored, slightly modernized version of Stringy */ -abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { +abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess +{ /** * An instance's string. */ @@ -80,10 +81,20 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { ); } - $this->str = (string)$str; + $this->str = (string) $str; $this->encoding = $encoding ?: mb_internal_encoding(); } + /** + * Returns the value in $str. + * + * @return string The current value of the $str property + */ + public function __toString(): string + { + return $this->str; + } + /** * Creates a Stringy object and assigns both str and encoding properties * the supplied values. $str is cast to a string prior to assignment, and if @@ -93,25 +104,15 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * * @param mixed $str Value to modify, after being cast to string * @param string|null $encoding The character encoding - * @return static A Stringy object * @throws InvalidArgumentException if an array or object without a * __toString method is passed as the first argument + * @return static A Stringy object */ public static function create(mixed $str = '', ?string $encoding = NULL): self { return new static($str, $encoding); } - /** - * Returns the value in $str. - * - * @return string The current value of the $str property - */ - public function __toString(): string - { - return $this->str; - } - /** * Returns a new string with $string appended. * @@ -190,7 +191,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy->str = preg_replace_callback( '/[\d]+(.)?/u', - static fn($match) => mb_strtoupper($match[0], $encoding), + static fn ($match) => mb_strtoupper($match[0], $encoding), $stringy->str ); @@ -395,7 +396,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $endOfStr = mb_strtolower($endOfStr, $this->encoding); } - return (string)$substring === $endOfStr; + return (string) $substring === $endOfStr; } /** @@ -585,8 +586,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { return \mb_strpos( $this->str, - (string)$needle, - (int)$offset, + (string) $needle, + (int) $offset, $this->encoding ); } @@ -605,8 +606,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { { return mb_strrpos( $this->str, - (string)$needle, - (int)$offset, + (string) $needle, + (int) $offset, $this->encoding ); } @@ -813,7 +814,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($char === mb_substr($otherStr, $i, 1, $encoding)) { $longestCommonPrefix .= $char; - } else + } + else { break; } @@ -842,7 +844,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($char === mb_substr($otherStr, -$i, 1, $encoding)) { $longestCommonSuffix = $char . $longestCommonSuffix; - } else + } + else { break; } @@ -898,7 +901,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $len = $table[$i][$j]; $end = $i; } - } else + } + else { $table[$i][$j] = 0; } @@ -941,7 +945,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { public function offsetExists(mixed $offset): bool { $length = $this->length(); - $offset = (int)$offset; + $offset = (int) $offset; if ($offset >= 0) { @@ -958,13 +962,13 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * does not exist. * * @param mixed $offset The index from which to retrieve the char - * @return string The character at the specified index * @throws OutOfBoundsException If the positive or negative offset does * not exist + * @return string The character at the specified index */ public function offsetGet(mixed $offset): string { - $offset = (int)$offset; + $offset = (int) $offset; $length = $this->length(); if (($offset >= 0 && $length <= $offset) || $length < abs($offset)) @@ -1012,9 +1016,9 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { * @param int $length Desired string length after padding * @param string $padStr String used to pad, defaults to space * @param string $padType One of 'left', 'right', 'both' - * @return static Object with a padded $str * @throws /InvalidArgumentException If $padType isn't one of 'right', * 'left' or 'both' + * @return static Object with a padded $str */ public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self { @@ -1313,7 +1317,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $startOfStr = mb_strtolower($startOfStr, $this->encoding); } - return (string)$substring === $startOfStr; + return (string) $substring === $startOfStr; } /** @@ -1359,13 +1363,16 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($end === NULL) { $length = $this->length(); - } elseif ($end >= 0 && $end <= $start) + } + elseif ($end >= 0 && $end <= $start) { return static::create('', $this->encoding); - } elseif ($end < 0) + } + elseif ($end < 0) { $length = $this->length() + $end - $start; - } else + } + else { $length = $end - $start; } @@ -1412,7 +1419,8 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { if ($functionExists) { $array = mb_split($pattern, $this->str, $limit); - } elseif ($this->supportsEncoding()) + } + elseif ($this->supportsEncoding()) { $array = \preg_split("/{$pattern}/", $this->str, $limit); } @@ -1549,7 +1557,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { $stringy = static::create($match[0], $encoding); - return (string)$stringy->toLowerCase()->upperCaseFirst(); + return (string) $stringy->toLowerCase()->upperCaseFirst(); }, $stringy->str ); @@ -1624,10 +1632,10 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } if (is_numeric($this->str)) { - return (int)($this->str) > 0; + return (int) ($this->str) > 0; } - return (bool)$this->regexReplace('[[:space:]]', '')->str; + return (bool) $this->regexReplace('[[:space:]]', '')->str; } /** @@ -2024,7 +2032,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { ], ]; - $charsArray[$language] = isset($languageSpecific[$language]) ? $languageSpecific[$language] : []; + $charsArray[$language] = $languageSpecific[$language] ?? []; return $charsArray[$language]; } @@ -2104,7 +2112,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess { } if ($this->supportsEncoding()) { - $option = str_replace('r', '', (string)$option); + $option = str_replace('r', '', (string) $option); return \preg_replace("/{$pattern}/u{$option}", $replacement, $string); } diff --git a/tools/rector.php b/tools/rector.php index e7bf177b..8550f720 100644 --- a/tools/rector.php +++ b/tools/rector.php @@ -3,10 +3,6 @@ use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; use Rector\CodeQuality\Rector\For_\{ForRepeatedCountToOwnVariableRector, ForToForeachRector}; use Rector\CodeQuality\Rector\If_\{ConsecutiveNullCompareReturnsToNullCoalesceQueueRector, SimplifyIfElseToTernaryRector, SimplifyIfReturnBoolRector}; -use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector; -use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector; -use Rector\Php81\Rector\Property\ReadOnlyPropertyRector; -use Rector\Set\ValueObject\LevelSetList; use Rector\CodeQuality\Rector\Ternary\{SimplifyTautologyTernaryRector, SwitchNegatedTernaryRector}; use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector; use Rector\CodingStyle\Rector\Class_\AddArrayDefaultToArrayPropertyRector; @@ -19,6 +15,7 @@ use Rector\CodingStyle\Rector\FuncCall\ CountArrayToEmptyArrayComparisonRector, VersionCompareFuncCallToConstantRector}; use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector; +use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector; use Rector\Config\RectorConfig; use Rector\DeadCode\Rector\ClassMethod\{RemoveUselessParamTagRector, RemoveUselessReturnTagRector}; use Rector\DeadCode\Rector\Foreach_\RemoveUnusedForeachKeyRector; @@ -26,7 +23,10 @@ use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector; use Rector\DeadCode\Rector\Switch_\RemoveDuplicatedCaseInSwitchRector; use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector; use Rector\EarlyReturn\Rector\If_\{ChangeIfElseValueAssignToEarlyReturnRector, RemoveAlwaysElseRector}; +use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector; +use Rector\Php81\Rector\Property\ReadOnlyPropertyRector; use Rector\PHPUnit\Set\PHPUnitSetList; +use Rector\Set\ValueObject\LevelSetList; use Rector\TypeDeclaration\Rector\ClassMethod\{AddMethodCallBasedStrictParamTypeRector, ParamTypeByMethodCallTypeRector, ParamTypeByParentCallTypeRector}; use Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector; use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; @@ -34,7 +34,7 @@ use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; return static function (RectorConfig $config): void { // Import names with use statements $config->importNames(); - $config->importShortClasses(false); + $config->importShortClasses(FALSE); $config->sets([ LevelSetList::UP_TO_PHP_81, From cbff3867343c10bcfc13b187308a406d71bed4d6 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 18 May 2023 12:55:38 -0400 Subject: [PATCH 06/18] Add specific locale arguments to keep up with the API --- app/views/character/details.php | 2 +- app/views/person/details.php | 3 +++ src/AnimeClient/API/Kitsu/Model.php | 6 +++--- .../API/Kitsu/Queries/AnimeDetails.graphql | 10 +++++----- .../API/Kitsu/Queries/AnimeDetailsById.graphql | 10 +++++----- .../API/Kitsu/Queries/CharacterDetails.graphql | 12 ++++++------ .../API/Kitsu/Queries/GetLibrary.graphql | 2 +- .../API/Kitsu/Queries/GetLibraryItem.graphql | 4 ++-- .../API/Kitsu/Queries/GetUserHistory.graphql | 2 +- .../API/Kitsu/Queries/MangaDetails.graphql | 4 ++-- .../API/Kitsu/Queries/MangaDetailsById.graphql | 4 ++-- .../API/Kitsu/Queries/PersonDetails.graphql | 8 ++++---- .../API/Kitsu/Queries/RandomMedia.graphql | 8 ++++---- .../API/Kitsu/Queries/SearchAnime.graphql | 2 +- .../API/Kitsu/Queries/SearchManga.graphql | 2 +- .../API/Kitsu/Queries/UserDetails.graphql | 11 ++++++----- .../API/Kitsu/Transformer/AnimeTransformer.php | 3 ++- .../API/Kitsu/Transformer/PersonTransformer.php | 10 ++++++++-- src/AnimeClient/Kitsu.php | 13 +++++++++++-- src/AnimeClient/Model/MediaTrait.php | 2 +- src/AnimeClient/Types/Person.php | 1 + 21 files changed, 70 insertions(+), 49 deletions(-) diff --git a/app/views/character/details.php b/app/views/character/details.php index 0a0977a7..9e0baa34 100644 --- a/app/views/character/details.php +++ b/app/views/character/details.php @@ -26,7 +26,7 @@ use Aviat\AnimeClient\Kitsu;

-

', $data['description']) ?>

+

diff --git a/app/views/person/details.php b/app/views/person/details.php index b3c362c6..eb06775a 100644 --- a/app/views/person/details.php +++ b/app/views/person/details.php @@ -8,6 +8,9 @@

+ +

+

diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index b4cf554f..018aea92 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -535,14 +535,14 @@ final class Model * Get the data for a specific list item, generally for editing * * @param string $listId - The unique identifier of that list item - * @return mixed */ - public function getListItem(string $listId) + public function getListItem(string $listId): AnimeListItem|MangaListItem|array { $baseData = $this->listItem->get($listId); if ( ! isset($baseData['data']['findLibraryEntryById'])) { - return []; + // We need to get the errors... + return $baseData; } return (new LibraryEntryTransformer())->transform($baseData['data']['findLibraryEntryById']); diff --git a/src/AnimeClient/API/Kitsu/Queries/AnimeDetails.graphql b/src/AnimeClient/API/Kitsu/Queries/AnimeDetails.graphql index 793028d7..ea57178c 100644 --- a/src/AnimeClient/API/Kitsu/Queries/AnimeDetails.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/AnimeDetails.graphql @@ -19,7 +19,7 @@ query ($slug: String!) { } categories(first: 100) { nodes { - title + title(locales: "en") } } characters(first: 100) { @@ -29,7 +29,7 @@ query ($slug: String!) { names { alternatives canonical - localized + localized(locales: "*") } image { original { @@ -50,7 +50,7 @@ query ($slug: String!) { startCursor } } - description + description(locales: "en") startDate endDate episodeCount @@ -87,7 +87,7 @@ query ($slug: String!) { names { alternatives canonical - localized + localized(locales: "*") } slug } @@ -118,7 +118,7 @@ query ($slug: String!) { alternatives canonical canonicalLocale - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } totalLength youtubeTrailerVideoId diff --git a/src/AnimeClient/API/Kitsu/Queries/AnimeDetailsById.graphql b/src/AnimeClient/API/Kitsu/Queries/AnimeDetailsById.graphql index a3b2bc0d..e39e9a6d 100644 --- a/src/AnimeClient/API/Kitsu/Queries/AnimeDetailsById.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/AnimeDetailsById.graphql @@ -19,7 +19,7 @@ query ($id: ID!) { } categories(first: 100) { nodes { - title + title(locales: "en") } } characters(first: 100) { @@ -29,7 +29,7 @@ query ($id: ID!) { names { alternatives canonical - localized + localized(locales: "*") } image { original { @@ -50,7 +50,7 @@ query ($id: ID!) { startCursor } } - description + description(locales: "en") startDate endDate episodeCount @@ -87,7 +87,7 @@ query ($id: ID!) { names { alternatives canonical - localized + localized(locales: "*") } slug } @@ -118,7 +118,7 @@ query ($id: ID!) { alternatives canonical canonicalLocale - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } totalLength youtubeTrailerVideoId diff --git a/src/AnimeClient/API/Kitsu/Queries/CharacterDetails.graphql b/src/AnimeClient/API/Kitsu/Queries/CharacterDetails.graphql index 587ae3c8..54768910 100644 --- a/src/AnimeClient/API/Kitsu/Queries/CharacterDetails.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/CharacterDetails.graphql @@ -6,12 +6,12 @@ query ($slug: String!) { url } } - description + description(locales: "en") names { alternatives canonical canonicalLocale - localized + localized(locales: "*") }, media(first: 100) { nodes { @@ -22,7 +22,7 @@ query ($slug: String!) { alternatives canonical canonicalLocale - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } posterImage { original { @@ -41,7 +41,7 @@ query ($slug: String!) { type } role - voices(first: 10) { + voices(first: 10, locale:"*", sort:{direction:ASCENDING, on: UPDATED_AT}) { nodes { id locale @@ -53,7 +53,7 @@ query ($slug: String!) { alternatives canonical canonicalLocale - localized + localized(locales: "*") } image { original { @@ -70,4 +70,4 @@ query ($slug: String!) { } slug } -} \ No newline at end of file +} diff --git a/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql b/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql index f2dd3bdd..8d34ccb1 100644 --- a/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql @@ -57,7 +57,7 @@ query ( type titles { canonical - localized + localized(locales: "*") alternatives } ...on Anime { diff --git a/src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql b/src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql index e970eeb5..0d96fb56 100644 --- a/src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/GetLibraryItem.graphql @@ -16,7 +16,7 @@ query($id: ID!) { ageRating categories(first: 100) { nodes { - title + title(locales: "*") } } mappings(first: 10) { @@ -41,7 +41,7 @@ query($id: ID!) { endDate titles { canonical - localized + localized(locales: "*") canonicalLocale } type diff --git a/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql b/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql index 78eca809..9418c22a 100644 --- a/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql @@ -33,7 +33,7 @@ query ($slug: String!) { titles { alternatives canonical - localized + localized(locales: "*") } ...on Anime { episodeCount diff --git a/src/AnimeClient/API/Kitsu/Queries/MangaDetails.graphql b/src/AnimeClient/API/Kitsu/Queries/MangaDetails.graphql index 9393aeff..7422c360 100644 --- a/src/AnimeClient/API/Kitsu/Queries/MangaDetails.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/MangaDetails.graphql @@ -19,7 +19,7 @@ query ($slug: String!) { } categories(first: 100) { nodes { - title + title(locales: "*") } } chapterCount @@ -116,7 +116,7 @@ query ($slug: String!) { titles { canonical canonicalLocale - localized + localized(locales: "*") } } } diff --git a/src/AnimeClient/API/Kitsu/Queries/MangaDetailsById.graphql b/src/AnimeClient/API/Kitsu/Queries/MangaDetailsById.graphql index 09a3aab6..6b8b129b 100644 --- a/src/AnimeClient/API/Kitsu/Queries/MangaDetailsById.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/MangaDetailsById.graphql @@ -19,7 +19,7 @@ query ($id: ID!) { } categories(first: 100) { nodes { - title + title(locales: "*") } } chapterCount @@ -116,7 +116,7 @@ query ($id: ID!) { titles { canonical canonicalLocale - localized + localized(locales: "*") } } } diff --git a/src/AnimeClient/API/Kitsu/Queries/PersonDetails.graphql b/src/AnimeClient/API/Kitsu/Queries/PersonDetails.graphql index 9830a947..9cd02d4b 100644 --- a/src/AnimeClient/API/Kitsu/Queries/PersonDetails.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/PersonDetails.graphql @@ -1,7 +1,7 @@ query ($slug: String!) { findPersonBySlug(slug: $slug) { id - description + description(locales: "en") birthday image { original { @@ -20,7 +20,7 @@ query ($slug: String!) { names { alternatives canonical - localized + localized(locales: "*") } mediaStaff(first: 100) { nodes { @@ -47,7 +47,7 @@ query ($slug: String!) { titles { alternatives canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } } } @@ -91,7 +91,7 @@ query ($slug: String!) { } titles { canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } } } diff --git a/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql b/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql index 63e19476..c0194711 100644 --- a/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql @@ -26,7 +26,7 @@ query ($type: MediaTypeEnum!) { } categories(first: 100) { nodes { - title + title(locales: "*") } } characters(first: 100) { @@ -36,7 +36,7 @@ query ($type: MediaTypeEnum!) { names { alternatives canonical - localized + localized(locales: "*") } image { original { @@ -90,7 +90,7 @@ query ($type: MediaTypeEnum!) { names { alternatives canonical - localized + localized(locales: "*") } slug } @@ -108,7 +108,7 @@ query ($type: MediaTypeEnum!) { alternatives canonical canonicalLocale - localized + localized(locales: "*") } ...on Anime { episodeCount diff --git a/src/AnimeClient/API/Kitsu/Queries/SearchAnime.graphql b/src/AnimeClient/API/Kitsu/Queries/SearchAnime.graphql index a91b6c6f..eda7a3d0 100644 --- a/src/AnimeClient/API/Kitsu/Queries/SearchAnime.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/SearchAnime.graphql @@ -19,7 +19,7 @@ query ($query: String!) { slug titles { canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) alternatives } myLibraryEntry { diff --git a/src/AnimeClient/API/Kitsu/Queries/SearchManga.graphql b/src/AnimeClient/API/Kitsu/Queries/SearchManga.graphql index 0e4bb4c6..687b78c1 100644 --- a/src/AnimeClient/API/Kitsu/Queries/SearchManga.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/SearchManga.graphql @@ -19,7 +19,7 @@ query ($query: String!) { slug titles { canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) alternatives } myLibraryEntry { diff --git a/src/AnimeClient/API/Kitsu/Queries/UserDetails.graphql b/src/AnimeClient/API/Kitsu/Queries/UserDetails.graphql index 492cb6a6..401cc12b 100644 --- a/src/AnimeClient/API/Kitsu/Queries/UserDetails.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/UserDetails.graphql @@ -52,7 +52,7 @@ query ($slug: String!) { } titles { canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } } ...on Manga { @@ -72,7 +72,7 @@ query ($slug: String!) { } titles { canonical - localized + localized(locales: ["en", "en-t-ja", "ja", "ja-jp"]) } } ...on Person { @@ -88,11 +88,12 @@ query ($slug: String!) { width } } + name, names { alternatives canonical canonicalLocale - localized + localized(locales: "*") }, } ...on Character { @@ -107,12 +108,12 @@ query ($slug: String!) { height width } - } + }, names { alternatives canonical canonicalLocale - localized + localized(locales: "*") }, } } diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php index 24baa11a..6bfa2e91 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php @@ -36,7 +36,8 @@ final class AnimeTransformer extends AbstractTransformer $characters = []; $links = []; $staff = []; - $genres = array_map(static fn ($genre) => $genre['title']['en'], $base['categories']['nodes']); + $rawGenres = array_filter($base['categories']['nodes'], static fn ($c) => $c !== null); + $genres = array_map(static fn ($genre) => $genre['title']['en'], $rawGenres); sort($genres); diff --git a/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php index ae966ebe..e8c8eadb 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/PersonTransformer.php @@ -35,6 +35,7 @@ final class PersonTransformer extends AbstractTransformer return Person::from([ 'id' => $data['id'], 'name' => $canonicalName, + 'birthday' => $data['birthday'], 'image' => $data['image']['original']['url'], 'names' => array_diff($data['names']['localized'], [$canonicalName]), 'description' => $data['description']['en'] ?? '', @@ -97,7 +98,12 @@ final class PersonTransformer extends AbstractTransformer { foreach ($data['voices']['nodes'] as $voicing) { - $character = $voicing['mediaCharacter']['character']; + if ($voicing === null) + { + continue; + } + + $character = $voicing['mediaCharacter']['character'] ?? []; $charId = $character['id']; $rawMedia = $voicing['mediaCharacter']['media']; $role = strtolower($voicing['mediaCharacter']['role']); @@ -123,7 +129,7 @@ final class PersonTransformer extends AbstractTransformer 'character' => [ 'id' => $character['id'], 'slug' => $character['slug'], - 'image' => $character['image']['original']['url'], + 'image' => $character['image']['original']['url'] ?? '', 'canonicalName' => $character['names']['canonical'], ], 'media' => [ diff --git a/src/AnimeClient/Kitsu.php b/src/AnimeClient/Kitsu.php index e249c68e..b3525936 100644 --- a/src/AnimeClient/Kitsu.php +++ b/src/AnimeClient/Kitsu.php @@ -305,7 +305,16 @@ final class Kitsu { // Really don't care about languages that aren't english // or Japanese for titles - if ( ! in_array($locale, ['en', 'en_us', 'en_jp', 'ja_jp'], TRUE)) + if ( ! in_array($locale, [ + 'en', + 'en-jp', + 'en-us', + 'en_jp', + 'en_us', + 'ja-jp', + 'ja_jp', + 'jp', + ], TRUE)) { continue; } @@ -486,7 +495,7 @@ final class Kitsu foreach ($existingTitles as $existing) { - $isSubset = mb_substr_count($existing, $title) > 0; + $isSubset = mb_substr_count(mb_strtolower($existing), mb_strtolower($title)) > 0; $diff = levenshtein(mb_strtolower($existing), mb_strtolower($title)); if ($diff <= 4 || $isSubset || mb_strlen($title) > 45 || mb_strlen($existing) > 50) diff --git a/src/AnimeClient/Model/MediaTrait.php b/src/AnimeClient/Model/MediaTrait.php index 8e0d3177..cd2f8579 100644 --- a/src/AnimeClient/Model/MediaTrait.php +++ b/src/AnimeClient/Model/MediaTrait.php @@ -74,7 +74,7 @@ trait MediaTrait * Get information about a specific list item * for editing/updating that item */ - public function getItem(string $itemId): AnimeListItem|MangaListItem + public function getItem(string $itemId): AnimeListItem|MangaListItem|array { return $this->kitsuModel->getListItem($itemId); } diff --git a/src/AnimeClient/Types/Person.php b/src/AnimeClient/Types/Person.php index 0b4f39a6..6038894f 100644 --- a/src/AnimeClient/Types/Person.php +++ b/src/AnimeClient/Types/Person.php @@ -21,6 +21,7 @@ final class Person extends AbstractType { public string $id; public ?string $name; + public ?string $birthday; public string $image; public array $names = []; public ?string $description; From 065290e8e6d9ee9188fb1c68bfadff22751a15fb Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 18 May 2023 15:17:19 -0400 Subject: [PATCH 07/18] More local fixes, add some more data to user profile page --- app/views/user/details.php | 43 +++++++---- frontEndSrc/css/src/general.css | 11 +-- public/css/auto.min.css | 2 +- public/css/dark.min.css | 2 +- public/css/light.min.css | 2 +- .../API/Kitsu/Queries/MangaDetails.graphql | 8 +-- .../API/Kitsu/Queries/UserDetails.graphql | 3 +- .../Kitsu/Transformer/AnimeTransformer.php | 4 +- .../Transformer/CharacterTransformer.php | 4 +- .../Kitsu/Transformer/MangaTransformer.php | 4 +- .../Kitsu/Transformer/PersonTransformer.php | 4 +- .../API/Kitsu/Transformer/UserTransformer.php | 2 + src/AnimeClient/Kitsu.php | 72 +++++++++++++++---- src/AnimeClient/Types/User.php | 2 + 14 files changed, 109 insertions(+), 54 deletions(-) diff --git a/app/views/user/details.php b/app/views/user/details.php index b559efe7..3bb45482 100644 --- a/app/views/user/details.php +++ b/app/views/user/details.php @@ -3,40 +3,55 @@ use Aviat\AnimeClient\Kitsu; ?>

+ About a( - "https://kitsu.io/users/{$data['slug']}", - $data['name'], [ - 'title' => 'View profile on Kitsu' + "https://kitsu.io/users/{$data['slug']}", + $data['name'], [ + 'title' => 'View profile on Kitsu' ]) ?>

-

html($data['about']) ?>

-
- `}).join("")}function _normalizeProperty(props,sep="."){return props.replace(/\[(.*?)]/g,sep+"$1")}function hasNestedProperty(object,property){if(object&&typeof object==="object"){if(typeof property==="string"&&property!==""){property=_normalizeProperty(property);let split=property.split(".");return split.reduce((obj,prop,idx,array)=>{if(idx===array.length-1)return!!(obj&&obj.hasOwnProperty(prop));return obj&&obj[prop]},object)}else if(typeof property==="number")return property in object}return false}function getNestedProperty(object,property,sep="."){if(isType("string",property)&&property!==""){property=_normalizeProperty(property,sep);const levels=property.split(sep);try{return levels.reduce((obj,prop)=>obj[prop],object)}catch(e){return undefined}}return null}function getType(x){if(Array.isArray(x))return"array";if(typeof x!=="object")return(typeof x).toLowerCase();const type=function(){return Object.prototype.toString.call(this).slice(8,-1)};return type.call(x).toLowerCase()}function isType(type,val){return getType(val)===String(type).toLowerCase()}const search=(query,isCollection=false)=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("anime",searchResults,isCollection)})};if(AnimeClient.hasElement(".anime #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}if(AnimeClient.hasElement("#search-anime-collection")){let prevRequest=null;AnimeClient.on("#search-anime-collection","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query,true)}))}AnimeClient.on("body.anime.list","click",".plus-one",e=>{let parentSel=AnimeClient.closestParent(e.target,"article");let watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;let totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);let title=AnimeClient.$(".name a",parentSel)[0].textContent;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}.`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(watchedCount)||watchedCount===0)data.data.status="CURRENT";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="COMPLETED";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data,dataType:"json",type:"POST",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;displayMessage("success","Updated")}catch(_){showError()}},error:showError})});const search1=query=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("manga",searchResults)})};if(AnimeClient.hasElement(".manga #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{let query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",e=>{let thisSel=e.target;let parentSel=AnimeClient.closestParent(e.target,"article");let type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";let completed=parseInt(AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent,10)||0;let total=parseInt(AnimeClient.$(`.${type}_count`,parentSel)[0].textContent,10);let title=AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:completed}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}.`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(completed)||completed===0)data.data.status="CURRENT";if(!isNaN(completed)&&completed+1===total)data.data.status="COMPLETED";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data,dataType:"json",type:"POST",mimeType:"application/json",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent=String(completed);displayMessage("success","Updated")}catch(_){showError()}},error:showError})}); \ No newline at end of file + `}).join("")}function _normalizeProperty(props,sep="."){return props.replace(/\[(.*?)]/g,sep+"$1")}function hasNestedProperty(object,property){if(object&&typeof object==="object"){if(typeof property==="string"&&property!==""){property=_normalizeProperty(property);let split=property.split(".");return split.reduce((obj,prop,idx,array)=>{if(idx===array.length-1)return!!(obj&&obj.hasOwnProperty(prop));return obj&&obj[prop]},object)}else if(typeof property==="number")return property in object}return false}function getNestedProperty(object,property,sep="."){if(isType("string",property)&&property!==""){property=_normalizeProperty(property,sep);const levels=property.split(sep);try{return levels.reduce((obj,prop)=>obj[prop],object)}catch(e){return undefined}}return null}function getType(x){if(Array.isArray(x))return"array";if(typeof x!=="object")return(typeof x).toLowerCase();const type=function(){return Object.prototype.toString.call(this).slice(8,-1)};return type.call(x).toLowerCase()}function isType(type,val){return getType(val)===String(type).toLowerCase()}const search=(query,isCollection=false)=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/anime-collection/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("anime",searchResults,isCollection)})};if(AnimeClient.hasElement(".anime #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query)}))}if(AnimeClient.hasElement("#search-anime-collection")){let prevRequest=null;AnimeClient.on("#search-anime-collection","input",AnimeClient.throttle(250,e=>{const query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search(query,true)}))}AnimeClient.on("body.anime.list","click",".plus-one",e=>{let parentSel=AnimeClient.closestParent(e.target,"article");let watchedCount=parseInt(AnimeClient.$(".completed_number",parentSel)[0].textContent,10)||0;let totalCount=parseInt(AnimeClient.$(".total_number",parentSel)[0].textContent,10);let title=AnimeClient.$(".name a",parentSel)[0].textContent;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:watchedCount+1}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(watchedCount)||watchedCount===0)data.data.status="CURRENT";if(!isNaN(watchedCount)&&watchedCount+1===totalCount)data.data.status="COMPLETED";AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/anime/increment"),{data,dataType:"json",type:"POST",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(".completed_number",parentSel)[0].textContent=++watchedCount;displayMessage("success","Updated")}catch(_){showError()}},error:showError})});const search1=query=>{AnimeClient.show(".cssload-loader");return AnimeClient.get(AnimeClient.url("/manga/search"),{query},(searchResults,status)=>{searchResults=JSON.parse(searchResults);AnimeClient.hide(".cssload-loader");AnimeClient.$("#series-list")[0].innerHTML=renderSearchResults("manga",searchResults)})};if(AnimeClient.hasElement(".manga #search")){let prevRequest=null;AnimeClient.on("#search","input",AnimeClient.throttle(250,e=>{let query=encodeURIComponent(e.target.value);if(query==="")return;if(prevRequest!==null)prevRequest.abort();prevRequest=search1(query)}))}AnimeClient.on(".manga.list","click",".edit-buttons button",e=>{let thisSel=e.target;let parentSel=AnimeClient.closestParent(e.target,"article");let type=thisSel.classList.contains("plus-one-chapter")?"chapter":"volume";let completed=parseInt(AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent,10)||0;let total=parseInt(AnimeClient.$(`.${type}_count`,parentSel)[0].textContent,10);let title=AnimeClient.$(".name",parentSel)[0].textContent;if(isNaN(completed))completed=0;let data={id:parentSel.dataset.kitsuId,anilist_id:parentSel.dataset.anilistId,mal_id:parentSel.dataset.malId,data:{progress:completed}};const displayMessage=(type,message)=>{AnimeClient.hide("#loading-shadow");AnimeClient.showMessage(type,`${message} ${title}`);AnimeClient.scrollToTop()};const showError=()=>displayMessage("error","Failed to update");if(isNaN(completed)||completed===0)data.data.status="CURRENT";if(!isNaN(completed)&&completed+1===total)data.data.status="COMPLETED";data.data.progress=++completed;AnimeClient.show("#loading-shadow");AnimeClient.ajax(AnimeClient.url("/manga/increment"),{data,dataType:"json",type:"POST",mimeType:"application/json",success:res=>{try{const resData=JSON.parse(res);let updatedProgress=getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.progress");if(hasNestedProperty(resData,"error")||updatedProgress!==data.data.progress){showError();return}if(getNestedProperty(resData,"data.libraryEntry.update.libraryEntry.status")==="COMPLETED"){AnimeClient.hide(parentSel);displayMessage("success","Completed");return}AnimeClient.$(`.${type}s_read`,parentSel)[0].textContent=String(completed);displayMessage("success","Updated")}catch(_){showError()}},error:showError})}); \ No newline at end of file diff --git a/public/js/scripts.min.js.map b/public/js/scripts.min.js.map index 24a2ad88..eb1b3b25 100644 --- a/public/js/scripts.min.js.map +++ b/public/js/scripts.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/sw.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime-client.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/events.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/session-check.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/template-helpers.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/fns.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/manga.js"],"sourcesContent":["// Start the service worker, if you can\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}","// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nconst AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {Element} [context]\n\t * @return array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {Element} current - the current Element\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {Element|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|Element} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|Element|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import _ from './anime-client.js';\n\n(() => {\n\tlet hidden = null;\n\tlet visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tdocument.removeEventListener(visibilityChange, handleVisibilityChange, false);\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n\tdocument.getElementById(`anilist_${id}`).checked = true;\n});\n\n/**\n * On search results with an existing library entry, this shows that fact, with an edit link for the existing\n * library entry\n *\n * @param {'anime'|'manga'} type\n * @param {Object} item\n * @param isCollection\n * @returns {String}\n */\nfunction renderEditLink (type, item, isCollection = false) {\n\tif (isCollection || item.libraryEntry === null) {\n\t\treturn '';\n\t}\n\n\treturn `\n\t\t
\n\t\t\t[ Already in List ]\n\t\t
\n\t\t
\n\t\t\t\n\t\t\t\tEdit\n\t\t\t\n\t\t
\n\t\t
 
\n\t`\n}\n\n/**\n * Show the search results for a media item\n *\n * @param {'anime'|'manga'} type\n * @param {Object} data\n * @param {boolean} isCollection\n * @returns {String}\n */\nexport function renderSearchResults (type, data, isCollection = false) {\n\treturn data.map(item => {\n\t\tconst titles = item.titles.join('
');\n\t\tlet disabled = item.libraryEntry !== null ? 'disabled' : '';\n\t\tconst editLink = renderEditLink(type, item, isCollection);\n\n\t\tif (isCollection) {\n\t\t\tdisabled = '';\n\t\t}\n\n\t\treturn `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t${editLink}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`;\n\t}).join('');\n}","/**\n * Make sure properties are in an easily splittable format\n *\n * @private\n * @param {String} props\n * @param {String} [sep='.'] The default separator\n * @return {String}\n */\nfunction _normalizeProperty(props, sep = '.') {\n\t// Since we split by period, and property lookup\n\t// is the same by dot or [], replace bracket lookups\n\t// with periods\n\treturn props.replace(/\\[(.*?)]/g, sep + '$1');\n}\n\n/**\n * Tell if a nested object has a given property (or array a given index)\n * given an object such as a.b.c.d = 5, hasNestedProperty(a, 'b.c.d') will return true.\n *\n * @param {Object} object the object to get the property from\n * @param {String} property the path to the property as a string\n * @returns {boolean} true when property in object, false otherwise\n */\nexport function hasNestedProperty(object, property) {\n\tif (object && typeof object === 'object') {\n\t\tif (typeof property === 'string' && property !== '') {\n\t\t\tproperty = _normalizeProperty(property);\n\n\t\t\tlet split = property.split('.');\n\t\t\treturn split.reduce((obj, prop, idx, array) => {\n\t\t\t\tif (idx === array.length - 1) {\n\t\t\t\t\treturn !!(obj && obj.hasOwnProperty(prop));\n\t\t\t\t}\n\n\t\t\t\treturn obj && obj[prop];\n\t\t\t}, object);\n\t\t} else if (typeof property === 'number') {\n\t\t\treturn property in object;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Get the value of a deeply nested property in an object\n *\n * @param {Object} object the object to get the property\n * @param {string} property the path to the property as a string\n * @param {string} [sep='.'] The default separator to split on\n * @return {*} the value of the property\n */\nexport function getNestedProperty(object, property, sep = '.') {\n\tif (isType('string', property) && property !== '') {\n\t\t// convert numbers to dot syntax\n\t\tproperty = _normalizeProperty(property, sep);\n\t\tconst levels = property.split(sep);\n\n\t\ttry {\n\t\t\treturn levels.reduce((obj, prop) => obj[prop], object);\n\t\t} catch (e) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Reliably get the type of the value of a variable\n *\n * @param {*} x The variable to get the type of\n * @return {string} The name of the type\n */\nexport function getType(x) {\n\t// is it an array?\n\tif (Array.isArray(x)) {\n\t\treturn 'array';\n\t}\n\n\t// Use typeof for truthy primitives\n\tif (typeof x !== 'object') {\n\t\treturn (typeof x).toLowerCase();\n\t}\n\n\tconst type = function () {\n\t\treturn Object.prototype.toString.call(this).slice(8, -1);\n\t}\n\n\t// Otherwise, strip the type out of the '[Object x]' toString value\n\treturn type.call(x).toLowerCase();\n}\n\n/**\n * Check whether the value matches the passed type name\n *\n * @param {string} type Javascript type name\n * @param {*} val The value to type check\n * @return {boolean}\n */\nexport function isType(type, val) {\n\treturn getType(val) === String(type).toLowerCase();\n}","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query, isCollection = false) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults, isCollection);\n\t});\n};\n\n// Anime list search\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Anime collection search\nif (_.hasElement('#search-anime-collection')) {\n\tlet prevRequest = null;\n\n\t_.on('#search-anime-collection', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query, true);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}.`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t\tdisplayMessage('success', 'Updated');\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}.`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed);\n\t\t\t\tdisplayMessage('success', 'Updated');\n\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/sw.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime-client.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/events.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/session-check.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/template-helpers.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/fns.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/anime.js","/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/manga.js"],"sourcesContent":["// Start the service worker, if you can\nif ('serviceWorker' in navigator) {\n\tnavigator.serviceWorker.register('/sw.js').then(reg => {\n\t\tconsole.log('Service worker registered', reg.scope);\n\t}).catch(error => {\n\t\tconsole.error('Failed to register service worker', error);\n\t});\n}","// -------------------------------------------------------------------------\n// ! Base\n// -------------------------------------------------------------------------\n\nconst matches = (elm, selector) => {\n\tlet m = (elm.document || elm.ownerDocument).querySelectorAll(selector);\n\tlet i = matches.length;\n\twhile (--i >= 0 && m.item(i) !== elm) {};\n\treturn i > -1;\n}\n\nconst AnimeClient = {\n\t/**\n\t * Placeholder function\n\t */\n\tnoop: () => {},\n\t/**\n\t * DOM selector\n\t *\n\t * @param {string} selector - The dom selector string\n\t * @param {Element} [context]\n\t * @return array of dom elements\n\t */\n\t$(selector, context = null) {\n\t\tif (typeof selector !== 'string') {\n\t\t\treturn selector;\n\t\t}\n\n\t\tcontext = (context !== null && context.nodeType === 1)\n\t\t\t? context\n\t\t\t: document;\n\n\t\tlet elements = [];\n\t\tif (selector.match(/^#([\\w]+$)/)) {\n\t\t\telements.push(document.getElementById(selector.split('#')[1]));\n\t\t} else {\n\t\t\telements = [].slice.apply(context.querySelectorAll(selector));\n\t\t}\n\n\t\treturn elements;\n\t},\n\t/**\n\t * Does the selector exist on the current page?\n\t *\n\t * @param {string} selector\n\t * @returns {boolean}\n\t */\n\thasElement (selector) {\n\t\treturn AnimeClient.$(selector).length > 0;\n\t},\n\t/**\n\t * Scroll to the top of the Page\n\t *\n\t * @return {void}\n\t */\n\tscrollToTop () {\n\t\tconst el = AnimeClient.$('header')[0];\n\t\tel.scrollIntoView(true);\n\t},\n\t/**\n\t * Hide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\thide (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.setAttribute('hidden', 'hidden'));\n\t\t} else {\n\t\t\tsel.setAttribute('hidden', 'hidden');\n\t\t}\n\t},\n\t/**\n\t * UnHide the selected element\n\t *\n\t * @param {string|Element|Element[]} sel - the selector of the element to hide\n\t * @return {void}\n\t */\n\tshow (sel) {\n\t\tif (typeof sel === 'string') {\n\t\t\tsel = AnimeClient.$(sel);\n\t\t}\n\n\t\tif (Array.isArray(sel)) {\n\t\t\tsel.forEach(el => el.removeAttribute('hidden'));\n\t\t} else {\n\t\t\tsel.removeAttribute('hidden');\n\t\t}\n\t},\n\t/**\n\t * Display a message box\n\t *\n\t * @param {string} type - message type: info, error, success\n\t * @param {string} message - the message itself\n\t * @return {void}\n\t */\n\tshowMessage (type, message) {\n\t\tlet template =\n\t\t\t`
\n\t\t\t\t\n\t\t\t\t${message}\n\t\t\t\t\n\t\t\t
`;\n\n\t\tlet sel = AnimeClient.$('.message');\n\t\tif (sel[0] !== undefined) {\n\t\t\tsel[0].remove();\n\t\t}\n\n\t\tAnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);\n\t},\n\t/**\n\t * Finds the closest parent element matching the passed selector\n\t *\n\t * @param {Element} current - the current Element\n\t * @param {string} parentSelector - selector for the parent element\n\t * @return {Element|null} - the parent element\n\t */\n\tclosestParent (current, parentSelector) {\n\t\tif (Element.prototype.closest !== undefined) {\n\t\t\treturn current.closest(parentSelector);\n\t\t}\n\n\t\twhile (current !== document.documentElement) {\n\t\t\tif (matches(current, parentSelector)) {\n\t\t\t\treturn current;\n\t\t\t}\n\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\n\t\treturn null;\n\t},\n\t/**\n\t * Generate a full url from a relative path\n\t *\n\t * @param {string} path - url path\n\t * @return {string} - full url\n\t */\n\turl (path) {\n\t\tlet uri = `//${document.location.host}`;\n\t\turi += (path.charAt(0) === '/') ? path : `/${path}`;\n\n\t\treturn uri;\n\t},\n\t/**\n\t * Throttle execution of a function\n\t *\n\t * @see https://remysharp.com/2010/07/21/throttling-function-calls\n\t * @see https://jsfiddle.net/jonathansampson/m7G64/\n\t * @param {Number} interval - the minimum throttle time in ms\n\t * @param {Function} fn - the function to throttle\n\t * @param {Object} [scope] - the 'this' object for the function\n\t * @return {Function}\n\t */\n\tthrottle (interval, fn, scope) {\n\t\tlet wait = false;\n\t\treturn function (...args) {\n\t\t\tconst context = scope || this;\n\n\t\t\tif ( ! wait) {\n\t\t\t\tfn.apply(context, args);\n\t\t\t\twait = true;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\twait = false;\n\t\t\t\t}, interval);\n\t\t\t}\n\t\t};\n\t},\n};\n\n// -------------------------------------------------------------------------\n// ! Events\n// -------------------------------------------------------------------------\n\nfunction addEvent(sel, event, listener) {\n\t// Recurse!\n\tif (! event.match(/^([\\w\\-]+)$/)) {\n\t\tevent.split(' ').forEach((evt) => {\n\t\t\taddEvent(sel, evt, listener);\n\t\t});\n\t}\n\n\tsel.addEventListener(event, listener, false);\n}\n\nfunction delegateEvent(sel, target, event, listener) {\n\t// Attach the listener to the parent\n\taddEvent(sel, event, (e) => {\n\t\t// Get live version of the target selector\n\t\tAnimeClient.$(target, sel).forEach((element) => {\n\t\t\tif(e.target == element) {\n\t\t\t\tlistener.call(element, e);\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Add an event listener\n *\n * @param {string|Element} sel - the parent selector to bind to\n * @param {string} event - event name(s) to bind\n * @param {string|Element|function} target - the element to directly bind the event to\n * @param {function} [listener] - event listener callback\n * @return {void}\n */\nAnimeClient.on = (sel, event, target, listener) => {\n\tif (listener === undefined) {\n\t\tlistener = target;\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\taddEvent(el, event, listener);\n\t\t});\n\t} else {\n\t\tAnimeClient.$(sel).forEach((el) => {\n\t\t\tdelegateEvent(el, target, event, listener);\n\t\t});\n\t}\n};\n\n// -------------------------------------------------------------------------\n// ! Ajax\n// -------------------------------------------------------------------------\n\n/**\n * Url encoding for non-get requests\n *\n * @param data\n * @returns {string}\n * @private\n */\nfunction ajaxSerialize(data) {\n\tlet pairs = [];\n\n\tObject.keys(data).forEach((name) => {\n\t\tlet value = data[name].toString();\n\n\t\tname = encodeURIComponent(name);\n\t\tvalue = encodeURIComponent(value);\n\n\t\tpairs.push(`${name}=${value}`);\n\t});\n\n\treturn pairs.join('&');\n}\n\n/**\n * Make an ajax request\n *\n * Config:{\n * \tdata: // data to send with the request\n * \ttype: // http verb of the request, defaults to GET\n * \tsuccess: // success callback\n * \terror: // error callback\n * }\n *\n * @param {string} url - the url to request\n * @param {Object} config - the configuration object\n * @return {XMLHttpRequest}\n */\nAnimeClient.ajax = (url, config) => {\n\t// Set some sane defaults\n\tconst defaultConfig = {\n\t\tdata: {},\n\t\ttype: 'GET',\n\t\tdataType: '',\n\t\tsuccess: AnimeClient.noop,\n\t\tmimeType: 'application/x-www-form-urlencoded',\n\t\terror: AnimeClient.noop\n\t}\n\n\tconfig = {\n\t\t...defaultConfig,\n\t\t...config,\n\t}\n\n\tlet request = new XMLHttpRequest();\n\tlet method = String(config.type).toUpperCase();\n\n\tif (method === 'GET') {\n\t\turl += (url.match(/\\?/))\n\t\t\t? ajaxSerialize(config.data)\n\t\t\t: `?${ajaxSerialize(config.data)}`;\n\t}\n\n\trequest.open(method, url);\n\n\trequest.onreadystatechange = () => {\n\t\tif (request.readyState === 4) {\n\t\t\tlet responseText = '';\n\n\t\t\tif (request.responseType === 'json') {\n\t\t\t\tresponseText = JSON.parse(request.responseText);\n\t\t\t} else {\n\t\t\t\tresponseText = request.responseText;\n\t\t\t}\n\n\t\t\tif (request.status > 299) {\n\t\t\t\tconfig.error.call(null, request.status, responseText, request.response);\n\t\t\t} else {\n\t\t\t\tconfig.success.call(null, responseText, request.status);\n\t\t\t}\n\t\t}\n\t};\n\n\tif (config.dataType === 'json') {\n\t\tconfig.data = JSON.stringify(config.data);\n\t\tconfig.mimeType = 'application/json';\n\t} else {\n\t\tconfig.data = ajaxSerialize(config.data);\n\t}\n\n\trequest.setRequestHeader('Content-Type', config.mimeType);\n\n\tif (method === 'GET') {\n\t\trequest.send(null);\n\t} else {\n\t\trequest.send(config.data);\n\t}\n\n\treturn request\n};\n\n/**\n * Do a get request\n *\n * @param {string} url\n * @param {object|function} data\n * @param {function} [callback]\n * @return {XMLHttpRequest}\n */\nAnimeClient.get = (url, data, callback = null) => {\n\tif (callback === null) {\n\t\tcallback = data;\n\t\tdata = {};\n\t}\n\n\treturn AnimeClient.ajax(url, {\n\t\tdata,\n\t\tsuccess: callback\n\t});\n};\n\n// -------------------------------------------------------------------------\n// Export\n// -------------------------------------------------------------------------\n\nexport default AnimeClient;","import _ from './anime-client.js';\n\n// ----------------------------------------------------------------------------\n// Event subscriptions\n// ----------------------------------------------------------------------------\n_.on('header', 'click', '.message', hide);\n_.on('form.js-delete', 'submit', confirmDelete);\n_.on('.js-clear-cache', 'click', clearAPICache);\n_.on('.vertical-tabs input', 'change', scrollToSection);\n_.on('.media-filter', 'input', filterMedia);\n\n// ----------------------------------------------------------------------------\n// Handler functions\n// ----------------------------------------------------------------------------\n\n/**\n * Hide the html element attached to the event\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction hide (event) {\n\t_.hide(event.target)\n}\n\n/**\n * Confirm deletion of an item\n *\n * @param {MouseEvent} event\n * @return void\n */\nfunction confirmDelete (event) {\n\tconst proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');\n\n\tif (proceed === false) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t}\n}\n\n/**\n * Clear the API cache, and show a message if the cache is cleared\n *\n * @return void\n */\nfunction clearAPICache () {\n\t_.get('/cache_purge', () => {\n\t\t_.showMessage('success', 'Successfully purged api cache');\n\t});\n}\n\n/**\n * Scroll to the accordion/vertical tab section just opened\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction scrollToSection (event) {\n\tconst el = event.currentTarget.parentElement;\n\tconst rect = el.getBoundingClientRect();\n\n\tconst top = rect.top + window.pageYOffset;\n\n\twindow.scrollTo({\n\t\ttop,\n\t\tbehavior: 'smooth',\n\t});\n}\n\n/**\n * Filter an anime or manga list\n *\n * @param {InputEvent} event\n * @return void\n */\nfunction filterMedia (event) {\n\tconst rawFilter = event.target.value;\n\tconst filter = new RegExp(rawFilter, 'i');\n\n\t// console.log('Filtering items by: ', filter);\n\n\tif (rawFilter !== '') {\n\t\t// Filter the cover view\n\t\t_.$('article.media').forEach(article => {\n\t\t\tconst titleLink = _.$('.name a', article)[0];\n\t\t\tconst title = String(titleLink.textContent).trim();\n\t\t\tif ( ! filter.test(title)) {\n\t\t\t\t_.hide(article);\n\t\t\t} else {\n\t\t\t\t_.show(article);\n\t\t\t}\n\t\t});\n\n\t\t// Filter the list view\n\t\t_.$('table.media-wrap tbody tr').forEach(tr => {\n\t\t\tconst titleCell = _.$('td.align-left', tr)[0];\n\t\t\tconst titleLink = _.$('a', titleCell)[0];\n\t\t\tconst linkTitle = String(titleLink.textContent).trim();\n\t\t\tconst textTitle = String(titleCell.textContent).trim();\n\t\t\tif ( ! (filter.test(linkTitle) || filter.test(textTitle))) {\n\t\t\t\t_.hide(tr);\n\t\t\t} else {\n\t\t\t\t_.show(tr);\n\t\t\t}\n\t\t});\n\t} else {\n\t\t_.show('article.media');\n\t\t_.show('table.media-wrap tbody tr');\n\t}\n}\n","import _ from './anime-client.js';\n\n(() => {\n\tlet hidden = null;\n\tlet visibilityChange = null;\n\n\tif (typeof document.hidden !== \"undefined\") {\n\t\thidden = \"hidden\";\n\t\tvisibilityChange = \"visibilitychange\";\n\t} else if (typeof document.msHidden !== \"undefined\") {\n\t\thidden = \"msHidden\";\n\t\tvisibilityChange = \"msvisibilitychange\";\n\t} else if (typeof document.webkitHidden !== \"undefined\") {\n\t\thidden = \"webkitHidden\";\n\t\tvisibilityChange = \"webkitvisibilitychange\";\n\t}\n\n\tfunction handleVisibilityChange() {\n\t\t// Check the user's session to see if they are currently logged-in\n\t\t// when the page becomes visible\n\t\tif ( ! document[hidden]) {\n\t\t\t_.get('/heartbeat', (beat) => {\n\t\t\t\tconst status = JSON.parse(beat)\n\n\t\t\t\t// If the session is expired, immediately reload so that\n\t\t\t\t// you can't attempt to do an action that requires authentication\n\t\t\t\tif (status.hasAuth !== true) {\n\t\t\t\t\tdocument.removeEventListener(visibilityChange, handleVisibilityChange, false);\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tif (hidden === null) {\n\t\tconsole.info('Page visibility API not supported, JS session check will not work');\n\t} else {\n\t\tdocument.addEventListener(visibilityChange, handleVisibilityChange, false);\n\t}\n})();","import _ from './anime-client.js';\n\n// Click on hidden MAL checkbox so\n// that MAL id is passed\n_.on('main', 'change', '.big-check', (e) => {\n\tconst id = e.target.id;\n\tdocument.getElementById(`mal_${id}`).checked = true;\n\tdocument.getElementById(`anilist_${id}`).checked = true;\n});\n\n/**\n * On search results with an existing library entry, this shows that fact, with an edit link for the existing\n * library entry\n *\n * @param {'anime'|'manga'} type\n * @param {Object} item\n * @param isCollection\n * @returns {String}\n */\nfunction renderEditLink (type, item, isCollection = false) {\n\tif (isCollection || item.libraryEntry === null) {\n\t\treturn '';\n\t}\n\n\treturn `\n\t\t
\n\t\t\t[ Already in List ]\n\t\t
\n\t\t
\n\t\t\t\n\t\t\t\tEdit\n\t\t\t\n\t\t
\n\t\t
 
\n\t`\n}\n\n/**\n * Show the search results for a media item\n *\n * @param {'anime'|'manga'} type\n * @param {Object} data\n * @param {boolean} isCollection\n * @returns {String}\n */\nexport function renderSearchResults (type, data, isCollection = false) {\n\treturn data.map(item => {\n\t\tconst titles = item.titles.join('
');\n\t\tlet disabled = item.libraryEntry !== null ? 'disabled' : '';\n\t\tconst editLink = renderEditLink(type, item, isCollection);\n\n\t\tif (isCollection) {\n\t\t\tdisabled = '';\n\t\t}\n\n\t\treturn `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t${editLink}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\tInfo Page\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t`;\n\t}).join('');\n}","/**\n * Make sure properties are in an easily splittable format\n *\n * @private\n * @param {String} props\n * @param {String} [sep='.'] The default separator\n * @return {String}\n */\nfunction _normalizeProperty(props, sep = '.') {\n\t// Since we split by period, and property lookup\n\t// is the same by dot or [], replace bracket lookups\n\t// with periods\n\treturn props.replace(/\\[(.*?)]/g, sep + '$1');\n}\n\n/**\n * Tell if a nested object has a given property (or array a given index)\n * given an object such as a.b.c.d = 5, hasNestedProperty(a, 'b.c.d') will return true.\n *\n * @param {Object} object the object to get the property from\n * @param {String} property the path to the property as a string\n * @returns {boolean} true when property in object, false otherwise\n */\nexport function hasNestedProperty(object, property) {\n\tif (object && typeof object === 'object') {\n\t\tif (typeof property === 'string' && property !== '') {\n\t\t\tproperty = _normalizeProperty(property);\n\n\t\t\tlet split = property.split('.');\n\t\t\treturn split.reduce((obj, prop, idx, array) => {\n\t\t\t\tif (idx === array.length - 1) {\n\t\t\t\t\treturn !!(obj && obj.hasOwnProperty(prop));\n\t\t\t\t}\n\n\t\t\t\treturn obj && obj[prop];\n\t\t\t}, object);\n\t\t} else if (typeof property === 'number') {\n\t\t\treturn property in object;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Get the value of a deeply nested property in an object\n *\n * @param {Object} object the object to get the property\n * @param {string} property the path to the property as a string\n * @param {string} [sep='.'] The default separator to split on\n * @return {*} the value of the property\n */\nexport function getNestedProperty(object, property, sep = '.') {\n\tif (isType('string', property) && property !== '') {\n\t\t// convert numbers to dot syntax\n\t\tproperty = _normalizeProperty(property, sep);\n\t\tconst levels = property.split(sep);\n\n\t\ttry {\n\t\t\treturn levels.reduce((obj, prop) => obj[prop], object);\n\t\t} catch (e) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Reliably get the type of the value of a variable\n *\n * @param {*} x The variable to get the type of\n * @return {string} The name of the type\n */\nexport function getType(x) {\n\t// is it an array?\n\tif (Array.isArray(x)) {\n\t\treturn 'array';\n\t}\n\n\t// Use typeof for truthy primitives\n\tif (typeof x !== 'object') {\n\t\treturn (typeof x).toLowerCase();\n\t}\n\n\tconst type = function () {\n\t\treturn Object.prototype.toString.call(this).slice(8, -1);\n\t}\n\n\t// Otherwise, strip the type out of the '[Object x]' toString value\n\treturn type.call(x).toLowerCase();\n}\n\n/**\n * Check whether the value matches the passed type name\n *\n * @param {string} type Javascript type name\n * @param {*} val The value to type check\n * @return {boolean}\n */\nexport function isType(type, val) {\n\treturn getType(val) === String(type).toLowerCase();\n}","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query, isCollection = false) => {\n\t// Show the loader\n\t_.show('.cssload-loader');\n\n\t// Do the api search\n\treturn _.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\n\t\t// Hide the loader\n\t\t_.hide('.cssload-loader');\n\n\t\t// Show the results\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('anime', searchResults, isCollection);\n\t});\n};\n\n// Anime list search\nif (_.hasElement('.anime #search')) {\n\tlet prevRequest = null;\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n// Anime collection search\nif (_.hasElement('#search-anime-collection')) {\n\tlet prevRequest = null;\n\n\t_.on('#search-anime-collection', 'input', _.throttle(250, (e) => {\n\t\tconst query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query, true);\n\t}));\n}\n\n// Action to increment episode count\n_.on('body.anime.list', 'click', '.plus-one', (e) => {\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet watchedCount = parseInt(_.$('.completed_number', parentSel)[ 0 ].textContent, 10) || 0;\n\tlet totalCount = parseInt(_.$('.total_number', parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name a', parentSel)[ 0 ].textContent;\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: watchedCount + 1\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently watching\n\tif (isNaN(watchedCount) || watchedCount === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last episode, mark as completed\n\tif ((!isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t_.show('#loading-shadow');\n\n\t// okay, lets actually make some changes!\n\t_.ajax(_.url('/anime/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$('.completed_number', parentSel)[ 0 ].textContent = ++watchedCount;\n\t\t\t\tdisplayMessage('success', 'Updated');\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});","import _ from './anime-client.js'\nimport { renderSearchResults } from './template-helpers.js'\nimport { getNestedProperty, hasNestedProperty } from \"./fns\";\n\nconst search = (query) => {\n\t_.show('.cssload-loader');\n\treturn _.get(_.url('/manga/search'), { query }, (searchResults, status) => {\n\t\tsearchResults = JSON.parse(searchResults);\n\t\t_.hide('.cssload-loader');\n\t\t_.$('#series-list')[ 0 ].innerHTML = renderSearchResults('manga', searchResults);\n\t});\n};\n\nif (_.hasElement('.manga #search')) {\n\tlet prevRequest = null\n\n\t_.on('#search', 'input', _.throttle(250, (e) => {\n\t\tlet query = encodeURIComponent(e.target.value);\n\t\tif (query === '') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (prevRequest !== null) {\n\t\t\tprevRequest.abort();\n\t\t}\n\n\t\tprevRequest = search(query);\n\t}));\n}\n\n/**\n * Javascript for editing manga, if logged in\n */\n_.on('.manga.list', 'click', '.edit-buttons button', (e) => {\n\tlet thisSel = e.target;\n\tlet parentSel = _.closestParent(e.target, 'article');\n\tlet type = thisSel.classList.contains('plus-one-chapter') ? 'chapter' : 'volume';\n\tlet completed = parseInt(_.$(`.${type}s_read`, parentSel)[ 0 ].textContent, 10) || 0;\n\tlet total = parseInt(_.$(`.${type}_count`, parentSel)[ 0 ].textContent, 10);\n\tlet title = _.$('.name', parentSel)[ 0 ].textContent;\n\n\tif (isNaN(completed)) {\n\t\tcompleted = 0;\n\t}\n\n\t// Setup the update data\n\tlet data = {\n\t\tid: parentSel.dataset.kitsuId,\n\t\tanilist_id: parentSel.dataset.anilistId,\n\t\tmal_id: parentSel.dataset.malId,\n\t\tdata: {\n\t\t\tprogress: completed\n\t\t}\n\t};\n\n\tconst displayMessage = (type, message) => {\n\t\t_.hide('#loading-shadow');\n\t\t_.showMessage(type, `${message} ${title}`);\n\t\t_.scrollToTop();\n\t}\n\n\tconst showError = () => displayMessage('error', 'Failed to update');\n\n\t// If the episode count is 0, and incremented,\n\t// change status to currently reading\n\tif (isNaN(completed) || completed === 0) {\n\t\tdata.data.status = 'CURRENT';\n\t}\n\n\t// If you increment at the last chapter, mark as completed\n\tif ((!isNaN(completed)) && (completed + 1) === total) {\n\t\tdata.data.status = 'COMPLETED';\n\t}\n\n\t// Update the total count\n\tdata.data.progress = ++completed;\n\n\t_.show('#loading-shadow');\n\n\t_.ajax(_.url('/manga/increment'), {\n\t\tdata,\n\t\tdataType: 'json',\n\t\ttype: 'POST',\n\t\tmimeType: 'application/json',\n\t\tsuccess: (res) => {\n\t\t\ttry {\n\t\t\t\tconst resData = JSON.parse(res);\n\n\t\t\t\t// Do a rough sanity check for weird errors\n\t\t\t\tlet updatedProgress = getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.progress');\n\t\t\t\tif (hasNestedProperty(resData, 'error') || updatedProgress !== data.data.progress) {\n\t\t\t\t\tshowError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// We've completed the series\n\t\t\t\tif (getNestedProperty(resData, 'data.libraryEntry.update.libraryEntry.status') === 'COMPLETED') {\n\t\t\t\t\t_.hide(parentSel);\n\t\t\t\t\tdisplayMessage('success', 'Completed')\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Just a normal update\n\t\t\t\t_.$(`.${type}s_read`, parentSel)[ 0 ].textContent = String(completed);\n\t\t\t\tdisplayMessage('success', 'Updated');\n\n\t\t\t} catch (_) {\n\t\t\t\tshowError();\n\t\t\t}\n\t\t},\n\t\terror: showError,\n\t});\n});"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/public/js/tables.min.js.map b/public/js/tables.min.js.map index 1e6b2e37..d7a606fa 100644 --- a/public/js/tables.min.js.map +++ b/public/js/tables.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/base/sort-tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconsole.log(\"Comparing \" + textA + \" and \" + textB)\n\n\t\tif(th.classList.contains(\"numeric\")){\n\t\t\tlet arrayA = textA.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tlet arrayB = textB.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tif(arrayA.length > 1) {\n\t\t\t\ttextA = parseInt(arrayA[0],10) / parseInt(arrayA[1],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10) / parseInt(arrayB[1],10);\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextA = parseInt(arrayA[0],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10);\n\t\t\t}\n\t\t}\n\t\telse if (parseInt(textA, 10)) {\n\t\t\ttextA = parseInt(textA, 10);\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting-asc' ? 'sorting-asc' : 'sorting-desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting-asc', 'sorting-desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting-asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tth.classList.add('testing');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"AAAA,MAAM,iBAAmB,AAAC,CAAA,IAAM,CAC/B,IAAI,GAAK,IAAI,CACb,IAAI,UAAY,IAAI,CACpB,IAAI,MAAQ,GACZ,MAAM,KAAO,AAAC,KAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,CAAC,WAAW,GACvE,MAAM,KAAO,CAAC,EAAG,IAAM,CACtB,IAAI,MAAQ,KAAK,GACjB,IAAI,MAAQ,KAAK,GACjB,QAAQ,GAAG,CAAC,aAAe,MAAQ,QAAU,OAE7C,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,WAAW,CACnC,IAAI,OAAS,MAAM,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,KAClE,IAAI,OAAS,MAAM,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,KAClE,GAAG,OAAO,MAAM,CAAG,EAAG,CACrB,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,IACpD,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,GACrD,KACI,CACH,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAC3B,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,GAC5B,CAAC,AACF,MACK,GAAI,SAAS,MAAO,IAAK,CAC7B,MAAQ,SAAS,MAAO,IACxB,MAAQ,SAAS,MAAO,GACzB,CAAC,AACD,GAAI,MAAQ,MACX,OAAO,CACP,CACD,GAAI,MAAQ,MACX,OAAO,EACP,CACD,OAAO,CACR,EACA,MAAM,OAAS,IAAM,CACpB,MAAM,EAAI,QAAU,cAAgB,cAAgB,cAAc,AAClE,CAAA,GAAG,SAAS,CAAG,AAAC,CAAA,GAAG,SAAS,CAAC,OAAO,CAAC,MAAO,IAAM,IAAM,CAAA,EAAG,IAAI,GAC/D,OAAO,MAAQ,CAChB,EACA,MAAM,MAAQ,IAAM,CACnB,GAAG,SAAS,CAAC,MAAM,CAAC,cAAe,gBACnC,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,OAAO,MAAQ,EAChB,EACA,MAAM,aAAe,AAAC,GAAM,CAC3B,GAAI,IAAO,YAAc,EAAE,MAAM,CAAC,SAAS,CAC1C,OACA,CACD,GAAK,EAAE,MAAM,CACb,GAAI,GAAG,QAAQ,CAAC,WAAW,KAAO,KAAM,CACvC,UAAY,GAAG,SAAS,CACxB,MAAM,MAAQ,GAAG,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAC9D,IAAI,KAAO,MAAM,IAAI,CAAC,MAAM,IAAI,EAChC,GAAI,KAAM,CACT,KAAK,IAAI,CAAC,MACV,GAAI,QAAU,cACb,KAAK,OAAO,EACZ,CACD,QACA,CAAA,MAAM,SAAS,CAAG,GAElB,KAAK,OAAO,CAAC,KAAO,CACnB,MAAM,WAAW,CAAC,IACnB,EACD,CAAC,AACF,CAAC,AACF,EACA,MAAO,CACN,KAAM,IAAM,CACX,IAAI,IAAM,SAAS,oBAAoB,CAAC,MACxC,IAAI,QAAU,EAAE,CAChB,IAAK,IAAI,EAAI,EAAG,IAAM,IAAI,MAAM,CAAE,EAAI,IAAK,IAAK,CAC/C,IAAI,GAAK,GAAG,CAAC,EAAE,CACf,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,GAAG,SAAS,CAAC,GAAG,CAAC,WACjB,QAAQ,IAAI,CAAC,GAAG,OAAO,CAAG,aAC3B,CACA,OAAO,OACR,CACD,CACD,CAAA,IAEA,iBAAiB,IAAI"} \ No newline at end of file +{"version":3,"sources":["/var/www/htdocs/github.timshomepage.net/animeclient/frontEndSrc/js/base/sort-tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => row.cells.item(cellIndex).textContent.toLowerCase();\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconsole.log(\"Comparing \" + textA + \" and \" + textB)\n\n\t\tif(th.classList.contains(\"numeric\")){\n\t\t\tlet arrayA = textA.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tlet arrayB = textB.replace('episodes: ','').replace('-',0).split(\"/\");\n\t\t\tif(arrayA.length > 1) {\n\t\t\t\ttextA = parseInt(arrayA[0],10) / parseInt(arrayA[1],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10) / parseInt(arrayB[1],10);\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextA = parseInt(arrayA[0],10);\n\t\t\t\ttextB = parseInt(arrayB[0],10);\n\t\t\t}\n\t\t}\n\t\telse if (parseInt(textA, 10)) {\n\t\t\ttextA = parseInt(textA, 10);\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting-asc' ? 'sorting-asc' : 'sorting-desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting-asc', 'sorting-desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting-asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tth.classList.add('testing');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"AAAA,MAAM,iBAAmB,AAAC,CAAA,KACzB,IAAI,GAAK,KACT,IAAI,UAAY,KAChB,IAAI,MAAQ,GACZ,MAAM,KAAO,AAAC,KAAQ,IAAI,MAAM,KAAK,WAAW,YAAY,cAC5D,MAAM,KAAO,CAAC,EAAG,KAChB,IAAI,MAAQ,KAAK,GACjB,IAAI,MAAQ,KAAK,GACjB,QAAQ,IAAI,aAAe,MAAQ,QAAU,OAE7C,GAAG,GAAG,UAAU,SAAS,WAAW,CACnC,IAAI,OAAS,MAAM,QAAQ,cAAc,IAAI,QAAQ,IAAI,GAAG,MAAM,KAClE,IAAI,OAAS,MAAM,QAAQ,cAAc,IAAI,QAAQ,IAAI,GAAG,MAAM,KAClE,GAAG,OAAO,OAAS,EAAG,CACrB,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,IACpD,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAAM,SAAS,MAAM,CAAC,EAAE,CAAC,GACrD,KACI,CACH,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,IAC3B,MAAQ,SAAS,MAAM,CAAC,EAAE,CAAC,GAC5B,CACD,MACK,GAAI,SAAS,MAAO,IAAK,CAC7B,MAAQ,SAAS,MAAO,IACxB,MAAQ,SAAS,MAAO,GACzB,CACA,GAAI,MAAQ,MACX,OAAO,EAER,GAAI,MAAQ,MACX,OAAO,GAER,OAAO,CACR,EACA,MAAM,OAAS,KACd,MAAM,EAAI,QAAU,cAAgB,cAAgB,cACpD,CAAA,GAAG,UAAY,AAAC,CAAA,GAAG,UAAU,QAAQ,MAAO,IAAM,IAAM,CAAA,EAAG,OAC3D,OAAO,MAAQ,CAChB,EACA,MAAM,MAAQ,KACb,GAAG,UAAU,OAAO,cAAe,gBACnC,GAAG,UAAU,IAAI,WACjB,OAAO,MAAQ,EAChB,EACA,MAAM,aAAe,AAAC,IACrB,GAAI,IAAO,YAAc,EAAE,OAAO,UACjC,QAED,GAAK,EAAE,OACP,GAAI,GAAG,SAAS,gBAAkB,KAAM,CACvC,UAAY,GAAG,UACf,MAAM,MAAQ,GAAG,aAAa,qBAAqB,QAAQ,CAAC,EAAE,CAC9D,IAAI,KAAO,MAAM,KAAK,MAAM,MAC5B,GAAI,KAAM,CACT,KAAK,KAAK,MACV,GAAI,QAAU,cACb,KAAK,UAEN,QACA,CAAA,MAAM,UAAY,GAElB,KAAK,QAAQ,MACZ,MAAM,YAAY,IACnB,EACD,CACD,CACD,EACA,MAAO,CACN,KAAM,KACL,IAAI,IAAM,SAAS,qBAAqB,MACxC,IAAI,QAAU,EAAE,CAChB,IAAK,IAAI,EAAI,EAAG,IAAM,IAAI,OAAQ,EAAI,IAAK,IAAK,CAC/C,IAAI,GAAK,GAAG,CAAC,EAAE,CACf,GAAG,UAAU,IAAI,WACjB,GAAG,UAAU,IAAI,WACjB,QAAQ,KAAK,GAAG,QAAU,aAC3B,CACA,OAAO,OACR,CACD,CACD,CAAA,IAEA,iBAAiB"} \ No newline at end of file diff --git a/tools/offline-db-update.php b/tools/offline-db-update.php deleted file mode 100644 index e69de29b..00000000 From b59e476b87bfe8a7c3d35f7e7e1be6b5dfd6ee8d Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 19 May 2023 16:34:07 -0400 Subject: [PATCH 17/18] Update tooling and config --- justfile | 54 ++++++++++++++++++++++++++++++++++++--------- phpstan.neon | 7 +++--- tools/composer.json | 2 +- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/justfile b/justfile index 9954e4b9..07e04916 100644 --- a/justfile +++ b/justfile @@ -2,13 +2,25 @@ default: @just --list -# Runs rector, showing what changes will be make -rector-dry-run: - tools/vendor/bin/rector process --config=tools/rector.php --dry-run src tests +# ------------------------------------------------------------------- +# Front-end stuff +# ------------------------------------------------------------------- -# Runs rector, and updates the source files -rector: - tools/vendor/bin/rector process --config=tools/rector.php src tests +# Builds/optimizes JS and CSS +build: + cd frontEndSrc && npm run build && cd .. + +# Builds/optimizes CSS +css: + composer run-script build:css + +# Builds/optimizes JS +js: + composer run-script build:js + +# ------------------------------------------------------------------- +# Code Quality and Formatting +# ------------------------------------------------------------------- # Check code formatting check-fmt: @@ -18,6 +30,22 @@ check-fmt: fmt: tools/vendor/bin/php-cs-fixer fix --verbose +# Runs phpstan code check +phpstan: + composer run-script phpstan + +# Runs rector, showing what changes will be make +rector-dry-run: + tools/vendor/bin/rector process --config=tools/rector.php --dry-run src tests + +# Runs rector, and updates the source files +rector: + tools/vendor/bin/rector process --config=tools/rector.php src tests + +# ------------------------------------------------------------------- +# Testing +# ------------------------------------------------------------------- + # Run tests test: composer run-script test @@ -26,10 +54,14 @@ test: test-update: composer run-script test-update -# Update the per-file header comments -update-headers: - php tools/update_header_comments.php - # Run unit tests and generate test-coverage report coverage: - composer run-script coverage \ No newline at end of file + composer run-script coverage + +# ------------------------------------------------------------------- +# Misc +# ------------------------------------------------------------------- + +# Update the per-file header comments +update-headers: + php tools/update_header_comments.php \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon index 1706927e..3e66a005 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,11 +9,12 @@ parameters: - ./console - index.php ignoreErrors: - - "#Offset 'fields' does not exist on array#" - - '#Function imagepalletetotruecolor not found#' + - '#Unable to resolve the template type T#' + - '#imagepalletetotruecolor not found#' - '#Call to an undefined method Aura\\\Html\\\HelperLocator::[a-zA-Z0-9_]+\(\)#' - '#Call to an undefined method Query\\QueryBuilderInterface::[a-zA-Z0-9_]+\(\)#' - excludes_analyse: + excludePaths: + - src/Ion/Type/Stringy.php - tests/mocks.php - vendor # These are objects that basically can return anything diff --git a/tools/composer.json b/tools/composer.json index d1d3c047..d6a58ef1 100644 --- a/tools/composer.json +++ b/tools/composer.json @@ -1,6 +1,6 @@ { "require": { "friendsofphp/php-cs-fixer": "^3.6", - "rector/rector": "^0.15.21" + "rector/rector": "^0.16.0" } } From 5242b95a0e83068851d20773801e17629c359e1d Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 19 May 2023 16:34:38 -0400 Subject: [PATCH 18/18] Fix a load of code cleanliness and style issues --- src/AnimeClient/API/Kitsu/Model.php | 10 ++--- src/AnimeClient/API/Kitsu/RequestBuilder.php | 41 +------------------ .../API/Kitsu/RequestBuilderTrait.php | 2 - .../Kitsu/Transformer/MangaTransformer.php | 2 +- src/AnimeClient/AnimeClient.php | 5 --- src/AnimeClient/Controller/Anime.php | 4 -- src/AnimeClient/Controller/Character.php | 2 - src/AnimeClient/Controller/Images.php | 20 +++++---- src/AnimeClient/Controller/Manga.php | 4 -- src/AnimeClient/Controller/Misc.php | 10 +---- src/AnimeClient/Controller/People.php | 2 - src/AnimeClient/Controller/Settings.php | 10 +---- src/AnimeClient/Controller/User.php | 2 - src/AnimeClient/Dispatcher.php | 24 +++-------- src/AnimeClient/Model/AnimeCollection.php | 16 ++++---- src/Ion/Json.php | 17 ++++++-- src/Ion/Type/StringType.php | 4 +- src/Ion/Type/Stringy.php | 2 +- src/Ion/View/HtmlView.php | 4 +- tests/AnimeClient/AnimeClientTest.php | 5 +++ tests/Ion/ConfigTest.php | 2 + tests/Ion/Type/StringTypeTest.php | 7 +++- tests/Ion/View/HttpViewTest.php | 1 + tests/Ion/functionsTest.php | 9 +++- 24 files changed, 78 insertions(+), 127 deletions(-) diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index b4293d7d..ae708394 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -283,7 +283,7 @@ final class Model if ($list === NULL) { - $data = $this->getList(MediaType::ANIME, $status) ?? []; + $data = $this->getList(MediaType::ANIME, $status); // Bail out on no data if (empty($data)) @@ -320,7 +320,7 @@ final class Model /** * Get all the anime entries, that are organized for output to html * - * @return array + * @return array */ public function getFullOrganizedAnimeList(): array { @@ -331,7 +331,7 @@ final class Model foreach ($statuses as $status) { $mappedStatus = AnimeWatchingStatus::KITSU_TO_TITLE[$status]; - $output[$mappedStatus] = $this->getAnimeList($status) ?? []; + $output[$mappedStatus] = $this->getAnimeList($status); } return $output; @@ -413,7 +413,7 @@ final class Model if ($list === NULL) { - $data = $this->getList(MediaType::MANGA, $status) ?? []; + $data = $this->getList(MediaType::MANGA, $status); // Bail out on no data if (empty($data)) @@ -787,7 +787,7 @@ final class Model } } - private function getUserId(): string + protected function getUserId(): string { static $userId = NULL; diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index f23dc727..204bedee 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -78,7 +78,7 @@ final class RequestBuilder extends APIRequestBuilder elseif ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL) { $token = $sessionSegment->get('auth_token'); - if ( ! (empty($token) || $cache->has(K::AUTH_TOKEN_CACHE_KEY))) + if ( ! empty($token)) { $cache->set(K::AUTH_TOKEN_CACHE_KEY, $token); } @@ -239,43 +239,4 @@ final class RequestBuilder extends APIRequestBuilder 'body' => $body, ]); } - - /** - * Make a request - */ - private function request(string $type, string $url, array $options = []): array - { - $logger = $this->container->getLogger('kitsu-request'); - $response = $this->getResponse($type, $url, $options); - $statusCode = $response->getStatus(); - - // Check for requests that are unauthorized - if ($statusCode === 401 || $statusCode === 403) - { - Event::emit(EventType::UNAUTHORIZED); - } - - $rawBody = wait($response->getBody()->buffer()); - - // Any other type of failed request - if ($statusCode > 299 || $statusCode < 200) - { - if ($logger !== NULL) - { - $logger->warning('Non 2xx response for api call', (array) $response); - } - } - - try - { - return Json::decode($rawBody); - } - catch (JsonException) - { - // dump($e); - dump($rawBody); - - exit(); - } - } } diff --git a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php index 1ba17909..f6ce8c06 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php @@ -23,8 +23,6 @@ trait RequestBuilderTrait /** * Set the request builder object - * - * @return ListItem|Model|RequestBuilderTrait */ public function setRequestBuilder(RequestBuilder $requestBuilder): self { diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php index ea0b2b69..668e08e1 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php @@ -54,7 +54,7 @@ final class MangaTransformer extends AbstractTransformer } $details = $rawCharacter['character']; - if (array_key_exists($details['id'], $characters[$type])) + if (array_key_exists($details['id'], (array)$characters[$type])) { $characters[$type][$details['id']] = [ 'image' => Kitsu::getImage($details), diff --git a/src/AnimeClient/AnimeClient.php b/src/AnimeClient/AnimeClient.php index 86e2cfb0..ca5e53d7 100644 --- a/src/AnimeClient/AnimeClient.php +++ b/src/AnimeClient/AnimeClient.php @@ -18,7 +18,6 @@ use Amp\Http\Client\{HttpClient, HttpClientBuilder, Request, Response}; use Aviat\Ion\{ConfigInterface, ImageBuilder}; use DateTimeImmutable; -use PHPUnit\Framework\Attributes\CodeCoverageIgnore; use Psr\SimpleCache\CacheInterface; use Throwable; @@ -40,7 +39,6 @@ const MINUTES_IN_YEAR = 525_600; * * @param string $path - Path to load config */ -#[CodeCoverageIgnore] function loadConfig(string $path): array { $output = []; @@ -80,7 +78,6 @@ function loadConfig(string $path): array /** * Load config from one specific TOML file */ -#[CodeCoverageIgnore] function loadTomlFile(string $filename): array { return Toml::parseFile($filename); @@ -250,7 +247,6 @@ function getLocalImg(string $kitsuUrl, bool $webp = TRUE): string /** * Create a transparent placeholder image */ -#[CodeCoverageIgnore] function createPlaceholderImage(string $path, int $width = 200, int $height = 200, string $text = 'Image Unavailable'): bool { $img = ImageBuilder::new($width, $height) @@ -303,7 +299,6 @@ function clearCache(CacheInterface $cache): bool /** * Render a PHP code template as a string */ -#[CodeCoverageIgnore] function renderTemplate(string $path, array $data): string { ob_start(); diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index be4c807d..ea0da284 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -306,8 +306,6 @@ final class Anime extends BaseController 'Anime not found', 'Anime Not Found' ); - - return; } $this->outputHTML('anime/details', [ @@ -345,8 +343,6 @@ final class Anime extends BaseController 'Anime not found', 'Anime Not Found' ); - - return; } $this->outputHTML('anime/details', [ diff --git a/src/AnimeClient/Controller/Character.php b/src/AnimeClient/Controller/Character.php index cc0685e6..8b681632 100644 --- a/src/AnimeClient/Controller/Character.php +++ b/src/AnimeClient/Controller/Character.php @@ -59,8 +59,6 @@ final class Character extends BaseController ), 'Character Not Found' ); - - return; } $data = (new CharacterTransformer())->transform($rawData)->toArray(); diff --git a/src/AnimeClient/Controller/Images.php b/src/AnimeClient/Controller/Images.php index 0abbb1ec..58b17ddb 100644 --- a/src/AnimeClient/Controller/Images.php +++ b/src/AnimeClient/Controller/Images.php @@ -96,7 +96,7 @@ final class Images extends BaseController $kitsuUrl .= $imageType['kitsuUrl']; $width = $imageType['width']; - $height = $imageType['height']; + $height = $imageType['height'] ?? 225; $filePrefix = "{$baseSavePath}/{$type}/{$id}"; $response = getResponse($kitsuUrl); @@ -120,11 +120,11 @@ final class Images extends BaseController if ($display) { - $this->getPlaceholder("{$baseSavePath}/{$type}", $width, $height); + $this->getPlaceholder("{$baseSavePath}/{$type}", $width ?? 225, $height); } else { - createPlaceholderImage("{$baseSavePath}/{$type}", $width, $height); + createPlaceholderImage("{$baseSavePath}/{$type}", $width ?? 225, $height); } return; @@ -132,7 +132,13 @@ final class Images extends BaseController $data = wait($response->getBody()->buffer()); - [$origWidth] = getimagesizefromstring($data); + $size = getimagesizefromstring($data); + if ($size === FALSE) + { + return; + } + + [$origWidth] = $size; $gdImg = imagecreatefromstring($data); if ($gdImg === FALSE) { @@ -182,15 +188,15 @@ final class Images extends BaseController /** * Get a placeholder for a missing image */ - private function getPlaceholder(string $path, ?int $width = 200, ?int $height = NULL): void + private function getPlaceholder(string $path, ?int $width = NULL, ?int $height = NULL): void { - $height ??= $width; + $height ??= $width ?? 200; $filename = $path . '/placeholder.png'; if ( ! file_exists($path . '/placeholder.png')) { - createPlaceholderImage($path, $width, $height); + createPlaceholderImage($path, $width ?? 200, $height); } header('Content-Type: image/png'); diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index cd69a825..84840e7b 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -277,8 +277,6 @@ final class Manga extends BaseController 'Manga not found', 'Manga Not Found' ); - - return; } $this->outputHTML('manga/details', [ @@ -306,8 +304,6 @@ final class Manga extends BaseController 'Manga not found', 'Manga Not Found' ); - - return; } $this->outputHTML('manga/details', [ diff --git a/src/AnimeClient/Controller/Misc.php b/src/AnimeClient/Controller/Misc.php index f4ba9fe2..f42fe70d 100644 --- a/src/AnimeClient/Controller/Misc.php +++ b/src/AnimeClient/Controller/Misc.php @@ -101,11 +101,7 @@ final class Misc extends BaseController } $this->setFlashMessage('Invalid username or password.'); - - $redirectUrl = $this->url->generate('login'); - $redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : ''; - - $this->redirect($redirectUrl, 303); + $this->redirect($this->url->generate('login'), 303); } /** @@ -145,8 +141,6 @@ final class Misc extends BaseController ), 'Character Not Found' ); - - return; } $data = (new CharacterTransformer())->transform($rawData)->toArray(); @@ -178,8 +172,6 @@ final class Misc extends BaseController ), 'Person Not Found' ); - - return; } $this->outputHTML('person/details', [ diff --git a/src/AnimeClient/Controller/People.php b/src/AnimeClient/Controller/People.php index 5e7db3db..80dc8d3b 100644 --- a/src/AnimeClient/Controller/People.php +++ b/src/AnimeClient/Controller/People.php @@ -60,8 +60,6 @@ final class People extends BaseController ), 'Person Not Found' ); - - return; } $this->outputHTML('person/details', [ diff --git a/src/AnimeClient/Controller/Settings.php b/src/AnimeClient/Controller/Settings.php index a5ffe601..ab2979fc 100644 --- a/src/AnimeClient/Controller/Settings.php +++ b/src/AnimeClient/Controller/Settings.php @@ -86,10 +86,7 @@ final class Settings extends BaseController ? $this->setFlashMessage('Saved config settings.', 'success') : $this->setFlashMessage('Failed to save config file.', 'error'); - $redirectUrl = $this->url->generate('settings'); - $redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : ''; - - $this->redirect($redirectUrl, 303); + $this->redirect($this->url->generate('settings'), 303); } /** @@ -152,9 +149,6 @@ final class Settings extends BaseController ? $this->setFlashMessage('Linked Anilist Account', 'success') : $this->setFlashMessage('Error Linking Anilist Account', 'error'); - $redirectUrl = $this->url->generate('settings'); - $redirectUrl = ($redirectUrl !== FALSE) ? $redirectUrl : ''; - - $this->redirect($redirectUrl, 303); + $this->redirect($this->url->generate('settings'), 303); } } diff --git a/src/AnimeClient/Controller/User.php b/src/AnimeClient/Controller/User.php index 249fd4ec..5983a610 100644 --- a/src/AnimeClient/Controller/User.php +++ b/src/AnimeClient/Controller/User.php @@ -72,8 +72,6 @@ final class User extends BaseController if ($rawData['data']['findProfileBySlug'] === NULL) { $this->notFound('Sorry, user not found', "The user '{$username}' does not seem to exist."); - - return; } $data = (new UserTransformer())->transform($rawData)->toArray(); diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php index 230a0a61..97ad2a52 100644 --- a/src/AnimeClient/Dispatcher.php +++ b/src/AnimeClient/Dispatcher.php @@ -82,11 +82,8 @@ final class Dispatcher extends RoutingBase { $route = $this->getRoute(); - if ($logger !== NULL) - { - $logger->info('Dispatcher - Route invoke arguments'); - $logger->info(print_r($route, TRUE)); - } + $logger?->info('Dispatcher - Route invoke arguments'); + $logger?->info(print_r($route, TRUE)); } if ( ! $route) @@ -183,10 +180,7 @@ final class Dispatcher extends RoutingBase } $logger = $this->container->getLogger(); - if ($logger !== NULL) - { - $logger->info(Json::encode($params)); - } + $logger?->info(Json::encode($params)); return [ 'controller_name' => $controllerName, @@ -208,10 +202,7 @@ final class Dispatcher extends RoutingBase $controller = reset($segments); $logger = $this->container->getLogger(); - if ($logger !== NULL) - { - $logger->info('Controller: ' . $controller); - } + $logger?->info('Controller: ' . $controller); if (empty($controller)) { @@ -224,7 +215,7 @@ final class Dispatcher extends RoutingBase /** * Get the list of controllers in the default namespace * - * @return mixed[] + * @return array */ public function getControllerList(): array { @@ -300,7 +291,6 @@ final class Dispatcher extends RoutingBase /** * Get the appropriate params for the error page * passed on the failed route - * @return mixed[][] */ protected function getErrorParams(): array { @@ -317,7 +307,7 @@ final class Dispatcher extends RoutingBase $params = []; - switch ($failure->failedRule) + switch ($failure?->failedRule) { case Rule\Allows::class: $params = [ @@ -349,8 +339,6 @@ final class Dispatcher extends RoutingBase /** * Select controller based on the current url, and apply its relevant routes - * - * @return mixed[] */ protected function setupRoutes(): array { diff --git a/src/AnimeClient/Model/AnimeCollection.php b/src/AnimeClient/Model/AnimeCollection.php index 1ff1ff2f..8d8f7048 100644 --- a/src/AnimeClient/Model/AnimeCollection.php +++ b/src/AnimeClient/Model/AnimeCollection.php @@ -91,7 +91,7 @@ final class AnimeCollection extends Collection $genres = $this->getGenreList(); $media = $this->getMediaList(); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -133,7 +133,7 @@ final class AnimeCollection extends Collection ->get(); $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -349,7 +349,7 @@ final class AnimeCollection extends Collection ->get() ->fetchAll(PDO::FETCH_ASSOC); - if ($mediaRows === FALSE) + if (empty($mediaRows)) { return []; } @@ -411,7 +411,7 @@ final class AnimeCollection extends Collection ->get(); $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -479,7 +479,7 @@ final class AnimeCollection extends Collection ->get(); $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -659,7 +659,7 @@ final class AnimeCollection extends Collection ->get(); $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -691,7 +691,7 @@ final class AnimeCollection extends Collection ->get(); $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } @@ -737,7 +737,7 @@ final class AnimeCollection extends Collection // Add genres associated with each item $rows = $query->fetchAll(PDO::FETCH_ASSOC); - if ($rows === FALSE) + if (empty($rows)) { return []; } diff --git a/src/Ion/Json.php b/src/Ion/Json.php index 3861d322..781c77ea 100644 --- a/src/Ion/Json.php +++ b/src/Ion/Json.php @@ -25,7 +25,10 @@ class Json /** * Encode data in json format * - * @throws JsonException + * @param mixed $data + * @param int $options + * @param int<1, max> $depth + * @return string */ public static function encode(mixed $data, int $options = 0, int $depth = 512): string { @@ -54,7 +57,11 @@ class Json /** * Decode data from json * - * @throws JsonException + * @param string|null $json + * @param bool $assoc + * @param int<1, max> $depth + * @param int $options + * @return mixed */ public static function decode(?string $json, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed { @@ -74,7 +81,11 @@ class Json /** * Decode json data loaded from the passed filename * - * @throws JsonException + * @param string $filename + * @param bool $assoc + * @param int<1, max> $depth + * @param int $options + * @return mixed */ public static function decodeFile(string $filename, bool $assoc = TRUE, int $depth = 512, int $options = 0): mixed { diff --git a/src/Ion/Type/StringType.php b/src/Ion/Type/StringType.php index d8e3cfed..e91d402d 100644 --- a/src/Ion/Type/StringType.php +++ b/src/Ion/Type/StringType.php @@ -24,9 +24,9 @@ final class StringType extends Stringy /** * Alias for `create` static constructor */ - public static function from(string $str): self + public static function from(string $str = '', ?string $encoding = NULL): self { - return self::create($str); + return self::create($str, $encoding); } /** diff --git a/src/Ion/Type/Stringy.php b/src/Ion/Type/Stringy.php index 5491b6db..147f6435 100644 --- a/src/Ion/Type/Stringy.php +++ b/src/Ion/Type/Stringy.php @@ -66,7 +66,7 @@ abstract class Stringy implements Countable, IteratorAggregate, ArrayAccess * @throws InvalidArgumentException if an array or object without a * __toString method is passed as the first argument */ - public function __construct(mixed $str = '', ?string $encoding = NULL) + final public function __construct(mixed $str = '', ?string $encoding = NULL) { if (is_array($str)) { diff --git a/src/Ion/View/HtmlView.php b/src/Ion/View/HtmlView.php index c1fbe1bf..231ab556 100644 --- a/src/Ion/View/HtmlView.php +++ b/src/Ion/View/HtmlView.php @@ -34,11 +34,11 @@ class HtmlView extends HttpView /** * Create the Html View */ - public function __construct(ContainerInterface $container) + public function __construct() { parent::__construct(); - $this->setContainer($container); + $this->setContainer(func_get_arg(0)); $this->response = new HtmlResponse(''); } diff --git a/tests/AnimeClient/AnimeClientTest.php b/tests/AnimeClient/AnimeClientTest.php index 425b0281..8893eef3 100644 --- a/tests/AnimeClient/AnimeClientTest.php +++ b/tests/AnimeClient/AnimeClientTest.php @@ -15,12 +15,17 @@ namespace Aviat\AnimeClient\Tests; use DateTime; +use PHPUnit\Framework\Attributes\IgnoreFunctionForCodeCoverage; use function Aviat\AnimeClient\{arrayToToml, checkFolderPermissions, clearCache, colNotEmpty, friendlyTime, getLocalImg, getResponse, isSequentialArray, tomlToArray}; use const Aviat\AnimeClient\{MINUTES_IN_DAY, MINUTES_IN_HOUR, MINUTES_IN_YEAR, SECONDS_IN_MINUTE}; /** * @internal */ +#[IgnoreFunctionForCodeCoverage('Aviat\AnimeClient\loadConfig')] +#[IgnoreFunctionForCodeCoverage('Aviat\AnimeClient\createPlaceholderImage')] +#[IgnoreFunctionForCodeCoverage('Aviat\AnimeClient\renderTemplate')] +#[IgnoreFunctionForCodeCoverage('Aviat\AnimeClient\getLocalImg')] final class AnimeClientTest extends AnimeClientTestCase { public function testArrayToToml(): void diff --git a/tests/Ion/ConfigTest.php b/tests/Ion/ConfigTest.php index 6bc26181..c32d9010 100644 --- a/tests/Ion/ConfigTest.php +++ b/tests/Ion/ConfigTest.php @@ -16,10 +16,12 @@ namespace Aviat\Ion\Tests; use Aviat\Ion\Config; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\IgnoreMethodForCodeCoverage; /** * @internal */ +#[IgnoreMethodForCodeCoverage(Config::class, 'set')] final class ConfigTest extends IonTestCase { protected Config $config; diff --git a/tests/Ion/Type/StringTypeTest.php b/tests/Ion/Type/StringTypeTest.php index 8535e342..1a762153 100644 --- a/tests/Ion/Type/StringTypeTest.php +++ b/tests/Ion/Type/StringTypeTest.php @@ -16,11 +16,15 @@ namespace Aviat\Ion\Tests\Type; use Aviat\Ion\Tests\IonTestCase; use Aviat\Ion\Type\StringType; +use Aviat\Ion\Type\Stringy; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage; +use PHPUnit\Framework\Attributes\Test; /** * @internal */ +#[IgnoreClassForCodeCoverage(Stringy::class)] final class StringTypeTest extends IonTestCase { public static function dataFuzzyCaseMatch(): array @@ -55,7 +59,8 @@ final class StringTypeTest extends IonTestCase } #[DataProvider('dataFuzzyCaseMatch')] - public function testFuzzyCaseMatch(string $str1, string $str2, bool $expected): void + #[Test] + public function fuzzyCaseMatch(string $str1, string $str2, bool $expected): void { $actual = StringType::from($str1)->fuzzyCaseMatch($str2); $this->assertSame($expected, $actual); diff --git a/tests/Ion/View/HttpViewTest.php b/tests/Ion/View/HttpViewTest.php index ec8acf4f..918ecab5 100644 --- a/tests/Ion/View/HttpViewTest.php +++ b/tests/Ion/View/HttpViewTest.php @@ -27,6 +27,7 @@ class HttpViewTest extends IonTestCase { parent::setUp(); $this->view = new TestHttpView(); + $this->view = TestHttpView::new(); $this->friend = new Friend($this->view); } diff --git a/tests/Ion/functionsTest.php b/tests/Ion/functionsTest.php index 3e28bdb1..1d77b2f8 100644 --- a/tests/Ion/functionsTest.php +++ b/tests/Ion/functionsTest.php @@ -14,6 +14,8 @@ namespace Aviat\Ion\Tests; +use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use function Aviat\Ion\_dir; @@ -22,9 +24,14 @@ use const DIRECTORY_SEPARATOR; /** * @internal */ +#[IgnoreClassForCodeCoverage(\Aviat\Ion\ImageBuilder::class)] +#[IgnoreClassForCodeCoverage(\Aviat\Ion\Attribute\Controller::class)] +#[IgnoreClassForCodeCoverage(\Aviat\Ion\Attribute\DefaultController::class)] +#[IgnoreClassForCodeCoverage(\Aviat\Ion\Attribute\Route::class)] final class functionsTest extends TestCase { - public function testDir() + #[Test] + public function dir(): void { $args = ['foo', 'bar', 'baz']; $expected = implode(DIRECTORY_SEPARATOR, $args);