diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 00000000..39ba0902 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# Pre-commit hook to run lightweight checks and auto-format the code. It's designed +# to be blazingly fast, so it checks only changed files. Run the following command +# to install this hook for yourself. It's a symlink, to make sure it stays always +# up-to-date. +# +# ```bash +# ln -s ../../.githooks/pre-commit .git/hooks/pre-commit +# ``` + +set -euxo pipefail + +function command_exists() { + bin_name=$(basename "$1") + + if command -v "$1" &> /dev/null; then + printf "\e[0;32m[INFO] Using %s...\e[0m\n" "$bin_name" + return 0 + fi + + printf "\e[0;33m[WARN] %s CLI was not found. Ignoring it...\e[0m\n" "$bin_name" >&2 + return 1 +} + +files=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') + +if [[ -z "$files" ]]; then + echo "No files changed. Exiting the pre-commit hook..." + exit 0 +fi + +if command_exists typos; then + echo "$files" | xargs typos +fi + +if command_exists ./node_modules/.bin/prettier; then + echo "$files" | xargs ./node_modules/.bin/prettier --ignore-unknown --write +fi + +if command_exists cargo; then + # `rustfmt` doesn't ignore non-rust files automatically + rust_files=$(echo "$files" | { grep -E '\.rs$' || true; }) + + if [[ -n "$rust_files" ]]; then + echo "$rust_files" | xargs cargo fmt --manifest-path native/Cargo.toml -- + fi +fi + +if command_exists mix; then + echo "$files" | xargs mix format --check-formatted +fi + +# Add the modified/prettified files to staging +echo "$files" | xargs git add + +exit 0 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f3d5c415..5ad98142 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,7 +4,6 @@ about: Create a report to help us improve title: '' labels: bug assignees: '' - --- **Describe the bug** @@ -12,6 +11,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 11fc491e..5f0a04ce 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,7 +4,6 @@ about: Suggest an idea for this project title: '' labels: enhancement assignees: '' - --- **Is your feature request related to a problem? Please describe.** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 652369bb..4f3922bb 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,10 @@ ### Before you begin -* I understand my contributions may be rejected for any reason -* I understand my contributions are for the benefit of Derpibooru and/or the Philomena software -* I understand my contributions are licensed under the GNU AGPLv3 +- I understand my contributions may be rejected for any reason +- I understand my contributions are for the benefit of Derpibooru and/or the Philomena software +- I understand my contributions are licensed under the GNU AGPLv3 -- [ ] I understand all of the above +* [ ] I understand all of the above --- diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index a5099702..645897eb 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -59,6 +59,18 @@ jobs: - name: cargo test run: (cd native/philomena && cargo test) + prettier: + name: 'Prettier Formatting Check' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + - run: npm ci --ignore-scripts + - run: npx prettier --check . + lint-and-test: name: 'JavaScript Linting and Unit Tests' runs-on: ubuntu-latest @@ -68,18 +80,10 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' + cache: 'npm' - - name: Cache node_modules - id: cache-node-modules - uses: actions/cache@v4 - with: - path: ./assets/node_modules - key: node_modules-${{ hashFiles('./assets/package-lock.json') }} - - - name: Install npm dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: npm ci --ignore-scripts + - run: npm ci --ignore-scripts working-directory: ./assets - run: npm run lint diff --git a/assets/.prettierrc.yml b/.prettierrc.yml similarity index 91% rename from assets/.prettierrc.yml rename to .prettierrc.yml index 83cfc971..c658d5c1 100644 --- a/assets/.prettierrc.yml +++ b/.prettierrc.yml @@ -9,6 +9,6 @@ quoteProps: as-needed trailingComma: all arrowParens: avoid overrides: - - files: "*.css" + - files: '*.css' options: singleQuote: false diff --git a/README.md b/README.md index 966d5e06..c0ae0caf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Philomena +  ## Getting started + On systems with `docker` and `docker compose` installed, the process should be as simple as: ``` @@ -23,11 +25,13 @@ Once the application has started, navigate to http://localhost:8080 and login wi If you are running Docker on Windows and the application crashes immediately upon startup, please ensure that `autocrlf` is set to `false` in your Git config, and then re-clone the repository. Additionally, it is recommended that you allocate at least 4GB of RAM to your Docker VM. If you run into an OpenSearch bootstrap error, you may need to increase your `max_map_count` on the host as follows: + ``` sudo sysctl -w vm.max_map_count=262144 ``` If you have SELinux enforcing (Fedora, Arch, others; manifests as a `Could not find a Mix.Project` error), you should run the following in the application directory on the host before proceeding: + ``` chcon -Rt svirt_sandbox_file_t . ``` @@ -37,6 +41,7 @@ This allows Docker or Podman to bind mount the application directory into the co If you are using a platform which uses cgroups v2 by default (Fedora 31+), use `podman` and `podman-compose`. ## Deployment + You need a key installed on the server you target, and the git remote installed in your ssh configuration. git remote add production philomena@<serverip>:philomena/ diff --git a/assets/.stylelintrc.yml b/assets/.stylelintrc.yml index c4eba511..e513ddac 100644 --- a/assets/.stylelintrc.yml +++ b/assets/.stylelintrc.yml @@ -1,20 +1,18 @@ --- extends: stylelint-config-recommended -plugins: - - stylelint-prettier rules: block-no-empty: true at-rule-no-unknown: - true - ignoreAtRules: - - mixin - - define-mixin + - mixin + - define-mixin media-query-no-invalid: rule-empty-line-before: - always-multi-line - except: - - after-single-line-comment - - first-nested + - after-single-line-comment + - first-nested declaration-block-no-duplicate-custom-properties: true declaration-block-no-duplicate-properties: true font-family-no-duplicate-names: true @@ -47,10 +45,10 @@ rules: at-rule-empty-line-before: - always - except: - - first-nested + - first-nested ignore: - - after-comment - - blockless-after-blockless + - after-comment + - blockless-after-blockless custom-property-empty-line-before: never declaration-empty-line-before: never declaration-block-single-line-max-declarations: 3 @@ -75,4 +73,3 @@ rules: declaration-block-no-redundant-longhand-properties: true shorthand-property-no-redundant-values: true comment-whitespace-inside: always - prettier/prettier: true diff --git a/assets/css/application.css b/assets/css/application.css index 31c177a9..a6ae2827 100644 --- a/assets/css/application.css +++ b/assets/css/application.css @@ -56,4 +56,4 @@ @import "views/search"; @import "views/staff"; @import "views/stats"; -@import "views/tags"; \ No newline at end of file +@import "views/tags"; diff --git a/assets/eslint.config.js b/assets/eslint.config.js index 51715805..51cc1e26 100644 --- a/assets/eslint.config.js +++ b/assets/eslint.config.js @@ -1,11 +1,9 @@ import tsEslint from 'typescript-eslint'; import vitestPlugin from 'eslint-plugin-vitest'; -import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import globals from 'globals'; export default tsEslint.config( ...tsEslint.configs.recommended, - eslintPluginPrettierRecommended, { name: 'PhilomenaConfig', files: ['**/*.js', '**/*.ts'], @@ -22,69 +20,37 @@ export default tsEslint.config( }, rules: { 'accessor-pairs': 2, - 'array-bracket-spacing': 0, 'array-callback-return': 2, - 'arrow-body-style': 0, - 'arrow-spacing': 2, 'block-scoped-var': 2, - 'block-spacing': 2, - 'callback-return': 0, camelcase: [2, { allow: ['camo_url', 'spoiler_image_uri', 'image_ids'] }], 'class-methods-use-this': 0, - 'comma-dangle': [2, 'only-multiline'], - 'comma-spacing': 2, - 'comma-style': 2, complexity: 0, - 'computed-property-spacing': [2, 'never'], 'consistent-return': 0, 'consistent-this': [2, 'that'], 'constructor-super': 2, curly: [2, 'multi-line', 'consistent'], 'default-case': 2, - 'dot-location': [2, 'property'], 'dot-notation': [2, { allowKeywords: true }], - 'eol-last': 2, eqeqeq: 2, - 'func-call-spacing': 0, 'func-name-matching': 2, 'func-names': 0, 'func-style': 0, - 'generator-star-spacing': 2, - 'global-require': 2, 'guard-for-in': 0, - 'handle-callback-err': 2, - 'id-blacklist': 0, 'id-length': 0, 'id-match': 2, 'init-declarations': 0, - 'jsx-quotes': 0, - 'key-spacing': 0, - 'keyword-spacing': 2, - 'line-comment-position': 0, - 'linebreak-style': [2, 'unix'], - 'lines-around-comment': 0, - 'lines-around-directive': 2, 'max-depth': 0, - 'max-len': 0, 'max-lines': 0, 'max-nested-callbacks': 0, 'max-params': 0, - 'max-statements-per-line': 0, 'max-statements': 0, - 'multiline-ternary': 0, 'new-cap': 2, - 'new-parens': 2, - 'newline-after-var': 0, - 'newline-before-return': 0, - 'newline-per-chained-call': 0, 'no-alert': 0, 'no-array-constructor': 2, 'no-caller': 2, 'no-case-declarations': 2, - 'no-catch-shadow': 2, 'no-class-assign': 2, 'no-cond-assign': 2, - 'no-confusing-arrow': 2, 'no-console': 0, 'no-const-assign': 2, 'no-constant-condition': 2, @@ -109,10 +75,7 @@ export default tsEslint.config( 'no-extra-bind': 2, 'no-extra-boolean-cast': 2, 'no-extra-label': 2, - 'no-extra-parens': [2, 'all', { nestedBinaryExpressions: false }], - 'no-extra-semi': 2, 'no-fallthrough': 2, - 'no-floating-decimal': 2, 'no-func-assign': 2, 'no-global-assign': 2, 'no-implicit-coercion': 2, @@ -130,37 +93,24 @@ export default tsEslint.config( 'no-lonely-if': 0, 'no-loop-func': 2, 'no-magic-numbers': 0, - 'no-mixed-operators': 0, - 'no-mixed-requires': 0, - 'no-mixed-spaces-and-tabs': 2, - 'no-multi-spaces': 0, 'no-multi-str': 2, - 'no-multiple-empty-lines': [2, { max: 3, maxBOF: 0, maxEOF: 1 }], - 'no-native-reassign': 2, 'no-negated-condition': 0, - 'no-negated-in-lhs': 2, 'no-nested-ternary': 2, 'no-new-func': 2, - 'no-new-object': 2, - 'no-new-require': 2, - 'no-new-symbol': 2, 'no-new-wrappers': 2, 'no-new': 2, 'no-obj-calls': 2, + 'no-object-constructor': 2, 'no-octal-escape': 2, 'no-octal': 2, 'no-param-reassign': 2, - 'no-path-concat': 2, 'no-plusplus': 0, - 'no-process-env': 2, - 'no-process-exit': 2, 'no-proto': 2, 'no-prototype-builtins': 0, 'no-redeclare': 2, 'no-regex-spaces': 2, 'no-restricted-globals': [2, 'event'], 'no-restricted-imports': 2, - 'no-restricted-modules': 2, 'no-restricted-properties': 0, 'no-restricted-syntax': 2, 'no-return-assign': 0, @@ -169,16 +119,11 @@ export default tsEslint.config( 'no-self-compare': 2, 'no-sequences': 2, 'no-shadow-restricted-names': 2, - 'no-shadow': 2, - 'no-spaced-func': 2, 'no-sparse-arrays': 2, - 'no-sync': 0, - 'no-tabs': 2, 'no-template-curly-in-string': 2, 'no-ternary': 0, 'no-this-before-super': 2, 'no-throw-literal': 2, - 'no-trailing-spaces': 2, 'no-undef-init': 2, 'no-undef': 2, 'no-undefined': 0, @@ -202,50 +147,29 @@ export default tsEslint.config( 'no-var': 2, 'no-void': 2, 'no-warning-comments': 0, - 'no-whitespace-before-property': 2, 'no-with': 2, - 'object-curly-newline': 0, - 'object-curly-spacing': 0, - 'object-property-newline': 0, 'object-shorthand': 2, - 'one-var-declaration-per-line': 0, 'one-var': 0, 'operator-assignment': [2, 'always'], - 'operator-linebreak': 0, - 'padded-blocks': 0, 'prefer-arrow-callback': 2, 'prefer-const': 2, 'prefer-numeric-literals': 2, - 'prefer-reflect': 0, 'prefer-rest-params': 2, 'prefer-spread': 0, 'prefer-template': 2, - 'quote-props': [2, 'as-needed'], radix: 2, 'require-jsdoc': 0, 'require-yield': 2, - 'rest-spread-spacing': 2, - 'semi-spacing': [2, { before: false, after: true }], - semi: 2, 'sort-imports': 0, 'sort-keys': 0, 'sort-vars': 0, - 'space-before-blocks': [2, 'always'], - 'space-in-parens': [2, 'never'], - 'space-infix-ops': 2, - 'space-unary-ops': [2, { words: true, nonwords: false }], - 'spaced-comment': 0, strict: [2, 'function'], 'symbol-description': 2, - 'template-curly-spacing': [2, 'never'], 'unicode-bom': 2, 'use-isnan': 2, 'valid-jsdoc': 0, 'valid-typeof': 2, 'vars-on-top': 2, - 'wrap-iife': 2, - 'wrap-regex': 0, - 'yield-star-spacing': 2, yoda: [2, 'never'], }, ignores: ['js/vendor/*', 'vite.config.ts'], @@ -266,10 +190,6 @@ export default tsEslint.config( 'no-redeclare': 'off', 'no-shadow': 'off', - // Often conflicts with prettier. - // TODO: prettier should just be enforced by CI. - 'no-extra-parens': 'off', - '@typescript-eslint/no-unused-vars': [ 2, { vars: 'all', args: 'after-used', varsIgnorePattern: '^_.*', argsIgnorePattern: '^_.*' }, diff --git a/assets/js/boorujs.js b/assets/js/boorujs.js index 86d9901b..87e05003 100644 --- a/assets/js/boorujs.js +++ b/assets/js/boorujs.js @@ -9,25 +9,47 @@ import { fetchHtml, handleError } from './utils/requests'; import { showBlock } from './utils/image'; import { addTag } from './tagsinput'; -/* eslint-disable prettier/prettier */ - // Event types and any qualifying conditions - return true to not run action const types = { - click(event) { return event.button !== 0; /* Left-click only */ }, - change() { /* No qualifier */ }, - fetchcomplete() { /* No qualifier */ }, + click(event) { + return event.button !== 0; /* Left-click only */ + }, + change() { + /* No qualifier */ + }, + fetchcomplete() { + /* No qualifier */ + }, }; const actions = { - hide(data) { selectorCb(data.base, data.value, el => el.classList.add('hidden')); }, - show(data) { selectorCb(data.base, data.value, el => el.classList.remove('hidden')); }, - toggle(data) { selectorCb(data.base, data.value, el => el.classList.toggle('hidden')); }, - submit(data) { selectorCb(data.base, data.value, el => el.submit()); }, - disable(data) { selectorCb(data.base, data.value, el => el.disabled = true); }, - focus(data) { document.querySelector(data.value).focus(); }, - unfilter(data) { showBlock(data.el.closest('.image-show-container')); }, - tabHide(data) { selectorCbChildren(data.base, data.value, el => el.classList.add('hidden')); }, - preventdefault() { /* The existence of this entry is enough */ }, + hide(data) { + selectorCb(data.base, data.value, el => el.classList.add('hidden')); + }, + show(data) { + selectorCb(data.base, data.value, el => el.classList.remove('hidden')); + }, + toggle(data) { + selectorCb(data.base, data.value, el => el.classList.toggle('hidden')); + }, + submit(data) { + selectorCb(data.base, data.value, el => el.submit()); + }, + disable(data) { + selectorCb(data.base, data.value, el => (el.disabled = true)); + }, + focus(data) { + document.querySelector(data.value).focus(); + }, + unfilter(data) { + showBlock(data.el.closest('.image-show-container')); + }, + tabHide(data) { + selectorCbChildren(data.base, data.value, el => el.classList.add('hidden')); + }, + preventdefault() { + /* The existence of this entry is enough */ + }, copy(data) { document.querySelector(data.value).select(); @@ -61,8 +83,8 @@ const actions = { tab(data) { const block = data.el.parentNode.parentNode, - newTab = $(`.block__tab[data-tab="${data.value}"]`), - loadTab = data.el.dataset.loadTab; + newTab = $(`.block__tab[data-tab="${data.value}"]`), + loadTab = data.el.dataset.loadTab; // Switch tab const selectedTab = block.querySelector('.selected'); @@ -80,15 +102,13 @@ const actions = { fetchHtml(loadTab) .then(handleError) .then(response => response.text()) - .then(response => newTab.innerHTML = response) - .then(() => newTab.dataset.loaded = true) - .catch(() => newTab.textContent = 'Error!'); + .then(response => (newTab.innerHTML = response)) + .then(() => (newTab.dataset.loaded = true)) + .catch(() => (newTab.textContent = 'Error!')); } }, }; -/* eslint-enable prettier/prettier */ - // Use this function to apply a callback to elements matching the selectors function selectorCb(base = document, selector, cb) { [].forEach.call(base.querySelectorAll(selector), cb); diff --git a/assets/js/shortcuts.ts b/assets/js/shortcuts.ts index 3de21c89..52071b31 100644 --- a/assets/js/shortcuts.ts +++ b/assets/js/shortcuts.ts @@ -47,8 +47,7 @@ function isOK(event: KeyboardEvent): boolean { ); } -/* eslint-disable prettier/prettier */ - +// prettier-ignore const keyCodes: ShortcutKeyMap = { 74() { click('.js-prev'); }, // J - go to previous image 73() { click('.js-up'); }, // I - go to index page @@ -68,8 +67,6 @@ const keyCodes: ShortcutKeyMap = { }, }; -/* eslint-enable prettier/prettier */ - export function listenForKeys() { document.addEventListener('keydown', (event: KeyboardEvent) => { if (isOK(event) && keyCodes[event.keyCode]) { diff --git a/assets/js/tags.ts b/assets/js/tags.ts index 8a0568fc..deb3c7bd 100644 --- a/assets/js/tags.ts +++ b/assets/js/tags.ts @@ -26,18 +26,40 @@ function createTagDropdown(tag: HTMLSpanElement) { const [unwatched, watched, spoilered, hidden] = $$<HTMLSpanElement>('.tag__state', tag); const tagId = parseInt(assertNotUndefined(tag.dataset.tagId), 10); - /* eslint-disable prettier/prettier */ const actions: TagDropdownActionList = { - unwatch() { hideEl(unwatch, watched); showEl(watch, unwatched); removeTag(tagId, watchedTagList); }, - watch() { hideEl(watch, unwatched); showEl(unwatch, watched); addTag(tagId, watchedTagList); }, + unwatch() { + hideEl(unwatch, watched); + showEl(watch, unwatched); + removeTag(tagId, watchedTagList); + }, + watch() { + hideEl(watch, unwatched); + showEl(unwatch, watched); + addTag(tagId, watchedTagList); + }, - unspoiler() { hideEl(unspoiler, spoilered); showEl(spoiler); removeTag(tagId, spoileredTagList); }, - spoiler() { hideEl(spoiler); showEl(unspoiler, spoilered); addTag(tagId, spoileredTagList); }, + unspoiler() { + hideEl(unspoiler, spoilered); + showEl(spoiler); + removeTag(tagId, spoileredTagList); + }, + spoiler() { + hideEl(spoiler); + showEl(unspoiler, spoilered); + addTag(tagId, spoileredTagList); + }, - unhide() { hideEl(unhide, hidden); showEl(hide); removeTag(tagId, hiddenTagList); }, - hide() { hideEl(hide); showEl(unhide, hidden); addTag(tagId, hiddenTagList); }, + unhide() { + hideEl(unhide, hidden); + showEl(hide); + removeTag(tagId, hiddenTagList); + }, + hide() { + hideEl(hide); + showEl(unhide, hidden); + addTag(tagId, hiddenTagList); + }, }; - /* eslint-enable prettier/prettier */ const tagIsWatched = watchedTagList.includes(tagId); const tagIsSpoilered = spoileredTagList.includes(tagId); diff --git a/assets/package-lock.json b/assets/package-lock.json index 412aaa4f..52ea697b 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -22,13 +22,9 @@ "@testing-library/jest-dom": "^6.6.3", "@vitest/coverage-v8": "^2.1.9", "eslint": "^9.16.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-vitest": "^0.5.4", - "prettier": "^3.4.2", "stylelint": "^16.11.0", "stylelint-config-standard": "^36.0.1", - "stylelint-prettier": "^5.0.2", "typescript-eslint": "8.17.0", "vitest": "^2.1.9", "vitest-fetch-mock": "^0.4.2" @@ -1120,18 +1116,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", @@ -2517,48 +2501,6 @@ } } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-plugin-vitest": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz", @@ -2828,12 +2770,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -4121,33 +4057,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", @@ -4628,22 +4537,6 @@ "stylelint": "^16.1.0" } }, - "node_modules/stylelint-prettier": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-5.0.2.tgz", - "integrity": "sha512-qJ+BN+1T2ZcKz9WIrv0x+eFGHzSUnXfXd5gL///T6XoJvr3D8/ztzz2fhtmXef7Vb8P33zBXmLTTveByr0nwBw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "prettier": ">=3.0.0", - "stylelint": ">=16.0.0" - } - }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", @@ -4750,22 +4643,6 @@ "optional": true, "peer": true }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/table": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", @@ -4992,12 +4869,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/assets/package.json b/assets/package.json index 41b85269..a2cf1ae2 100644 --- a/assets/package.json +++ b/assets/package.json @@ -27,13 +27,9 @@ "@testing-library/jest-dom": "^6.6.3", "@vitest/coverage-v8": "^2.1.9", "eslint": "^9.16.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-vitest": "^0.5.4", - "prettier": "^3.4.2", "stylelint": "^16.11.0", "stylelint-config-standard": "^36.0.1", - "stylelint-prettier": "^5.0.2", "typescript-eslint": "8.17.0", "vitest": "^2.1.9", "vitest-fetch-mock": "^0.4.2" diff --git a/assets/tsconfig.json b/assets/tsconfig.json index e825a6a0..83fba68a 100644 --- a/assets/tsconfig.json +++ b/assets/tsconfig.json @@ -6,11 +6,7 @@ "esModuleInterop": true, "allowJs": true, "skipLibCheck": true, - "lib": [ - "ES2016", - "DOM", - "DOM.Iterable" - ], + "lib": ["ES2016", "DOM", "DOM.Iterable"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, diff --git a/config/avatar.json b/config/avatar.json index 577db737..baa37b40 100644 --- a/config/avatar.json +++ b/config/avatar.json @@ -1,264 +1,129 @@ { "header": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"125\" height=\"125\" viewBox=\"0 0 125 125\" class=\"avatar-svg\">", "background": "<rect width=\"125\" height=\"125\" fill=\"#c6dff2\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony" - ], + "species": ["unicorn", "pegasus", "earthpony"], "body_shapes": [ { "shape": "<path d=\"M73.054 24.46c25.886 0 39.144 26.39 28.916 44.95 1.263.38 4.924 2.274 3.41 4.8-1.516 2.525-7.577 16.288-27.78 14.773-1.01 6.44-.33 12.613 1.642 22.854 1.39 7.224-.632 14.648-.632 14.648s-47.785.216-73.74-.127c-1.883-6.387 8.964-25.76 20.833-24.748 15.674 1.334 19.193 1.64 21.592-2.02 2.4-3.662 0-23.234-3.535-30.81-3.536-7.577-7.83-40.785 29.294-44.32z\" fill=\"#BODY_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] } ], "tail_shapes": [ { "shape": "<path d=\"M15.456 109.15C12.02 97.805 6.44 95.036-.794 98.89v19.102c5.13-10.09 10.263-8.294 15.395-5.7\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] } ], "hair_shapes": [ { "shape": "<path d=\"M76.48 11.35c2.215.014 4.26.185 6.02.518l4.624.875-4.67.657c-5.435.77-7.802 1.83-10.266 3.833 14.608-2.52 25.094 1.816 32.14 8.69 7.51 7.337 11.223 17.454 12.508 25.286l.363 2.236-1.8-1.548c-6.914-5.983-15.308-9.988-25.68-11.48 2.26 1.687 4.477 3.113 6.764 3.932l2.81 1.005-2.97.487c-7.684 1.264-15.37-2.687-22.687-6.52-7.162-3.754-13.99-7.357-19.843-6.578-3.708 5.568-5.84 11.828-5.882 17.63-.03 3.945.886 7.66 2.9 10.84l.37.47.022.027.018.028c.168.26.328.52.496.78.833 1.085 1.808 2.098 2.934 3.02l2.065 1.685-2.49-.3c3.97 7.734 5.85 15.703 6.24 22.54.24 4.19-.07 7.95-.825 10.985-.753 3.038-1.905 5.37-3.577 6.688l-1.516 1.195.105-1.823c.16-2.637.47-5.577.123-8.528-.38.702-.825 1.36-1.32 1.977-1.43 1.746-3.414 3.064-5.934 3.426-2.517.365-5.498-.217-8.956-2.01l-1.7-.884 1.87-.544c2.374-.69 4.147-1.565 5.465-2.575-.7.033-1.4 0-2.092-.09-4.135-.542-7.932-2.934-10.414-5.09l-1.19-1.038 1.612-.294c5.34-.965 9.6-3.222 11.54-6.996 1.945-3.775 1.67-9.254-2.587-16.895-2.502-4.487-4.24-8.59-5.29-12.398-.267-.588-.497-1.19-.69-1.802-.656-2.083-.868-4.297-.564-6.545-.022-1.894.146-3.72.496-5.49 1.48-7.405 6.09-13.753 12.596-20.25h-.003C51.55 16.54 57.96 14.01 64.518 12.62c4.104-.868 8.265-1.287 11.958-1.262z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M61.346 30.543s6.965 1.786 2.68 9.464c3.497-.7 27.61.684 44.068 3.636 1.028-5.24.59-5.866.262-8.384 2.537 2.828 3.104 5.216 3.53 9.122 2.952.627 5.52 1.313 7.496 2.054-.536-9.822-5.893-47.68-61.428-27.143-5.715 3.75-11.965 12.143-11.965 12.143s-8.394 11.07-5.536 28.928c1.62 10.127 6.428 21.43-1.608 40.715 2.5 2.14 19.108 5.534 26.072 4.463 1.607-9.107-2.617-39.046-9.107-45.536-4.464-4.464-6.445-10.326-4.106-16.786 3.75-10.356 9.642-12.677 9.642-12.677z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M58.93 30.714c4.463.536 8.75 2.59 4.64 12.68 7.144-.18 29.02-.358 33.305-6.608 0 0 1.07 5-1.43 6.07 10.766-1.87 24.773-9.743 16.274-19.82-12.5-14.822-40.827-12.143-55.827-2.68-15 9.465-20.068 23.473-17.143 36.25 3.393 14.823 14.378 36.825 1.7 50.218 8.213.714 21.546-12.46 21.693-22.18.178-11.787-5.357-24.287-10.18-29.823-4.82-5.534-3.392-17.856 6.966-24.106z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M54.3 19.6c19.19-14.947 44.49-12.68 62.386-4.014 4.697 2.275 11.857 12.1-3.583 12.05 10.746 3.893 11.87 22.562 6.702 24.558-5.956 2.3-10.71-7.422-10.227-13.637-2.522 11.215-8.36 22.893-13.84 18.31-4.597-3.846-4.192-8.617-.95-13.764-5.694 4.724-11.298 7.872-16.992 3.566-5.77 3.204-10.776 8.625-17.182 5.93-7.935-3.34-1.024-13.468 3.976-17.143-7.308-.314-9.815 3.454-14.432 12.895 2.963 17.85 19.438 32.202 18.517 49.25-.536 9.916-4.688 10.88-5.852 2.51 1.696 25.253-8.634 24.816-9.356 13.904-9.447 16.2-13.625 4.51-10.93-4.183 2.054-6.628 4.03-12.16 6.425-16.777-2.547 7.66-7.333 5.232-8.583 4.43-2.854-1.834-.855-12.302 4.035-19.33 8.3-11.93-23.73-30.172 2.47-53.197\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M64.335 34.675c3.358 1.584 6.716.908 10.073 1.043-.265 13.078 19.05 19.74 31.58 4.16 6.077 6.273 24.776 2.28 12.42-18.66-12.88-21.833-42.605-11.287-61-.5l-7.25 11c-29.918 14.92-16.418 45.666-.75 57.625-12.967 2.522-6.234 30.16 9.904 24.894 18.84-6.147-1.986-51.066-7.78-62.644l1.495-11.736z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M52.426 21.376c25.818-7.37 48.653-24.77 66.7 7.096 3.995 7.053 3.306 14.184-1.62 18.23-8.428 6.92-25.402 6.743-24.694-4.35-9.947 5.8-19.764 6.727-17.758-7.25-5.545 2.905-7.34 2.858-12.887-1.376L51.7 40.92l-.283 10.556C55.46 60.642 62.01 69.434 60.792 78.6c7.922.748 15.435 6.55 2 13.126 15.47 9.894 7.286 24.773-4.25 19.25 1.142 13.048-5.167 11.66-9 6.5-17.216-23.18-9.895-61.743-4.25-82z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M102.625 9.594c-.617.033-1.224.124-1.78.28-10.205 2.87-17.71 11.35-32.845 7.97-.096-.186-.132-.25-.23-.37-.294-.37-6.635-1.52-6.943-1.41-.21.074-.282.22-.375.34-21.85-18.666-57.55-7.878-33.796 56.534 2.593 7.032-8.706 5.65-9.25-2.312-5.552 4.567-4.144 16.383 5.313 16.188-1.03 14.91 4.02 9.98 8.78 9.28-.47 10.136 11.71 10.447 13.81-2.203 12.79 3.06 13.08-9.74 10.88-20.44-2.36-11.46-11.016-22.16-6.586-33.5l5.42-5.01c3.526-.72 9.956-3.402 9.413.298-2.856 9.612-10.034 5.077-10.1 10.924-.028 2.465 1.502 4.653 5.656 2.53-2.517 9.795 11.9 13.08 18.905 2.907 2.354 4.592 9.82 8.295 6.72-4.5 3.22 6.775 6.05 4.517 6.936 2.342 4.31 3.093 7.42 2.92 8.595-2.658 6.02 6.838 10.68 3.283 9.063-5.06 1.377.31 2.352-.472 2.842-2.595 1.148 2.375.496 5.903 2.53 6.874 4.66 2.224 11.55-1.366 3.657-14.97 7.64-9.13-7.368-21.936-16.626-21.436z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M60.982 35.02c13.642.26 19.686 5.237 29.97 13.01.136-5.54.728-6.83-4.33-12.368 11.895 2.714 24.29 8.52 35.945 18.718 2.125-26.222-15.928-43.006-31.905-41.724C94.884 7.638 95.28 4.836 93.54-.25c-4.477 11.725-29.89 7.512-39.19 17.063C42.782 25.81 36.323 36.35 36.764 52.875c.613 22.964 17.723 48.87.527 67.55 19.194 3.242 36.48-23.735 21.57-45.983 2.318.894 4.125.91 8.78-2.298-11.9-3.87-16.395-15.49-15.792-22.93l.717-7.538z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M63.62 35.025c11.562.736 19.798 3.434 34.567 11.597 25.383-12.243 16.01-35.524-.763-39.99-15.625-4.16-25.83-1.755-37-5.565 1.956 4.14 4.564 8.348 8 10.322-18.826-.18-28.113-3.676-42.75-7.05 2.95 5.29 9.994 11.52 13.25 13.884-12.083 5.094-20.916-.076-33-2.15 3.333 5.823 7.048 11.19 12.25 14.783-5 16.343 19.916 37.197 29.787 57.14 2.7-12.815 4.76-30.792 3.29-43.607z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M64.33 33.283c9.705 22.482 32.942 3.702 38.82 11.746 3.072 7.98 2.498 17.27-1.44 24.37 2.934 1.12 4.508 2.91 3.49 4.8-4.31 7.99-11.594 15.45-27.637 14.54-3.062 12.93 5.765 26.87-.126 40.64 11.173 8.95 42.412 16.97 38.09-13.953-10.32 13-15.464 2.34-13.707-3.42 4.16-13.63 31.874-51.83 17.542-74.7-12.647-20.18-40.576-27.73-69.92-13.164-29.344 14.568 5.794 91.68-8.67 116.406l26.737.356c-12.15-11.23-6.13-30.195-17.41-45.886 4.24 4.636 7.68 5.417 13.62 3.315-12.013-5.83-19.25-25.54-11.41-46.41l1.214-10.2z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony" - ] + "species": ["unicorn", "pegasus", "earthpony"] }, { "shape": "<path d=\"M44.666 21.39c2.88-9.64 21.828-34.834 52.575-4.97 22.297-9.464 31.18 14.324 16.478 27.943 8.44 7.118-2.553 17.874-8.52 15.18.256-5.74-.34-12.306-2.865-16.798-7.614 17.73-27.62 10.2-38.18-8.388L52.11 39.335l-.06 12.682c-.614 7.093 17.074 16.908 13.22 23.89 2.52 3.48 15.83 20.395 3.97 27.226-9.958 37.27-37.444-2.66-21.166-8.785C32.694 78.324 28.346 70.315 29.7 48.306c.935-15.233 8.206-27.93 14.97-26.915z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M97.37 50.6c15.89 10.53 26.147-13.405 18.827-28.587.066 1.56-.416 2.486-.834 3.485-1.683-5.233-2.087-6.758-3.05-9.9-.65 5.35-.446 10.048-5.488 18.74-1.196-11.776-6.05-20.513-11.554-25.79.7 2.945.56 6.08-.32 9.025-15.752-23.3-38.63-12.01-46.413-5.528-29.76 24.786-16.288 62.293-9.69 75.682-.317-4.247-1.077-8.09-.063-11.67 2.004 3.86 4.007 6.256 6.01 8.838-1.955 7.063 3.654 10.892-.93 17.733 4.235-.512 11.51-8.156 9.15-17.557-2.954-11.753-.804-23.57-1.844-33.58l1.427-9.883 9.993-6.958c11.89-4.685 23.622 8.56 34.78 15.953z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M50.874 23.522c23.66-15.832 58.66-24.962 70.02 2.35 10.813 26-22.117 24.082-27.334 22.23 6.058-4.43 10.695-8.353 17.07-14.05-14.197 11.133-33.26 15.265-48.32 16.272 2.97-5.293 4.97-10.57 2.723-15.09L57.15 33.13l-6.094 18.71c48.018 71.35-18.295 80.53-19.233 64.863 27.224 12.403-3.396-65.87 13.624-87.52\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M52.325 51.93l-.063-12.07 10.32-5.327c16.453 11.482 33.565 4.952 40.567 10.496 3.07 7.98 2.49 17.27-1.44 24.37 2.93 1.12 4.5 2.91 3.49 4.8-3.67 6.8-10.19 14.44-25.51 14.68.07 5.13.47 10.23-.75 15.36 11.28 3.43 31.1 3.94 42.39 1.37-10.24-18.287-9.87-40.87-9.85-57.37 1.755-.198 4.4 1.69 8.275 3.663-13.94-37.69-52.24-41.51-69.037-29.156l-4.19 7.19C41.89 37 29.75 45.454 23.303 39.312c-.443 5.295 8.04 13.68 12.444 17.022-3.68.662-8.356 1.16-13.03-.785 8.12 11.47 13.312 29.02 25.21 31.97-.01-11.8-2.65-23.52 4.39-35.6z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M65.888 115.415C60.6 98.25 45.403 78.935 52.325 51.93l3.006-17.147c18.28-6.646 46.31 13.088 40.76 36.57 2.425 1.032 4.488 1.745 6.967 1.69-2.06 7.493-10.448 16.372-25.49 15.71-2.303 9.72 2.117 20.104 1.946 30.413 9.23 3.104 19.833 2.55 30.445 1.972 2.537-16.423 2.068-32.667 1.46-47.214 2.085.69 6.348-.022 8.358.24.904-12.23.92-24.644-3.66-34.595-9.958-21.64-37.62-37.768-65.378-16.81L46.792 34.2c-14.727 22.36-4.263 53.73-2.577 78.448 6.39-.468 12.547-1.325 21.673 2.767z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M55.33 34.783c8.91-5.593 22.85-3.56 30.63 6.92 5.854-1.71 12.958-2.89 17.19 3.326 3.07 7.982 2.498 17.277-1.44 24.377 2.934 1.124 4.508 2.915 3.49 4.8-4.31 7.993-11.594 15.457-27.637 14.544-3.062 12.93 5.765 26.87-.126 40.644l32.34 5.797c6.21-36.57 17.973-70.336 6.335-95.622-9.958-21.638-37.62-37.765-65.378-16.808L46.792 34.2c-19.9 30.21 6.194 76.877-5.52 101.353l16.987 5.857c8.434-28.756-22-46.724-5.936-89.48z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M92.715 36.313c8.637 2.465 10.713 4.464 25.17 16.612.3-5.667-1.5-11.334-5.556-17 3.29 1.666 6.39 3.333 8.82 5-3.59-5.917-.64-11.527-13.428-20.165 4.3 1.387 7.764-1.722 11.177-5.11-18.67-.334-27.47-19.297-46.66 3.65-.275-3.042 1.24-6.084 3.625-9.125-6.813 1.285-11.79 5.566-15.498 12-5.698-5.507-13.085 1.003-18.49 2.667-6.89-14.66-15.616-10.166-21.167-4.66-9.283 9.21-8.08 25.87-.303 46.64 2.105 5.622-5.684 4.734-8.597 2.206l1.35 7.647c-2.54-2.5-3.63-5.866-4.913-9.117-1.628 13.92 22.205 43.486 30.347-.926 1.6 3.075 4.044 5.322 6.28 4.588-1.566-8.808 3.46-24.512 7.917-29.176 5.368-4.292 16.9-13.79 29.33-11.75 4.02 1.358 7.968 2.813 10.6 6.02z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony" - ] + "species": ["unicorn", "pegasus", "earthpony"] }, { "shape": "<path d=\"M56.16 28.044c17.344-13.22 56.258-29.205 63.063 3.847 2.52 12.248.225 13.76-6.188 17.91-7.79 5.045-17.386-1.37-15.05-6.662-8.652 7.707-15.484 10.624-23.12 9.85-9.167-.927-6.437-6.76-2.417-9.872 2.437-1.887 5.08-3.57 9.436-5.76-7.942 2.55-13.992 1.974-19.282-3.34l-10.947 5.55.015 11.542C53.3 64.17 62.758 80.81 63.912 93.42c.72 7.876-5.532 6.637-8.65 1.425 1.847 5.582 3.592 9.892 3.483 15.89-.13 7.178-8.386 11.54-12.047 1.098-7.505-21.405-12.965-51.97-.973-75.3z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M64.306 35.686C75.18 32.366 93.94 34.6 99.078 51.34c6.337 2.127 12.625 3.224 15.202-3.89-3.127.498-5.786.083-8.04-1.186C123 41.61 123.66 29.374 122.42 21.6c-2.037 3.04-6.775 4.266-10.11 4.348C118.174 7.128 103.16 6.76 94.1.66c2.573 3.79 4.323 6.698 5.105 10.49C90.527 5.044 78.69 1.94 67.1 1.197c6.55 3.24 10.68 6.743 15.12 10.52-18.077-6.532-34.664 10.644-48.495.853 1.91 5.032 2.298 9.83 7.413 15.355-3.47.772-10.105 2.726-13.43 1.29.557 2.41 1.36 4.87 4.782 7.808-5.045-.055-10.09-2.138-15.135-3.696C20.058 42.85 23.76 52.122 32.8 60.054c-3.718-1.25-8.08-3.69-12.356-5.97 3.248 4.72 7.48 9.14 14.208 12.794-3.305.483-5.89.304-8.648.284 8.55 7.333 15.247 9.858 22.72 27.618 6.01-12.27 3.08-31.184 1.815-43.933l1.125-10.842z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M92.906 14.75c-14.61.286-26.147 9.556-39.687 13.53l-5.565 8.595C43.81 30.5 36.58 28.752 32 32.812c-8.645 7.666-12.336 29.877-.75 42.344 5.224 5.622 10.25 5.16 13.406-2.72 2.242 4.647 2.416 9.293 2.72 13.94.6 9.248-3.733 10.614-6.75 4.5-2.905 16.18 15.08 28.385 19.5 6.124 2.096-10.564-10.178-34.003-7.866-45.145-1.19-12.517 6.56-14.07 8.24-18.417 4.955-.63 8.483 7.77 13.97 19.156l16.25 1.656c2.246-4.542 2.954-9.24 2.374-14.53 3.326 5.076 3.486 8.08 2.562 14.155l12.688-.406c.818-4.864 1.737-10.438 1.187-15.783 4.447 5.572 1.82 9.458 2.22 15.03 9.41-5.17 16.63-25.01.03-33.343-6.964-3.497-13.156-4.737-18.873-4.625z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M52.103 23.43C70.12 1.668 97.126 2.89 110.14 16.998c27.93 30.27-15.676 43.662-18.952 21.868-12.934-4.453-23.22-3.956-34.13-2.747L51.12 49.26c.557 23.24 17.787 26.876 22.887 41.315 4.124 11.677-5.325 14.075-9.404 12.656 4.622 17.668-12.022 24.3-20.003 7.4-1.797-3.8-2.81-14.813 3.672-14.51-3.182-16.784-17.45-38.285-2.43-63.75z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] }, { "shape": "<path d=\"M64.268 33.955c.417 4.905.2 15.162 11.578 10.276 1.96 6.36 12.832 8.068 16.833 2.37.77 3.5 15.69 10.525 17.49 1.676 19.792 5.17 10.453-26.42-12.985-31.76-14.75-3.36-32.286-5.9-48.993 5.386-28.595 19.318-3.18 39.89-5.026 56-4.353 38.03 12.04 46.05 14.974 20.586 18-.676 5.704-14.656-2.884-22.693C70.602 72.203 42.78 56.16 49.2 43.46z\" fill=\"#HAIR_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] } ], "extra_shapes": [ { "shape": "<path d=\"M92.752 36.834s9.092-19.572 6.06-22.73c-3.03-3.156-15.277 11.492-16.92 16.542 2.02.505 8.082 2.273 10.86 6.188z\" fill=\"#BODY_FILL\"/>", - "species": [ - "unicorn" - ] + "species": ["unicorn"] }, { "shape": "<path d=\"M43.267 107.324s-6.825-14.137-7.64-30.166c-.817-16.03-4.197-31.468-10.55-40.688-6.354-9.22-13.272-9.73-11.997-3.982 1.275 5.748 11.123 33.016 12.128 35.954C23.042 65.648 7.038 41.11-.43 37.222c-7.47-3.886-8.96.346-6.892 5.885 2.068 5.54 18.507 30.844 20.886 33.502-2.738-1.685-12.256-9.036-16.997-8.996-4.742.04-4.91 5.366-2.617 8.526 2.292 3.162 20.912 19.173 25.15 20.945-5.35.28-10.384 1.996-9.186 6.004 1.2 4.006 11.384 14.063 28.53 12.377 2.576-2.834 4.823-8.143 4.823-8.143z\" fill=\"#BODY_FILL\"/>", - "species": [ - "pegasus" - ] + "species": ["pegasus"] }, { "shape": "<path d=\"M1.63 34.003s-8.46-5.35-14.8-5.626c5.125 4.444 24.008 19.984.12 34.287C-2.694 67.754 14.656 74.77.435 89.662c12.087 4.118 22.935 10.387 24.452 17.605 6.935-2.58 14.536-2.557 14.536-2.557L27.868 92.518 24.7 79.98l4.45-11.208 1.148-9.387L12.646 41.1 1.63 34.003\" fill=\"#74879c\"/><path d=\"M43.074 105.257c-7.347-4.89-14.894-13.1-14.524-21.41.37-8.31 6.128-16.213 8.922-20.638 2.794-4.426-.414-7.708-1.693-8.64.352 2.842-1.043 5.233-2.608 6.677-1.638-4.25-16.28-22.455-31.543-27.244C9.31 40.313 28.07 58.7 27.685 65.706c-.386 7.005-6.082 7.433-11.51 3.943-5.43-3.49-11.346-8.044-29.227-6.986 5.558 1.234 23.802 3.85 30.857 10.76 7.056 6.91 8.737 14.602.825 15.058-7.912.457-18.196 1.18-18.196 1.18s12.823-.28 19.82 2.003c6.997 2.284 13.553 7.303 4.632 15.602 14.536-2.557 15.073 2.3 17.602 1.912 2.53-.39.584-3.923.584-3.923z\" fill=\"#4f538d\"/>", - "species": [ - "batpony" - ] + "species": ["batpony"] }, { "shape": "<path d=\"M54.878 16.157c-2.55-4.117-4.816-7.13-6.17-6.475-1.357.655.865 7.59 3.092 11.277-4.267-3.22-7.552-4.118-7.552-4.118-3.34.21 4.375 8.207 4.375 8.207s6.52 1.44 6.255-8.893z\" fill=\"#BODY_FILL\"/>", - "species": [ - "batpony" - ] + "species": ["batpony"] }, { "shape": "<path d=\"M64.342 35.57s3.283-8.08-7.324-19.318c-1.768-1.768-3.03-2.273-4.672-.758-1.64 1.515-17.046 16.036.253 38.26.504-2.4 1.135-9.597 1.135-9.597z\" fill=\"#BODY_FILL\"/>", - "species": [ - "unicorn", - "pegasus", - "earthpony", - "batpony" - ] + "species": ["unicorn", "pegasus", "earthpony", "batpony"] } ], "footer": "</svg>" diff --git a/config/footer.json b/config/footer.json index d875df97..24102ca3 100644 --- a/config/footer.json +++ b/config/footer.json @@ -1,9 +1,5 @@ { - "cols": [ - "Site Resources", - "Help & Information", - "Community" - ], + "cols": ["Site Resources", "Help & Information", "Community"], "Site Resources": [ { "title": "Site Rules", diff --git a/config/quick_tag_table.json b/config/quick_tag_table.json index 6810305e..90911eae 100644 --- a/config/quick_tag_table.json +++ b/config/quick_tag_table.json @@ -44,21 +44,8 @@ "1": "season" }, "Main": { - "Ratings": [ - "safe", - "suggestive", - "questionable", - "explicit", - "semi-grimdark", - "grimdark", - "grotesque" - ], - "General Spoilers": [ - "spoiler:comic", - "spoiler:g5", - "spoiler:pony life", - "spoilers for another series" - ], + "Ratings": ["safe", "suggestive", "questionable", "explicit", "semi-grimdark", "grimdark", "grotesque"], + "General Spoilers": ["spoiler:comic", "spoiler:g5", "spoiler:pony life", "spoilers for another series"], "Species": [ "anthro", "equestria girls", @@ -115,160 +102,145 @@ "timber wolf", "windigo" ], - "Misc": [ - "original species", - "hybrid" - ] + "Misc": ["original species", "hybrid"] }, "Shorthands A": [ - ["Mane Cast", [ - ["m6", "mane six"], - ["pt", "princess twilight"], - ["ts", "twilight sparkle"], - ["rd", "rainbow dash"], - ["ry", "rarity"], - ["aj", "applejack"], - ["fs", "fluttershy"], - ["pp", "pinkie pie"], - ["sp", "spike"] - ]], - ["Secondary Cast", [ - ["cmc", "cutie mark crusaders"], - ["ab", "apple bloom"], - ["sl", "scootaloo"], - ["sb", "sweetie belle"], - ["tia", "princess celestia"], - ["luna", "princess luna"], - ["pcd", "princess cadance"], - ["sa", "shining armor"], - ["sg", "starlight glimmer"] - ]], - ["More Ponies", [ - ["tx", "trixie"], - ["sus", "sunset shimmer"], - ["sombra", "king sombra"], - ["qc", "queen chrysalis"], - ["dc", "discord"], - ["nmm", "nightmare moon"], - ["sf", "spitfire"], - ["sn", "soarin'"], - ["ld", "lightning dust"] - ]], - ["More Apples", [ - ["bm", "big macintosh"], - ["gs", "granny smith"], - ["bb", "braeburn"], - ["bs", "babs seed"] - ]], - ["Fillies and Colts", [ - ["ss", "silver spoon"], - ["dt", "diamond tiara"], - ["pfh", "princess flurry heart"] - ]] + [ + "Mane Cast", + [ + ["m6", "mane six"], + ["pt", "princess twilight"], + ["ts", "twilight sparkle"], + ["rd", "rainbow dash"], + ["ry", "rarity"], + ["aj", "applejack"], + ["fs", "fluttershy"], + ["pp", "pinkie pie"], + ["sp", "spike"] + ] + ], + [ + "Secondary Cast", + [ + ["cmc", "cutie mark crusaders"], + ["ab", "apple bloom"], + ["sl", "scootaloo"], + ["sb", "sweetie belle"], + ["tia", "princess celestia"], + ["luna", "princess luna"], + ["pcd", "princess cadance"], + ["sa", "shining armor"], + ["sg", "starlight glimmer"] + ] + ], + [ + "More Ponies", + [ + ["tx", "trixie"], + ["sus", "sunset shimmer"], + ["sombra", "king sombra"], + ["qc", "queen chrysalis"], + ["dc", "discord"], + ["nmm", "nightmare moon"], + ["sf", "spitfire"], + ["sn", "soarin'"], + ["ld", "lightning dust"] + ] + ], + [ + "More Apples", + [ + ["bm", "big macintosh"], + ["gs", "granny smith"], + ["bb", "braeburn"], + ["bs", "babs seed"] + ] + ], + [ + "Fillies and Colts", + [ + ["ss", "silver spoon"], + ["dt", "diamond tiara"], + ["pfh", "princess flurry heart"] + ] + ] ], "B": [ - ["Background Ponies", [ - ["dh", "derpy hooves"], - ["dw", "doctor whooves"], - ["cgt", "colgate"], - ["bon", "bon bon"], - ["oct", "octavia melody"], - ["dj", "vinyl scratch"], - ["bp", "berry punch"], - ["pbb", "prince blueblood"] - ]], - ["Student Six", [ - ["s6", "student six"], - ["ga", "gallus"], - ["ols", "ocellus"], - ["snb", "sandbar"], - ["svs", "silverstream"], - ["sm", "smolder"], - ["yn", "yona"] - ]], - ["Uncategorized", [ - ["maud", "maud pie"], - ["coco", "coco pommel"], - ["suri", "suri polomare"], - ["rg", "royal guard"], - ["za", "zecora"], - ["mm", "mayor mare"], - ["pdp", "pinkamena diane pie"], - ["owol", "owlowiscious"], - ["opal", "opalescence"] - ]], - ["Other Things", [ - ["cm", "cutie mark"], - ["eoh", "elements of harmony"], - ["nmn", "nightmare night"] - ]] + [ + "Background Ponies", + [ + ["dh", "derpy hooves"], + ["dw", "doctor whooves"], + ["cgt", "colgate"], + ["bon", "bon bon"], + ["oct", "octavia melody"], + ["dj", "vinyl scratch"], + ["bp", "berry punch"], + ["pbb", "prince blueblood"] + ] + ], + [ + "Student Six", + [ + ["s6", "student six"], + ["ga", "gallus"], + ["ols", "ocellus"], + ["snb", "sandbar"], + ["svs", "silverstream"], + ["sm", "smolder"], + ["yn", "yona"] + ] + ], + [ + "Uncategorized", + [ + ["maud", "maud pie"], + ["coco", "coco pommel"], + ["suri", "suri polomare"], + ["rg", "royal guard"], + ["za", "zecora"], + ["mm", "mayor mare"], + ["pdp", "pinkamena diane pie"], + ["owol", "owlowiscious"], + ["opal", "opalescence"] + ] + ], + [ + "Other Things", + [ + ["cm", "cutie mark"], + ["eoh", "elements of harmony"], + ["nmn", "nightmare night"] + ] + ] ], "Ships ts": { - "implying": [ - "shipping", - "twilight sparkle" - ], - "not_implying": [ - - ] + "implying": ["shipping", "twilight sparkle"], + "not_implying": [] }, "rd": { - "implying": [ - "shipping", - "rainbow dash" - ], - "not_implying": [ - - ] + "implying": ["shipping", "rainbow dash"], + "not_implying": [] }, "ry": { - "implying": [ - "shipping", - "rarity" - ], - "not_implying": [ - - ] + "implying": ["shipping", "rarity"], + "not_implying": [] }, "aj": { - "implying": [ - "shipping", - "applejack" - ], - "not_implying": [ - - ] + "implying": ["shipping", "applejack"], + "not_implying": [] }, "fs": { - "implying": [ - "shipping", - "fluttershy" - ], - "not_implying": [ - - ] + "implying": ["shipping", "fluttershy"], + "not_implying": [] }, "pp": { - "implying": [ - "shipping", - "pinkie pie" - ], - "not_implying": [ - - ] + "implying": ["shipping", "pinkie pie"], + "not_implying": [] }, "misc": { - "implying": [ - "shipping" - ], - "not_implying": [ - "twilight sparkle", - "rainbow dash", - "rarity", - "applejack", - "fluttershy", - "pinkie pie" - ] + "implying": ["shipping"], + "not_implying": ["twilight sparkle", "rainbow dash", "rarity", "applejack", "fluttershy", "pinkie pie"] }, "Season 9": [ ["1-2", "the beginning of the end"], diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..f7aea3ab --- /dev/null +++ b/package-lock.json @@ -0,0 +1,27 @@ +{ + "name": "philomena", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "prettier": "^3.5.3" + } + }, + "node_modules/prettier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..76e7bb99 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "scripts": { + "fmt": "prettier --write ." + }, + "devDependencies": { + "prettier": "^3.5.3" + } +} diff --git a/priv/repo/seeds.json b/priv/repo/seeds.json index 3c5f06d9..546d4706 100644 --- a/priv/repo/seeds.json +++ b/priv/repo/seeds.json @@ -1,14 +1,10 @@ { - "system_filters": [{ + "system_filters": [ + { "name": "Default", "description": "The site's default filter.", - "hidden": [ - "explicit", - "grotesque" - ], - "spoilered": [ - "questionable" - ] + "hidden": ["explicit", "grotesque"], + "spoilered": ["questionable"] }, { "name": "Everything", @@ -17,7 +13,8 @@ "spoilered": [] } ], - "forums": [{ + "forums": [ + { "name": "General Discussion", "short_name": "dis", "description": "This is a discussion forum for everything unrelated to the show or other forums", @@ -60,37 +57,31 @@ "access_level": "staff" } ], - "users": [{ - "name": "Administrator", - "email": "admin@example.com", - "password": "philomena123", - "role": "admin" - }], - "rating_tags": [ - "safe", - "suggestive", - "questionable", - "explicit", - "semi-grimdark", - "grimdark", - "grotesque" + "users": [ + { + "name": "Administrator", + "email": "admin@example.com", + "password": "philomena123", + "role": "admin" + } ], + "rating_tags": ["safe", "suggestive", "questionable", "explicit", "semi-grimdark", "grimdark", "grotesque"], "roles": [ - {"name": "moderator", "resource_type": "Image"}, - {"name": "moderator", "resource_type": "DuplicateReport"}, - {"name": "moderator", "resource_type": "Comment"}, - {"name": "moderator", "resource_type": "Tag"}, - {"name": "moderator", "resource_type": "ArtistLink"}, - {"name": "admin", "resource_type": "Tag"}, - {"name": "moderator", "resource_type": "User"}, - {"name": "admin", "resource_type": "SiteNotice"}, - {"name": "admin", "resource_type": "Badge"}, - {"name": "admin", "resource_type": "Role"}, - {"name": "batch_update", "resource_type": "Tag"}, - {"name": "moderator", "resource_type": "Topic"}, - {"name": "admin", "resource_type": "Advert"}, - {"name": "admin", "resource_type": "StaticPage"}, - {"name": "admin", "resource_type": "Image"} + { "name": "moderator", "resource_type": "Image" }, + { "name": "moderator", "resource_type": "DuplicateReport" }, + { "name": "moderator", "resource_type": "Comment" }, + { "name": "moderator", "resource_type": "Tag" }, + { "name": "moderator", "resource_type": "ArtistLink" }, + { "name": "admin", "resource_type": "Tag" }, + { "name": "moderator", "resource_type": "User" }, + { "name": "admin", "resource_type": "SiteNotice" }, + { "name": "admin", "resource_type": "Badge" }, + { "name": "admin", "resource_type": "Role" }, + { "name": "batch_update", "resource_type": "Tag" }, + { "name": "moderator", "resource_type": "Topic" }, + { "name": "admin", "resource_type": "Advert" }, + { "name": "admin", "resource_type": "StaticPage" }, + { "name": "admin", "resource_type": "Image" } ], "pages": [] } diff --git a/priv/repo/seeds_development.json b/priv/repo/seeds_development.json index 47625a51..4788b0f5 100644 --- a/priv/repo/seeds_development.json +++ b/priv/repo/seeds_development.json @@ -1,5 +1,6 @@ { - "users": [{ + "users": [ + { "name": "Hot Pocket Consumer", "email": "moderator@example.com", "password": "philomena123", @@ -21,24 +22,18 @@ "remote_images": [ { "url": "https://derpicdn.net/img/2015/9/26/988000/thumb.gif", - "sources": [ - "https://derpibooru.org/988000" - ], + "sources": ["https://derpibooru.org/988000"], "description": "Fairly large GIF (~23MB), use to test WebM stuff.", "tag_input": "alicorn, angry, animated, art, artist:assasinmonkey, artist:equum_amici, badass, barrier, crying, dark, epic, female, fight, force field, glare, glow, good vs evil, lord tirek, low angle, magic, mare, messy mane, metal as fuck, perspective, plot, pony, raised hoof, safe, size difference, spread wings, stomping, twilight's kingdom, twilight sparkle, twilight sparkle (alicorn), twilight vs tirek, underhoof" }, { "url": "https://derpicdn.net/img/2012/1/2/25/large.png", - "sources": [ - "https://derpibooru.org/25" - ], + "sources": ["https://derpibooru.org/25"], "tag_input": "artist:moe, canterlot, castle, cliff, cloud, detailed background, fog, forest, grass, mountain, mountain range, nature, no pony, outdoors, path, river, safe, scenery, scenery porn, signature, source needed, sunset, technical advanced, town, tree, useless source url, water, waterfall, widescreen, wood" }, { "url": "https://derpicdn.net/img/2018/6/28/1767886/full.webm", - "sources": [ - "http://hydrusbeta.deviantart.com/art/Gleaming-in-the-Sun-Our-Colors-Shine-in-Every-Hue-611497309" - ], + "sources": ["http://hydrusbeta.deviantart.com/art/Gleaming-in-the-Sun-Our-Colors-Shine-in-Every-Hue-611497309"], "tag_input": "3d, animated, architecture, artist:hydrusbeta, castle, cloud, crystal empire, crystal palace, flag, flag waving, no pony, no sound, safe, scenery, webm" }, { @@ -50,16 +45,12 @@ }, { "url": "https://derpicdn.net/img/view/2016/3/17/1110529.jpg", - "sources": [ - "https://www.deviantart.com/devinian/art/Commission-Crystals-of-thy-heart-511134926" - ], + "sources": ["https://www.deviantart.com/devinian/art/Commission-Crystals-of-thy-heart-511134926"], "tag_input": "artist:devinian, aurora crystialis, bridge, cloud, crepuscular rays, crystal empire, crystal palace, edit, flower, forest, grass, log, mountain, no pony, river, road, safe, scenery, scenery porn, source needed, stars, sunset, swing, tree, wallpaper" }, { "url": "https://derpicdn.net/img/view/2019/6/16/2067468.svg", - "sources": [ - "https://derpibooru.org/2067468" - ], + "sources": ["https://derpibooru.org/2067468"], "tag_input": "artist:cheezedoodle96, babs seed, bloom and gloom, cutie mark, cutie mark only, no pony, safe, scissors, simple background, svg, .svg available, transparent background, vector" } ], @@ -69,33 +60,28 @@ "embedded image inside a spoiler: ||who needs it anyway >>1s||", "spoilers inside of a table\n\nHello | World\n--- | ---:\n`||cool beans!||` | ||cool beans!||" ], - "forum_posts": [{ - "forum": "dis", - "topics": [{ - "title": "Example Topic", - "posts": [ - "example post", - "yet another example post" - ] - }, - { - "title": "Second Example Topic", - "posts": [ - "post", - "post 2" - ] - } - ]}, + "forum_posts": [ + { + "forum": "dis", + "topics": [ + { + "title": "Example Topic", + "posts": ["example post", "yet another example post"] + }, + { + "title": "Second Example Topic", + "posts": ["post", "post 2"] + } + ] + }, { "forum": "art", - "topics": [{ - "title": "Embedded Images", - "posts": [ - ">>1t >>1s >>1p", - ">>1", - "non-existent: >>1000t >>1000s >>1000p >>1000" - ] - }] + "topics": [ + { + "title": "Embedded Images", + "posts": [">>1t >>1s >>1p", ">>1", "non-existent: >>1000t >>1000s >>1000p >>1000"] + } + ] } ] }