From 6a69894829bb2f8cf501cdcf6680de0bc7e7e64b Mon Sep 17 00:00:00 2001 From: Cobblestone Date: Sun, 19 Jul 2026 22:06:35 -0400 Subject: [PATCH 01/10] I forgot something --- src/app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.css b/src/app.css index fd03046..12b4d27 100644 --- a/src/app.css +++ b/src/app.css @@ -74,7 +74,7 @@ button { --custom-source-align: top; } -.obfuscated:not(:has([data-atlas-object-node], [data-player-object-node])) { +.obfuscated { filter: blur(2px); } From b1516edfd97bcc80bfe517a1474d02a03772e6de Mon Sep 17 00:00:00 2001 From: Cobblestone Date: Mon, 20 Jul 2026 13:28:21 -0400 Subject: [PATCH 02/10] testing refactor part 1 --- bun.lock | 147 +++---- package.json | 1 + src/app.css | 8 +- src/lib/text/nbt/export.ts | 13 +- src/lib/text/nbt/import.ts | 41 +- src/lib/types.ts | 2 +- src/routes/+page.svelte | 6 +- .../data/bad/json/too_big_shadow_color.json | 18 + .../clean/json/illegal_marked_object.json | 27 ++ .../unit/data/clean/json/shadow_color.json | 18 + .../clean/json/shadow_color_transparent.json | 18 + ...mple_text_tiptap.json => simple_text.json} | 0 ...nicode_tiptap.json => simple_unicode.json} | 0 .../data/clean/snbt/base16_shadow_color.snbt | 2 +- .../optimising_mc_json.spec.ts | 2 +- .../exporting/translating_mc_json.spec.ts | 174 ++++++++ src/tests/unit/exporting/type_props.spec.ts | 101 +++++ .../unit/importing/snbt_importing.spec.ts | 205 +++++++++ src/tests/unit/importing/source_props.spec.ts | 194 +++++++++ src/tests/unit/{ => misc}/utils.spec.ts | 3 +- src/tests/unit/snbt_importing.spec.ts | 412 ------------------ src/tests/unit/translating_mc_json.spec.ts | 256 ----------- vite.config.ts | 4 +- 23 files changed, 883 insertions(+), 769 deletions(-) create mode 100644 src/tests/unit/data/bad/json/too_big_shadow_color.json create mode 100644 src/tests/unit/data/clean/json/illegal_marked_object.json create mode 100644 src/tests/unit/data/clean/json/shadow_color.json create mode 100644 src/tests/unit/data/clean/json/shadow_color_transparent.json rename src/tests/unit/data/clean/json/{simple_text_tiptap.json => simple_text.json} (100%) rename src/tests/unit/data/clean/json/{simple_unicode_tiptap.json => simple_unicode.json} (100%) rename src/tests/unit/{ => exporting}/optimising_mc_json.spec.ts (98%) create mode 100644 src/tests/unit/exporting/translating_mc_json.spec.ts create mode 100644 src/tests/unit/exporting/type_props.spec.ts create mode 100644 src/tests/unit/importing/snbt_importing.spec.ts create mode 100644 src/tests/unit/importing/source_props.spec.ts rename src/tests/unit/{ => misc}/utils.spec.ts (97%) delete mode 100644 src/tests/unit/snbt_importing.spec.ts delete mode 100644 src/tests/unit/translating_mc_json.spec.ts diff --git a/bun.lock b/bun.lock index f8da0ab..9ec8e90 100644 --- a/bun.lock +++ b/bun.lock @@ -5,43 +5,44 @@ "": { "name": "tools", "dependencies": { - "@tiptap/core": "latest", - "@tiptap/extension-placeholder": "latest", - "@tiptap/pm": "latest", - "@tiptap/starter-kit": "latest", - "bits-ui": "latest", - "html2canvas-pro": "latest", - "idb": "latest", - "svelte-awesome-color-picker": "latest", - "tippy.js": "latest", - "typescript-color-gradient": "latest", + "@tiptap/core": "^3.27.4", + "@tiptap/extension-placeholder": "^3.27.4", + "@tiptap/pm": "^3.27.4", + "@tiptap/starter-kit": "^3.27.4", + "bits-ui": "^2.18.1", + "html2canvas-pro": "^2.2.4", + "idb": "^8.0.3", + "svelte-awesome-color-picker": "^4.1.3", + "tippy.js": "^6.3.7", + "typescript-color-gradient": "^4.2.0", }, "devDependencies": { - "@iconify-json/tabler": "latest", - "@playwright/test": "latest", - "@sveltejs/adapter-auto": "latest", - "@sveltejs/kit": "latest", - "@sveltejs/vite-plugin-svelte": "latest", - "@tailwindcss/vite": "latest", - "@testing-library/jest-dom": "latest", - "@testing-library/svelte": "latest", - "@tiptap/extension-color": "latest", - "@tiptap/extension-font-family": "latest", - "@tiptap/extension-text-style": "latest", - "@types/node": "latest", - "file-type": "latest", - "jsdom": "latest", - "oxlint": "latest", - "prettier": "latest", - "prettier-plugin-svelte": "latest", - "prettier-plugin-tailwindcss": "latest", - "svelte": "latest", - "svelte-check": "latest", - "tailwindcss": "latest", - "typescript": "latest", - "unplugin-icons": "latest", - "vite": "latest", - "vitest": "latest", + "@iconify-json/tabler": "^1.2.35", + "@playwright/test": "^1.61.1", + "@sveltejs/adapter-auto": "^7.0.1", + "@sveltejs/kit": "^2.69.3", + "@sveltejs/vite-plugin-svelte": "^7.2.0", + "@tailwindcss/vite": "^4.3.2", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/svelte": "^5.4.2", + "@tiptap/extension-color": "^3.27.4", + "@tiptap/extension-font-family": "^3.27.4", + "@tiptap/extension-text-style": "^3.27.4", + "@types/node": "^26.1.1", + "@vitest/coverage-v8": "4.1.10", + "file-type": "^22.0.1", + "jsdom": "^29.1.1", + "oxlint": "^1.74.0", + "prettier": "^3.9.5", + "prettier-plugin-svelte": "^4.1.1", + "prettier-plugin-tailwindcss": "^0.8.0", + "svelte": "^5.56.5", + "svelte-check": "^4.7.2", + "tailwindcss": "^4.3.2", + "typescript": "^6.0.3", + "unplugin-icons": "^23.0.1", + "vite": "^8.1.4", + "vitest": "^4.1.10", }, }, }, @@ -60,10 +61,18 @@ "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], + "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="], + "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], + "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], "@bramus/specificity": ["@bramus/specificity@2.4.2", "", { "dependencies": { "css-tree": "^3.0.0" }, "bin": { "specificity": "bin/cli.js" } }, "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw=="], @@ -322,45 +331,7 @@ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], - "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], - - "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], - - "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], - - "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], - - "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], - - "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], - - "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], - - "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], - - "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], - - "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], - - "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], - - "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], - - "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], - - "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], - - "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], - - "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], - - "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], - - "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], - - "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], - - "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.10", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.10", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.10", "vitest": "4.1.10" }, "optionalPeers": ["@vitest/browser"] }, "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g=="], "@vitest/expect": ["@vitest/expect@4.1.10", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.10", "@vitest/utils": "4.1.10", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA=="], @@ -386,6 +357,8 @@ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.5", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA=="], + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], "base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="], @@ -454,8 +427,12 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "html-encoding-sniffer": ["html-encoding-sniffer@6.0.0", "", { "dependencies": { "@exodus/bytes": "^1.6.0" } }, "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg=="], + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], + "html2canvas-pro": ["html2canvas-pro@2.2.4", "", { "dependencies": { "css-line-break": "^2.1.0", "text-segmentation": "^1.0.3" } }, "sha512-fo/VOiQZ3oWykAPvnMNHymUHzLWJE7c7C7VWPh+ydb+NquFTwqY5rHQRoxkgsaXo/iciVryPNffTvLzYg98xhg=="], "idb": ["idb@8.0.3", "", {}, "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg=="], @@ -470,9 +447,15 @@ "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], + + "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], + + "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], + "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + "js-tokens": ["js-tokens@10.0.0", "", {}, "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q=="], "jsdom": ["jsdom@29.1.1", "", { "dependencies": { "@asamuzakjp/css-color": "^5.1.11", "@asamuzakjp/dom-selector": "^7.1.1", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.3", "@exodus/bytes": "^1.15.0", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.3.5", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.1", "undici": "^7.25.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.1", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q=="], @@ -514,6 +497,10 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="], + + "make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], + "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], @@ -608,6 +595,8 @@ "saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="], + "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + "set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="], "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], @@ -626,6 +615,8 @@ "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "svelte": ["svelte@5.56.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.10", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.12", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-P03YJmUy2JoOxYHb4Ka3oFat1hq2ko2it1MOItSjsJ4B6WgZPLc3+RyyU+57OGWhs3Ieq74EJpZtSnNXdAGgDw=="], "svelte-awesome-color-picker": ["svelte-awesome-color-picker@4.1.3", "", { "dependencies": { "colord": "^2.9.3", "svelte-awesome-slider": "2.0.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-fYio6XR2vp9WO0ihT6Vlw1Kj278gEZtqfIRde4YBx5OgGjBdQJxFE8jl6OibPQPrmaz625HZPZaSbRflL88/Mg=="], @@ -670,7 +661,7 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], "typescript-color-gradient": ["typescript-color-gradient@4.2.0", "", {}, "sha512-If2yZZfj+9KbBjdPUqTuppmn3JgYAZoPwE9jlxSYf5u3zFKCMAInNSHnEaIekoeykkSuaS8CnnP4XI/X68KybQ=="], @@ -714,6 +705,10 @@ "zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="], + "@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], diff --git a/package.json b/package.json index 60d0976..a059f5a 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@tiptap/extension-font-family": "^3.27.4", "@tiptap/extension-text-style": "^3.27.4", "@types/node": "^26.1.1", + "@vitest/coverage-v8": "4.1.10", "file-type": "^22.0.1", "jsdom": "^29.1.1", "oxlint": "^1.74.0", diff --git a/src/app.css b/src/app.css index 2b2c3a4..2b4cd05 100644 --- a/src/app.css +++ b/src/app.css @@ -84,8 +84,12 @@ button { --custom-source-align: top; } -.obfuscated:not(:has([data-atlas-object-node], [data-player-object-node])) { - filter: blur(2px); +.obfuscated { + @apply transition-all; +} + +.obfuscated:not(:hover) { + filter: blur(3px); } .color-picker { diff --git a/src/lib/text/nbt/export.ts b/src/lib/text/nbt/export.ts index ed31c9f..bcafd90 100644 --- a/src/lib/text/nbt/export.ts +++ b/src/lib/text/nbt/export.ts @@ -212,10 +212,13 @@ export function translateJSON( const shadowColorMark = c.marks?.find((m) => m.type === "shadowColor"); if (shadowColorMark) { - current.shadow_color = parseInt( - rgbaToArgbHex(shadowColorMark.attrs?.shadowColor).replace(/^#/, ""), - 16, - ); + let colorVal = shadowColorMark.attrs?.shadowColor.replace(/^#/, ""); + if (colorVal && colorVal.length <= 8) { + current.shadow_color = parseInt( + rgbaToArgbHex(colorVal).replace(/^#/, ""), + 16, + ); + } } current = addTypeSpecificValues(current, c, true); @@ -249,7 +252,7 @@ export function translateJSON( if (num > 2 ** 31 - 1 || num < (-2) ** 31) { finalResult = finalResult.replaceAll( match[0], - `shadow_color:${num}L`, + `"shadow_color":${num}L`, ); } } diff --git a/src/lib/text/nbt/import.ts b/src/lib/text/nbt/import.ts index ace6647..8654aaf 100644 --- a/src/lib/text/nbt/import.ts +++ b/src/lib/text/nbt/import.ts @@ -44,10 +44,15 @@ export function convertToTextOrEmpty(raw: string): StringyMCText[] { return [raw.replace(/"/g, "")]; } - // replace 1b and 0b + // replace 1b and 0b with true and false literals raw = raw.replace(/(?<="\w+"\s*:\s*)\b1b\b/g, "true"); raw = raw.replace(/(?<="\w+"\s*:\s*)\b0b\b/g, "false"); + // remove type suffixes from numbers (e.g., 1.0f, 2.0d, 3l) + raw = raw.replace(/(?<="\w+"\s*:\s*)-?\d+(\.\d+)?[fdl]/gi, (match) => { + return match.slice(0, -1); + }); + let parsed: MinecraftText[] | MinecraftText | string; try { @@ -242,13 +247,22 @@ function applyStyling( } if (text.shadow_color) { - const hex = "#" + text.shadow_color.toString(16).padStart(8, "0"); - finalText.marks?.push({ - type: "shadowColor", - attrs: { - shadowColor: hex, - }, - }); + const combinedShadowStr = ( + Array.isArray(text.shadow_color) + ? text.shadow_color.map(mapToHexByte).join("") + : text.shadow_color.toString(16) + ).replace(/[lL#]/g, ""); + const intValue = parseInt(combinedShadowStr, 16); + + if (intValue > 0 && intValue < 0xffffffff) { + const hex = "#" + combinedShadowStr.padStart(8, "ff"); + finalText.marks?.push({ + type: "shadowColor", + attrs: { + shadowColor: hex, + }, + }); + } } if (text.bold) { @@ -406,3 +420,14 @@ function fixBrokenNewLines(doc: JSONContent) { content: fixedContent, }; } + +function mapToHexByte(value: number): string { + if (value < 0.0 || value > 1.0) { + return "00"; // Return "00" for out-of-range values + } + + const byteValue = Math.round(value * 255); + const hexString = byteValue.toString(16); + + return hexString.length === 1 ? "0" + hexString : hexString; +} diff --git a/src/lib/types.ts b/src/lib/types.ts index f1bad8a..5b993e1 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -60,7 +60,7 @@ export type MinecraftText = { atlas?: string; sprite?: string; player?: { - name?: string; + name: string; }; hat?: string; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 2b2e352..783adde 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -574,9 +574,9 @@
{#if page.url.searchParams.has("dev")}
-					DEV ONLY: {editor ? JSON.stringify(editor.getJSON()) : "Loading..."}
-				
+ >DEV ONLY: {editor + ? JSON.stringify(editor.getJSON()) + : "Loading..."}
{/if}
diff --git a/src/tests/unit/data/bad/json/too_big_shadow_color.json b/src/tests/unit/data/bad/json/too_big_shadow_color.json new file mode 100644 index 0000000..a1b66bc --- /dev/null +++ b/src/tests/unit/data/bad/json/too_big_shadow_color.json @@ -0,0 +1,18 @@ +{ + "content": [ + { + "content": [ + { + "type": "text", + "text": "Shadow", + "marks": [ + { + "type": "shadowColor", + "attrs": { "shadowColor": "#100000000" } + } + ] + } + ] + } + ] +} diff --git a/src/tests/unit/data/clean/json/illegal_marked_object.json b/src/tests/unit/data/clean/json/illegal_marked_object.json new file mode 100644 index 0000000..d535ea1 --- /dev/null +++ b/src/tests/unit/data/clean/json/illegal_marked_object.json @@ -0,0 +1,27 @@ +{ + "content": [ + { + "type": "paragraph", + "content": [ + { + "type": "atlas_object", + "attrs": { "atlas": "", "sprite": "item/cobblestone" }, + "marks": [ + { "type": "bold" }, + { "type": "italic" }, + { "type": "obfuscated" } + ] + }, + { + "type": "player_object", + "attrs": { "player": { "name": "Cbble_" }, "hat": true }, + "marks": [ + { "type": "bold" }, + { "type": "italic" }, + { "type": "obfuscated" } + ] + } + ] + } + ] +} diff --git a/src/tests/unit/data/clean/json/shadow_color.json b/src/tests/unit/data/clean/json/shadow_color.json new file mode 100644 index 0000000..d9aef53 --- /dev/null +++ b/src/tests/unit/data/clean/json/shadow_color.json @@ -0,0 +1,18 @@ +{ + "content": [ + { + "content": [ + { + "type": "text", + "text": "Shadow", + "marks": [ + { + "type": "shadowColor", + "attrs": { "shadowColor": "#ff00ff" } + } + ] + } + ] + } + ] +} diff --git a/src/tests/unit/data/clean/json/shadow_color_transparent.json b/src/tests/unit/data/clean/json/shadow_color_transparent.json new file mode 100644 index 0000000..d2e22c9 --- /dev/null +++ b/src/tests/unit/data/clean/json/shadow_color_transparent.json @@ -0,0 +1,18 @@ +{ + "content": [ + { + "content": [ + { + "type": "text", + "text": "Shadow", + "marks": [ + { + "type": "shadowColor", + "attrs": { "shadowColor": "#ff000080" } + } + ] + } + ] + } + ] +} diff --git a/src/tests/unit/data/clean/json/simple_text_tiptap.json b/src/tests/unit/data/clean/json/simple_text.json similarity index 100% rename from src/tests/unit/data/clean/json/simple_text_tiptap.json rename to src/tests/unit/data/clean/json/simple_text.json diff --git a/src/tests/unit/data/clean/json/simple_unicode_tiptap.json b/src/tests/unit/data/clean/json/simple_unicode.json similarity index 100% rename from src/tests/unit/data/clean/json/simple_unicode_tiptap.json rename to src/tests/unit/data/clean/json/simple_unicode.json diff --git a/src/tests/unit/data/clean/snbt/base16_shadow_color.snbt b/src/tests/unit/data/clean/snbt/base16_shadow_color.snbt index c475b5b..4c58457 100644 --- a/src/tests/unit/data/clean/snbt/base16_shadow_color.snbt +++ b/src/tests/unit/data/clean/snbt/base16_shadow_color.snbt @@ -1 +1 @@ -["",{shadow_color:"#ff0000",text:"oooo spooky shadows"}] \ No newline at end of file +["",{shadow_color:"#ffff0000",text:"oooo spooky shadows"}] \ No newline at end of file diff --git a/src/tests/unit/optimising_mc_json.spec.ts b/src/tests/unit/exporting/optimising_mc_json.spec.ts similarity index 98% rename from src/tests/unit/optimising_mc_json.spec.ts rename to src/tests/unit/exporting/optimising_mc_json.spec.ts index 416ffee..63c68e0 100644 --- a/src/tests/unit/optimising_mc_json.spec.ts +++ b/src/tests/unit/exporting/optimising_mc_json.spec.ts @@ -1,5 +1,5 @@ import { optimise } from "$lib/text/nbt/optimiser"; -import { describe, it, expect } from "vitest"; +import { describe, expect, it } from "vitest"; // Minimal mock types for test compatibility type StringyMCText = string | { [key: string]: any }; diff --git a/src/tests/unit/exporting/translating_mc_json.spec.ts b/src/tests/unit/exporting/translating_mc_json.spec.ts new file mode 100644 index 0000000..73ad299 --- /dev/null +++ b/src/tests/unit/exporting/translating_mc_json.spec.ts @@ -0,0 +1,174 @@ +import { outputVersion } from "$lib/stores"; +import { translateJSON } from "$lib/text/nbt/export"; +import { versions, type TranslateOptions } from "$lib/types"; +import type { JSONContent } from "@tiptap/core"; +import { expect, it } from "vitest"; +import { readTestDataFile, readTestJSONFile } from "../test_utils"; + +it("should return a basic string", () => { + const document = { + type: "doc", + content: [{ type: "paragraph", content: [{ type: "text", text: "test" }] }], + }; + const snbt = translateJSON(document, { + exportType: "standard", + optimise: true, + }); + expect(snbt).toEqual('"test"'); +}); + +it("should return a basic color string", async () => { + const document = await readTestDataFile("clean/json/basic_color_tiptap.json"); + const snbt = translateJSON(JSON.parse(document), { + exportType: "standard", + optimise: true, + }); + expect(JSON.parse(snbt)).toEqual(["", { text: "test", color: "dark_red" }]); +}); + +const baseOptions: TranslateOptions = { + exportType: "standard", + optimise: false, +}; + +it("returns waiting message for empty content", () => { + const json: JSONContent = {}; + const result = translateJSON(json, baseOptions); + expect(result).toBeOneOf([ + "waiting for input...", + "🤓 <- kevin is waiting for you to type something", + ]); +}); + +it("translates simple text node", () => { + const json: JSONContent = { + content: [ + { + content: [ + { + type: "text", + text: "Hello", + marks: [], + }, + ], + }, + ], + }; + const result = translateJSON(json, baseOptions); + expect(result).toContain("Hello"); + expect(result).not.toContain("color"); +}); + +it("applies bold and italic marks", () => { + const json: JSONContent = { + content: [ + { + content: [ + { + type: "text", + text: "BoldItalic", + marks: [{ type: "bold" }, { type: "italic" }], + }, + ], + }, + ], + }; + const result = translateJSON(json, baseOptions); + expect(result).toContain("BoldItalic"); + expect(result).toContain('"bold":true'); + expect(result).toContain('"italic":true'); +}); + +it("should not apply bold, italic, or obfuscated marks to objects", async () => { + const json: JSONContent = (await readTestJSONFile( + "clean/json/illegal_marked_object.json", + )) as JSONContent; + outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports atlas_object and player_object + const result = translateJSON(json, baseOptions); + expect(result).toContain('"object":"player"'); + expect(result).not.toContain('"bold":true'); + expect(result).not.toContain('"italic":true'); + expect(result).not.toContain('"obfuscated":true'); +}); + +it("handles shadowColor mark", async () => { + const json: JSONContent = (await readTestJSONFile( + "clean/json/shadow_color.json", + )) as JSONContent; + const result = translateJSON(json, baseOptions); + expect(result).toContain('"shadow_color":16711935'); +}); + +it("handles shadowColor transparency", async () => { + const json: JSONContent = (await readTestJSONFile( + "clean/json/shadow_color_transparent.json", + )) as JSONContent; + const result = translateJSON(json, baseOptions); + expect(result).toContain('"shadow_color":2164195328L'); +}); + +it("should remove shadow_color if out of range", async () => { + const json: JSONContent = (await readTestJSONFile( + "bad/json/too_big_shadow_color.json", + )) as JSONContent; + const result = translateJSON(json, baseOptions); + expect(result).not.toContain('"shadow_color"'); +}); + +it("handles multiple paragraphs with newlines", () => { + const json: JSONContent = { + content: [ + { + content: [{ type: "text", text: "First", marks: [] }], + }, + { + content: [{ type: "text", text: "Second", marks: [] }], + }, + ], + }; + const result = translateJSON(json, baseOptions); + expect(result).toContain("First"); + expect(result).toContain("Second"); + expect(result).toContain("\\n"); +}); + +it("uses older format output when exportVersion=old", async () => { + const json: JSONContent = (await readTestJSONFile( + "clean/json/interactives_tiptap.json", + )) as JSONContent; + outputVersion.set(versions[0]); + const result = translateJSON(json, { + ...baseOptions, + }); + expect(JSON.parse(result)).toHaveProperty("[1].clickEvent"); + expect(JSON.parse(result)).not.toHaveProperty("[1].click_event"); + expect(JSON.parse(result)).toHaveProperty("[1].hoverEvent"); + expect(JSON.parse(result)).not.toHaveProperty("[1].hover_event"); +}); + +it("handles exportType=item_lore", () => { + const json: JSONContent = { + content: [ + { + content: [{ type: "text", text: "Lore", marks: [] }], + }, + ], + }; + const result = translateJSON(json, { + ...baseOptions, + exportType: "item_lore", + }); + expect(result).toContain("Lore"); + expect(result.startsWith("[")).toBe(true); +}); + +it("handles unknown exportType gracefully", () => { + const json: JSONContent = { + content: [], + }; + const result = translateJSON(json, { + ...baseOptions, + exportType: "unknown" as any, + }); + expect(result).toBe("[]"); +}); diff --git a/src/tests/unit/exporting/type_props.spec.ts b/src/tests/unit/exporting/type_props.spec.ts new file mode 100644 index 0000000..ed1d8d5 --- /dev/null +++ b/src/tests/unit/exporting/type_props.spec.ts @@ -0,0 +1,101 @@ +import { outputVersion } from "$lib/stores"; +import { addTypeSpecificValues } from "$lib/text/nbt/export"; +import { versions, type MinecraftText } from "$lib/types"; +import type { JSONContent } from "@tiptap/core"; +import { expect, it } from "vitest"; + +it("should add text property for type 'text'", () => { + const current: MinecraftText = {}; + const c: JSONContent = { type: "text", text: "hello" }; + const result = addTypeSpecificValues(current, c, false); + expect(result.text).toBe("hello"); +}); + +it("should add score property for type 'score'", () => { + const current: MinecraftText = {}; + const c: JSONContent = { + type: "score", + attrs: { name: "player", objective: "obj" }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result.score).toEqual({ name: "player", objective: "obj" }); +}); + +it("should add translate, with, and fallback for type 'translate'", () => { + const current: MinecraftText = {}; + const c: JSONContent = { + type: "translate", + attrs: { + key: "translation.key", + params: ["param1", "param2"], + fallback: "fallback text", + }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result.translate).toBe("translation.key"); + expect(result.with).toEqual(["param1", "param2"]); + expect(result.fallback).toBe("fallback text"); +}); + +it("should add nbt, storage, block, entity, interpret for nbt types", () => { + const current: MinecraftText = {}; + const c: JSONContent = { + type: "storage_nbt", + attrs: { + nbt: "someNbt", + storage: "someStorage", + block: "someBlock", + entity: "someEntity", + interpret: true, + }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result.nbt).toBe("someNbt"); + expect(result.storage).toBe("someStorage"); + expect(result.block).toBe("someBlock"); + expect(result.entity).toBe("someEntity"); + expect(result.interpret).toBe(true); +}); + +it("should add keybind property for type 'keybind'", () => { + const current: MinecraftText = {}; + const c: JSONContent = { type: "keybind", attrs: { key: "key.jump" } }; + const result = addTypeSpecificValues(current, c, false); + expect(result.keybind).toBe("key.jump"); +}); + +it("should add selector property for type 'selector'", () => { + const current: MinecraftText = {}; + const c: JSONContent = { type: "selector", attrs: { selector: "@a" } }; + const result = addTypeSpecificValues(current, c, false); + expect(result.selector).toBe("@a"); +}); + +it("should add atlas and sprite for type 'atlas_object'", () => { + outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports atlas_object + const current: MinecraftText = {}; + const c: JSONContent = { + type: "atlas_object", + attrs: { + atlas: "someAtlas", + sprite: "someSprite", + }, + }; + + const result = addTypeSpecificValues(current, c, false); + expect(result.atlas).toBe("someAtlas"); + expect(result.sprite).toBe("someSprite"); +}); + +it("should add object, player, and hat for type 'player_object'", () => { + outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports player_object + const current: MinecraftText = {}; + const c: JSONContent = { + type: "player_object", + attrs: { player: { name: "Cbble_" }, hat: true }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result.object).toBe("player"); + expect(result.player).toEqual({ name: "Cbble_" }); + expect(result.hat).toBe(true); +}); diff --git a/src/tests/unit/importing/snbt_importing.spec.ts b/src/tests/unit/importing/snbt_importing.spec.ts new file mode 100644 index 0000000..293e8a5 --- /dev/null +++ b/src/tests/unit/importing/snbt_importing.spec.ts @@ -0,0 +1,205 @@ +import { convertToTextOrEmpty, snbtToDocument } from "$lib/text/nbt/import"; +import { describe, expect, it } from "vitest"; +import { readTestDataFile, readTestJSONFile } from "../test_utils"; + +it("should return a basic document", async () => { + const document = snbtToDocument(convertToTextOrEmpty('"test"')); + const expectedDocument = await readTestJSONFile( + "clean/json/simple_text.json", + ); + expect(document).toEqual(expectedDocument); +}); + +it("should return a basic document (empty str)", async () => { + const document = snbtToDocument(convertToTextOrEmpty("")); + const expectedDocument = { content: [], type: "doc" }; + expect(document).toEqual(expectedDocument); +}); + +it("should apply a color to a text node", async () => { + const basicColorSNBT = await readTestDataFile("clean/snbt/basic_color.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + + const mark = textNode?.marks?.at(0); + + expect(mark?.type).toMatch("textStyle"); + + expect(mark?.attrs?.color).toBeDefined(); + expect(mark?.attrs?.color).toMatch("#AA0000"); +}); + +it("should apply a hex color to a text node", async () => { + const basicColorSNBT = await readTestDataFile("clean/snbt/hex_color.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + + const mark = textNode?.marks?.at(0); + + expect(mark?.type).toMatch("textStyle"); + + expect(mark?.attrs?.color).toBeDefined(); + expect(mark?.attrs?.color).toMatch("#c0bb1e"); +}); + +it("should apply a decimal shadow color to a text node", async () => { + const basicColorSNBT = await readTestDataFile( + "clean/snbt/base10_shadow_color.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + + const mark = textNode?.marks?.at(0); + + expect(mark?.type).toMatch("shadowColor"); + + expect(mark?.attrs?.shadowColor).toBeDefined(); + expect(mark?.attrs?.shadowColor).toMatch("#ffff0000"); +}); + +it("should apply a hexadecimal shadow color to a text node", async () => { + const basicColorSNBT = await readTestDataFile( + "clean/snbt/base16_shadow_color.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + + const mark = textNode?.marks?.at(0); + + expect(mark?.type).toMatch("shadowColor"); + + expect(mark?.attrs?.shadowColor).toBeDefined(); + expect(mark?.attrs?.shadowColor).toMatch("#ffff0000"); +}); + +it("should throw an error if the format is invalid", async () => { + const broken = await readTestDataFile("bad/broken.snbt"); + const converted = convertToTextOrEmpty(broken); + expect( + JSON.stringify(converted).includes( + "An error occurred while parsing the SNBT", + ), + ).toBe(true); +}); + +it("should return a one length array if passed with a single component", async () => { + const singleComponentSNBT = await readTestDataFile( + "clean/snbt/single_component.snbt", + ); + const converted = convertToTextOrEmpty(singleComponentSNBT); + expect(converted.length).toEqual(1); + expect(converted[0]).toEqual({ text: "hi", color: "#c0bb1e" }); +}); + +describe("handling text styling marks", () => { + it("should bold text styling to a text node", async () => { + const allTextStyleSNBT = await readTestDataFile( + "clean/snbt/all_text_style_marks.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); + + expect(textNode?.marks).toContainEqual({ type: "bold" }); + }); + + it("should italic text styling to a text node", async () => { + const allTextStyleSNBT = await readTestDataFile( + "clean/snbt/all_text_style_marks.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); + + expect(textNode?.marks).toContainEqual({ type: "italic" }); + }); + + it("should obfuscated text styling to a text node", async () => { + const allTextStyleSNBT = await readTestDataFile( + "clean/snbt/all_text_style_marks.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); + + expect(textNode?.marks).toContainEqual({ type: "obfuscated" }); + }); + + it("should underline text styling to a text node", async () => { + const allTextStyleSNBT = await readTestDataFile( + "clean/snbt/all_text_style_marks.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); + + expect(textNode?.marks).toContainEqual({ type: "underline" }); + }); + + it("should strike text styling to a text node", async () => { + const allTextStyleSNBT = await readTestDataFile( + "clean/snbt/all_text_style_marks.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); + + expect(textNode?.marks).toContainEqual({ type: "strike" }); + }); + + it("should handle unicode characters", async () => { + const unicodeSNBT = await readTestDataFile("clean/snbt/unicode.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(unicodeSNBT)); + const expectedDocument = await readTestJSONFile( + "clean/json/simple_unicode.json", + ); + expect(document).toEqual(expectedDocument); + }); +}); + +describe("handling invalid cases", () => { + it("should return nothing if its an empty string literal", () => { + const document = snbtToDocument(convertToTextOrEmpty('""')); + expect(document).toEqual({ + type: "doc", + content: [], + }); + }); + + it("should return nothing if its an empty string", () => { + const document = snbtToDocument(convertToTextOrEmpty("")); + expect(document).toEqual({ + type: "doc", + content: [], + }); + }); +}); + +describe("handling extra", () => { + it("should apply text styling (bold)", async () => { + const boldSNBT = await readTestDataFile("clean/snbt/extra_test.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(boldSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + expect(textNode?.marks?.[0].type).toMatch("bold"); + + const translateNode = document.content?.[0]?.content?.at(-1); + expect(translateNode?.marks).toBeDefined(); + expect(translateNode?.marks).toHaveLength(1); + expect(translateNode?.marks?.[0].type).toMatch("bold"); + }); +}); diff --git a/src/tests/unit/importing/source_props.spec.ts b/src/tests/unit/importing/source_props.spec.ts new file mode 100644 index 0000000..2ac74aa --- /dev/null +++ b/src/tests/unit/importing/source_props.spec.ts @@ -0,0 +1,194 @@ +import { convertToTextOrEmpty, snbtToDocument } from "$lib/text/nbt/import"; +import { expect, it } from "vitest"; +import { readTestDataFile } from "../test_utils"; + +it("should properly apply the font properties", async () => { + const fontsSNBT = await readTestDataFile("clean/snbt/fonts.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(fontsSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks).toBeDefined(); + expect(textNode?.marks).toHaveLength(1); + + const mark = textNode?.marks?.at(0); + + expect(mark?.type).toMatch("textStyle"); + + expect(mark?.attrs?.font).toBeDefined(); + expect(mark?.attrs?.font).toMatch("minecraft:illageralt"); +}); + +it("should properly apply text properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + + expect(node[0].type).toMatch("text"); + expect(node[0].text).toMatch("hi"); +}); + +it("should properly apply translate properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[1].attrs!; + + expect(node[1].type).toMatch("translate"); + expect(node[1].attrs).toBeDefined(); + expect(attrs.key).toBeDefined(); + expect(attrs.key).toMatch("hi"); + expect(attrs.fallback).toBeDefined(); + expect(attrs.fallback).toMatch("hi"); + expect(attrs.params).toBeDefined(); +}); + +it("should properly apply storage NBT properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[2].attrs!; + + expect(node[2].type).toMatch("storage_nbt"); + expect(node[2].attrs).toBeDefined(); + expect(attrs.storage).toBeDefined(); + expect(attrs.storage).toMatch("hi"); + expect(attrs.nbt).toBeDefined(); + expect(attrs.nbt).toMatch("Items[0].id"); + expect(attrs.interpret).toBeDefined(); + expect(attrs.interpret).toEqual(true); +}); + +it("should properly apply block NBT properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[3].attrs!; + + expect(node[3].type).toMatch("block_nbt"); + expect(node[3].attrs).toBeDefined(); + expect(attrs.block).toBeDefined(); + expect(attrs.block).toMatch("blah"); + expect(attrs.nbt).toBeDefined(); + expect(attrs.nbt).toMatch("Items[0].id"); + expect(attrs.interpret).toBeDefined(); + expect(attrs.interpret).toEqual(false); +}); + +it("should properly apply entity NBT properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[4].attrs!; + + expect(node[4].type).toMatch("entity_nbt"); + expect(node[4].attrs).toBeDefined(); + expect(attrs.entity).toBeDefined(); + expect(attrs.entity).toMatch("blah"); + expect(attrs.nbt).toBeDefined(); + expect(attrs.nbt).toMatch("Items[0].id"); + expect(attrs.interpret).toBeDefined(); + expect(attrs.interpret).toEqual(false); +}); + +it("should properly apply score properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[5].attrs!; + + expect(node[5].type).toMatch("score"); + expect(node[5].attrs).toBeDefined(); + expect(attrs.name).toBeDefined(); + expect(attrs.name).toMatch("@s"); + expect(attrs.objective).toBeDefined(); + expect(attrs.objective).toMatch("money"); +}); +it("should properly apply selector properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[6].attrs!; + + expect(node[6].type).toMatch("selector"); + expect(node[6].attrs).toBeDefined(); + expect(attrs.selector).toBeDefined(); + expect(attrs.selector).toMatch("@p"); +}); + +it("should properly apply keybind properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[7].attrs!; + + expect(node[7].type).toMatch("keybind"); + expect(node[7].attrs).toBeDefined(); + expect(attrs.key).toBeDefined(); + expect(attrs.key).toMatch("key.jump"); +}); + +it("should properly apply atlas object properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[8].attrs!; + + expect(node[8].type).toMatch("atlas_object"); + expect(node[8].attrs).toBeDefined(); + expect(attrs.atlas).toBeDefined(); + expect(attrs.atlas).toMatch("Banana"); + expect(attrs.sprite).toMatch("blah"); +}); + +it("should properly apply player object properties", async () => { + const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); + const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); + const textNode = document.content![0]; + expect(textNode).toBeDefined(); + expect(textNode.type).toMatch("paragraph"); + + const node = textNode.content!; + const attrs = node[9].attrs!; + + expect(node[9].type).toMatch("player_object"); + expect(node[9].attrs).toBeDefined(); + expect(attrs.player).toBeDefined(); + expect(attrs.player.name).toBeDefined(); + expect(attrs.player.name).toMatch("Cbble_"); + expect(attrs.hat).toEqual(true); +}); diff --git a/src/tests/unit/utils.spec.ts b/src/tests/unit/misc/utils.spec.ts similarity index 97% rename from src/tests/unit/utils.spec.ts rename to src/tests/unit/misc/utils.spec.ts index a60581c..96b99c6 100644 --- a/src/tests/unit/utils.spec.ts +++ b/src/tests/unit/misc/utils.spec.ts @@ -7,8 +7,7 @@ import { unescapeUnicode, } from "$lib/text/utils"; import type { JSONContent } from "@tiptap/core"; -import { it } from "vitest"; -import { describe, expect } from "vitest"; +import { describe, expect, it } from "vitest"; describe("isDefinedTextObject", () => { it("should report defined object with minimal object", () => { diff --git a/src/tests/unit/snbt_importing.spec.ts b/src/tests/unit/snbt_importing.spec.ts deleted file mode 100644 index 3a99101..0000000 --- a/src/tests/unit/snbt_importing.spec.ts +++ /dev/null @@ -1,412 +0,0 @@ -import { - convertToTextOrEmpty, - snbtToDocument, -} from "../../lib/text/nbt/import"; -import { describe, expect, it } from "vitest"; -import { readTestDataFile, readTestJSONFile } from "./test_utils"; - -it("should return a basic document", async () => { - const document = snbtToDocument(convertToTextOrEmpty('"test"')); - const expectedDocument = await readTestJSONFile( - "clean/json/simple_text_tiptap.json", - ); - expect(document).toEqual(expectedDocument); -}); - -it("should return a basic document (empty str)", async () => { - const document = snbtToDocument(convertToTextOrEmpty("")); - const expectedDocument = { content: [], type: "doc" }; - expect(document).toEqual(expectedDocument); -}); - -it("should apply a color to a text node", async () => { - const basicColorSNBT = await readTestDataFile("clean/snbt/basic_color.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - - const mark = textNode?.marks?.at(0); - - expect(mark?.type).toMatch("textStyle"); - - expect(mark?.attrs?.color).toBeDefined(); - expect(mark?.attrs?.color).toMatch("#AA0000"); -}); - -it("should apply a hex color to a text node", async () => { - const basicColorSNBT = await readTestDataFile("clean/snbt/hex_color.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - - const mark = textNode?.marks?.at(0); - - expect(mark?.type).toMatch("textStyle"); - - expect(mark?.attrs?.color).toBeDefined(); - expect(mark?.attrs?.color).toMatch("#c0bb1e"); -}); - -it.skip("should apply a decimal shadow color to a text node", async () => { - const basicColorSNBT = await readTestDataFile( - "clean/snbt/base10_shadow_color.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - - const mark = textNode?.marks?.at(0); - - expect(mark?.type).toMatch("shadowColor"); - - expect(mark?.attrs?.shadowColor).toBeDefined(); - expect(mark?.attrs?.shadowColor).toMatch("#ff0000"); -}); - -it.skip("should apply a hexadecimal shadow color to a text node", async () => { - const basicColorSNBT = await readTestDataFile( - "clean/snbt/base16_shadow_color.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(basicColorSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - - const mark = textNode?.marks?.at(0); - - expect(mark?.type).toMatch("shadowColor"); - - expect(mark?.attrs?.shadowColor).toBeDefined(); - expect(mark?.attrs?.shadowColor).toMatch("#ff0000"); -}); - -it("should throw an error if the format is invalid", async () => { - const broken = await readTestDataFile("bad/broken.snbt"); - const converted = convertToTextOrEmpty(broken); - expect( - JSON.stringify(converted).includes( - "An error occurred while parsing the SNBT", - ), - ).toBe(true); -}); - -it("should return a one length array if passed with a single component", async () => { - const singleComponentSNBT = await readTestDataFile( - "clean/snbt/single_component.snbt", - ); - const converted = convertToTextOrEmpty(singleComponentSNBT); - expect(converted.length).toEqual(1); - expect(converted[0]).toEqual({ text: "hi", color: "#c0bb1e" }); -}); - -describe("handling text styling marks", () => { - it("should bold text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "bold" }); - }); - - it("should italic text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "italic" }); - }); - - it("should obfuscated text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "obfuscated" }); - }); - - it("should underline text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "underline" }); - }); - - it("should strike text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "strike" }); - }); - - it("should strike text styling to a text node", async () => { - const allTextStyleSNBT = await readTestDataFile( - "clean/snbt/all_text_style_marks.snbt", - ); - const document = snbtToDocument(convertToTextOrEmpty(allTextStyleSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks?.length).toBeGreaterThanOrEqual(1); - - expect(textNode?.marks).toContainEqual({ type: "strike" }); - }); -}); - -it("should return nothing if its an empty string literal", () => { - const document = snbtToDocument(convertToTextOrEmpty('""')); - expect(document).toEqual({ - type: "doc", - content: [], - }); -}); - -it("should return nothing if its an empty string", () => { - const document = snbtToDocument(convertToTextOrEmpty("")); - expect(document).toEqual({ - type: "doc", - content: [], - }); -}); - -it("should handle unicode characters", async () => { - const unicodeSNBT = await readTestDataFile("clean/snbt/unicode.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(unicodeSNBT)); - const expectedDocument = await readTestJSONFile( - "clean/json/simple_unicode_tiptap.json", - ); - expect(document).toEqual(expectedDocument); -}); - -it("should properly apply the font properties", async () => { - const fontsSNBT = await readTestDataFile("clean/snbt/fonts.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(fontsSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - - const mark = textNode?.marks?.at(0); - - expect(mark?.type).toMatch("textStyle"); - - expect(mark?.attrs?.font).toBeDefined(); - expect(mark?.attrs?.font).toMatch("minecraft:illageralt"); -}); - -describe("applying source props", () => { - it("should properly apply text properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - - expect(node[0].type).toMatch("text"); - expect(node[0].text).toMatch("hi"); - }); - - it("should properly apply translate properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[1].attrs!; - - expect(node[1].type).toMatch("translate"); - expect(node[1].attrs).toBeDefined(); - expect(attrs.key).toBeDefined(); - expect(attrs.key).toMatch("hi"); - expect(attrs.fallback).toBeDefined(); - expect(attrs.fallback).toMatch("hi"); - expect(attrs.params).toBeDefined(); - // TODO: add checks for the `with` array - }); - - it("should properly apply storage NBT properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[2].attrs!; - - expect(node[2].type).toMatch("storage_nbt"); - expect(node[2].attrs).toBeDefined(); - expect(attrs.storage).toBeDefined(); - expect(attrs.storage).toMatch("hi"); - expect(attrs.nbt).toBeDefined(); - expect(attrs.nbt).toMatch("Items[0].id"); - expect(attrs.interpret).toBeDefined(); - expect(attrs.interpret).toEqual(true); - }); - - it("should properly apply block NBT properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[3].attrs!; - - expect(node[3].type).toMatch("block_nbt"); - expect(node[3].attrs).toBeDefined(); - expect(attrs.block).toBeDefined(); - expect(attrs.block).toMatch("blah"); - expect(attrs.nbt).toBeDefined(); - expect(attrs.nbt).toMatch("Items[0].id"); - expect(attrs.interpret).toBeDefined(); - expect(attrs.interpret).toEqual(false); - }); - - it("should properly apply entity NBT properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[4].attrs!; - - expect(node[4].type).toMatch("entity_nbt"); - expect(node[4].attrs).toBeDefined(); - expect(attrs.entity).toBeDefined(); - expect(attrs.entity).toMatch("blah"); - expect(attrs.nbt).toBeDefined(); - expect(attrs.nbt).toMatch("Items[0].id"); - expect(attrs.interpret).toBeDefined(); - expect(attrs.interpret).toEqual(false); - }); - - it("should properly apply score properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[5].attrs!; - - expect(node[5].type).toMatch("score"); - expect(node[5].attrs).toBeDefined(); - expect(attrs.name).toBeDefined(); - expect(attrs.name).toMatch("@s"); - expect(attrs.objective).toBeDefined(); - expect(attrs.objective).toMatch("money"); - }); - it("should properly apply selector properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[6].attrs!; - - expect(node[6].type).toMatch("selector"); - expect(node[6].attrs).toBeDefined(); - expect(attrs.selector).toBeDefined(); - expect(attrs.selector).toMatch("@p"); - }); - - it("should properly apply keybind properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[7].attrs!; - - expect(node[7].type).toMatch("keybind"); - expect(node[7].attrs).toBeDefined(); - expect(attrs.key).toBeDefined(); - expect(attrs.key).toMatch("key.jump"); - }); - - it("should properly apply atlas object properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[8].attrs!; - - expect(node[8].type).toMatch("atlas_object"); - expect(node[8].attrs).toBeDefined(); - expect(attrs.atlas).toBeDefined(); - expect(attrs.atlas).toMatch("Banana"); - expect(attrs.sprite).toMatch("blah"); - }); - - it("should properly apply player object properties", async () => { - const sourceSNBT = await readTestDataFile("clean/snbt/source.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(sourceSNBT)); - const textNode = document.content![0]; - expect(textNode).toBeDefined(); - expect(textNode.type).toMatch("paragraph"); - - const node = textNode.content!; - const attrs = node[9].attrs!; - - expect(node[9].type).toMatch("player_object"); - expect(node[9].attrs).toBeDefined(); - expect(attrs.player).toBeDefined(); - expect(attrs.player.name).toBeDefined(); - expect(attrs.player.name).toMatch("Cbble_"); - expect(attrs.hat).toEqual(true); - }); -}); - -describe("handling extra", () => { - it("should apply text styling (bold)", async () => { - const boldSNBT = await readTestDataFile("clean/snbt/extra_test.snbt"); - const document = snbtToDocument(convertToTextOrEmpty(boldSNBT)); - const textNode = document.content?.[0]?.content?.[0]; - expect(textNode?.marks).toBeDefined(); - expect(textNode?.marks).toHaveLength(1); - expect(textNode?.marks?.[0].type).toMatch("bold"); - - const translateNode = document.content?.[0]?.content?.at(-1); - expect(translateNode?.marks).toBeDefined(); - expect(translateNode?.marks).toHaveLength(1); - expect(translateNode?.marks?.[0].type).toMatch("bold"); - }); -}); diff --git a/src/tests/unit/translating_mc_json.spec.ts b/src/tests/unit/translating_mc_json.spec.ts deleted file mode 100644 index cc57011..0000000 --- a/src/tests/unit/translating_mc_json.spec.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { addTypeSpecificValues, translateJSON } from "$lib/text/nbt/export"; -import { - versions, - type MinecraftText, - type TranslateOptions, -} from "$lib/types"; -import type { JSONContent } from "@tiptap/core"; -import { describe, expect, it } from "vitest"; -import { readTestDataFile, readTestJSONFile } from "./test_utils"; -import { outputVersion } from "$lib/stores"; - -describe("translate", () => { - it("should return a basic string", () => { - const document = { - type: "doc", - content: [ - { type: "paragraph", content: [{ type: "text", text: "test" }] }, - ], - }; - const snbt = translateJSON(document, { - exportType: "standard", - optimise: true, - }); - expect(snbt).toEqual('"test"'); - }); - - it("should return a basic color string", async () => { - const document = await readTestDataFile( - "clean/json/basic_color_tiptap.json", - ); - const snbt = translateJSON(JSON.parse(document), { - exportType: "standard", - optimise: true, - }); - expect(JSON.parse(snbt)).toEqual(["", { text: "test", color: "dark_red" }]); - }); - - const baseOptions: TranslateOptions = { - exportType: "standard", - optimise: false, - }; - - it("returns waiting message for empty content", () => { - const json: JSONContent = {}; - const result = translateJSON(json, baseOptions); - expect(result).toBeOneOf([ - "waiting for input...", - "🤓 <- kevin is waiting for you to type something", - ]); - }); - - it("translates simple text node", () => { - const json: JSONContent = { - content: [ - { - content: [ - { - type: "text", - text: "Hello", - marks: [], - }, - ], - }, - ], - }; - const result = translateJSON(json, baseOptions); - expect(result).toContain("Hello"); - expect(result).not.toContain("color"); - }); - - it("applies bold and italic marks", () => { - const json: JSONContent = { - content: [ - { - content: [ - { - type: "text", - text: "BoldItalic", - marks: [{ type: "bold" }, { type: "italic" }], - }, - ], - }, - ], - }; - const result = translateJSON(json, baseOptions); - expect(result).toContain("BoldItalic"); - expect(result).toContain('"bold":true'); - expect(result).toContain('"italic":true'); - }); - - it.skip("handles shadowColor mark", () => { - const json: JSONContent = { - content: [ - { - content: [ - { - type: "text", - text: "Shadow", - marks: [ - { - type: "shadowColor", - attrs: { shadowColor: "#ff00ff" }, - }, - ], - }, - ], - }, - ], - }; - const result = translateJSON(json, baseOptions); - expect(result).toContain('"shadow_color":-65281'); - }); - - it("handles multiple paragraphs with newlines", () => { - const json: JSONContent = { - content: [ - { - content: [{ type: "text", text: "First", marks: [] }], - }, - { - content: [{ type: "text", text: "Second", marks: [] }], - }, - ], - }; - const result = translateJSON(json, baseOptions); - expect(result).toContain("First"); - expect(result).toContain("Second"); - expect(result).toContain("\\n"); - }); - - it("optimises output when optimise=true", () => { - const json: JSONContent = { - content: [ - { - content: [ - { type: "text", text: "A", marks: [] }, - { type: "text", text: "B", marks: [] }, - ], - }, - ], - }; - const result = translateJSON(json, { ...baseOptions, optimise: true }); - expect(result).toContain("A"); - expect(result).toContain("B"); - }); - - it("uses older format output when exportVersion=old", async () => { - const json: JSONContent = (await readTestJSONFile( - "clean/json/interactives_tiptap.json", - )) as JSONContent; - outputVersion.set(versions[0]); - const result = translateJSON(json, { - ...baseOptions, - }); - expect(JSON.parse(result)).toHaveProperty("[1].clickEvent"); - expect(JSON.parse(result)).not.toHaveProperty("[1].click_event"); - expect(JSON.parse(result)).toHaveProperty("[1].hoverEvent"); - expect(JSON.parse(result)).not.toHaveProperty("[1].hover_event"); - }); - - it("handles exportType=item_lore", () => { - const json: JSONContent = { - content: [ - { - content: [{ type: "text", text: "Lore", marks: [] }], - }, - ], - }; - const result = translateJSON(json, { - ...baseOptions, - exportType: "item_lore", - }); - expect(result).toContain("Lore"); - expect(result.startsWith("[")).toBe(true); - }); - - it("handles unknown exportType gracefully", () => { - const json: JSONContent = { - content: [], - }; - const result = translateJSON(json, { - ...baseOptions, - exportType: "unknown" as any, - }); - expect(result).toBe("[]"); - }); -}); - -describe("adding type props", () => { - it("should add text property for type 'text'", () => { - const current: MinecraftText = {}; - const c: JSONContent = { type: "text", text: "hello" }; - const result = addTypeSpecificValues(current, c, false); - expect(result.text).toBe("hello"); - }); - - it("should add score property for type 'score'", () => { - const current: MinecraftText = {}; - const c: JSONContent = { - type: "score", - attrs: { name: "player", objective: "obj" }, - }; - const result = addTypeSpecificValues(current, c, false); - expect(result.score).toEqual({ name: "player", objective: "obj" }); - }); - - it("should add translate, with, and fallback for type 'translate'", () => { - const current: MinecraftText = {}; - const c: JSONContent = { - type: "translate", - attrs: { - key: "translation.key", - params: ["param1", "param2"], - fallback: "fallback text", - }, - }; - const result = addTypeSpecificValues(current, c, false); - expect(result.translate).toBe("translation.key"); - expect(result.with).toEqual(["param1", "param2"]); - expect(result.fallback).toBe("fallback text"); - }); - - it("should add nbt, storage, block, entity, interpret for nbt types", () => { - const current: MinecraftText = {}; - const c: JSONContent = { - type: "storage_nbt", - attrs: { - nbt: "someNbt", - storage: "someStorage", - block: "someBlock", - entity: "someEntity", - interpret: true, - }, - }; - const result = addTypeSpecificValues(current, c, false); - expect(result.nbt).toBe("someNbt"); - expect(result.storage).toBe("someStorage"); - expect(result.block).toBe("someBlock"); - expect(result.entity).toBe("someEntity"); - expect(result.interpret).toBe(true); - }); - - it("should add keybind property for type 'keybind'", () => { - const current: MinecraftText = {}; - const c: JSONContent = { type: "keybind", attrs: { key: "key.jump" } }; - const result = addTypeSpecificValues(current, c, false); - expect(result.keybind).toBe("key.jump"); - }); - - it("should add selector property for type 'selector'", () => { - const current: MinecraftText = {}; - const c: JSONContent = { type: "selector", attrs: { selector: "@a" } }; - const result = addTypeSpecificValues(current, c, false); - expect(result.selector).toBe("@a"); - }); -}); diff --git a/vite.config.ts b/vite.config.ts index f43b6dd..5e3b77f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -15,7 +15,7 @@ export default defineConfig({ name: "client", environment: "jsdom", clearMocks: true, - include: ["src/tests/unit/*.svelte.{test,spec}.{js,ts}"], + include: ["src/tests/unit/**/*.svelte.{test,spec}.{js,ts}"], exclude: ["src/lib/server/**"], setupFiles: ["./vitest-setup-client.ts"], }, @@ -25,7 +25,7 @@ export default defineConfig({ test: { name: "server", environment: "node", - include: ["src/tests/unit/*.{test,spec}.{js,ts}"], + include: ["src/tests/unit/**/*.{test,spec}.{js,ts}"], exclude: ["src/**/*.svelte.{test,spec}.{js,ts}"], }, }, From 4517b496f603cb394333171bbd69fc1096c88a13 Mon Sep 17 00:00:00 2001 From: Cobblestone Date: Wed, 22 Jul 2026 08:38:23 -0400 Subject: [PATCH 03/10] test updates part 2 --- bun.lock | 156 +-- package-lock.json | 963 +++++++++++------- package.json | 40 +- src/lib/text/nbt/export.ts | 20 +- src/lib/text/nbt/import.ts | 17 +- src/lib/text/nbt/optimiser.ts | 35 +- src/lib/text/utils.ts | 26 +- .../unit/data/clean/snbt/interactives.snbt | 1 + .../data/clean/snbt/interactives_old.snbt | 1 + .../unit/exporting/optimising_mc_json.spec.ts | 12 + src/tests/unit/exporting/type_props.spec.ts | 80 +- .../unit/importing/snbt_importing.spec.ts | 20 + src/tests/unit/misc/utils.spec.ts | 15 +- vite.config.ts | 2 +- 14 files changed, 854 insertions(+), 534 deletions(-) create mode 100644 src/tests/unit/data/clean/snbt/interactives.snbt create mode 100644 src/tests/unit/data/clean/snbt/interactives_old.snbt diff --git a/bun.lock b/bun.lock index 9ec8e90..7430543 100644 --- a/bun.lock +++ b/bun.lock @@ -103,7 +103,7 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], - "@iconify-json/tabler": ["@iconify-json/tabler@1.2.35", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-/sJMqHvh5ZWrEERVfDCT5NjVDeKJdhosFtKjJofAVl+P/3AzLiryOQw7WvrfDF25Xa5N/eoOQ15Y1jnhYXxBoQ=="], + "@iconify-json/tabler": ["@iconify-json/tabler@1.2.37", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-tXc0jGhrxec6eTKxMI9We/r3cEItyU5dG8ngDOEKsL36a6+/xwk4sR7PIZROVajzxmvyUBsn659adDIfcswiUw=="], "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], @@ -125,43 +125,43 @@ "@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="], - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.74.0", "", { "os": "android", "cpu": "arm" }, "sha512-+gHd12muVI9ZLBaWLPkHt3Fj7jihFjgQ1MGtBaRL8vWrWrI0P7dLUty/cHrHS0oqPYIRgQUJsPu2CExQuMcwNw=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.75.0", "", { "os": "android", "cpu": "arm" }, "sha512-lutovtFzJqlRaqpZrCqSSGaHZzl9nIxxpjLzhSRLunN6dCLylj0uzlCyQGaQDIys7rrv8kVXiFO+R4Zpn0bX7g=="], - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.74.0", "", { "os": "android", "cpu": "arm64" }, "sha512-xjKdoMB+H+RCOByv/7l7nfIGW9mlOisqYdcyC75UqYuQecLpReAeEYUf2CNeDEI3KtmUgxpRw/+c63y4AeF/Bw=="], + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.75.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hXI0hDgHkw4w5nfru72aG7y+2iQJmC4waH/KV6H/hbgA6yAP5jYNx0P9yug15Hs0tWl/+mda3Jjn/2gmDT48tw=="], - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.74.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iUK7wvc6sejMKsC+Pt67mntoF5weFcyEunhZfLJceU6gL419mexz5wBkSx/EnkFBExMLNtOi9fnDSc5xfK0IzQ=="], + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.75.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-D91BWbK/dMYfCcrghspPIuKs2D9LF4Z/OabVSQjw1AO6PWxArD7teDA48bm0ySFqWDaPVqmQRl5GMWNglTXyrQ=="], - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.74.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ggKc/tn5SJ1u2yG2izC6VKODfYKV8MQ2AicJlNzOjuyrC29udvOef6/JzK2r32xqCnBDLFouR1VCkjzEI0/N9Q=="], + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.75.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-02mpwzf12BonZ6PT0TuQoomvEh2kVl2WGBIKWezCyToIS+rYkQZ6GXnARBAl9A4Ovm2V+Xe7M4KretyqmmcnJQ=="], - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.74.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-u++dH/43jy9hTLbneaWlS0gla/Bp1JdwJ2zgevCl8nDFUh6qRCGMxcL0f0lb7By3A9p/LfFr+7cG4HU1hG856g=="], + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.75.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-qZJgLnDaBsiL5YESx2t/TZ8eXkL9fEkKoXEdzegROhlz9A0lgyGnZ0dAzJrh7LJAHQl2K9RdRueN2s/9N7+odg=="], - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.74.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Sj1zmtFDVTPeIbIz4ZfcXAbFHqCmKCXdCUlAJzvTF7I20NTH1RDpoF2PhkqNODutJzVhJYmm3oz0GwgY+tvE2g=="], + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.75.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7XlaWA5BJD3XpCfrEqjEe6Zseeb14S7QGa304XfwKignRaKQ+eIj775BQ7nIslggWickl4IsPUFqJ+/gAyNHVg=="], - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.74.0", "", { "os": "linux", "cpu": "arm" }, "sha512-//PKyQb/tQXcHArx2f7z+oVI/eMS2Jpv+edNuAtOrgIhWdGcpHxogveAxzmF2rpH1AIHp4Hq04RF/rgJdiICnQ=="], + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.75.0", "", { "os": "linux", "cpu": "arm" }, "sha512-av6Tpv8yrcMMMOadOqENBhlsLRcGFXXwoQ0hzHhsmS9FJ4Wioy8we427GbcMe2XTxmL2e60T67H1Dyr3up+tAA=="], - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.74.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-/k1Me+aX2tjuH10K62mLS0y8cLkJBHX6Ce0xPK+eWeel4bSdEGZ8dv4+hYMzg0GrSmjwy4yAYsDPeEeKBft/2w=="], + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.75.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-WcUhd8fHT5plrA14lANevl+hOl815mVI5t2hU21oFWrZKFXIVV/Sr4rWQV0NzSvzBupbMLNc5ErEA6Ehxh5jMg=="], - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.74.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3tFSjBxc5D8/zvjEuLvOqcA8ZXKD0+6NuaVO/edeamNc49MoAsbfaC9s1UiwODwgF6slGaF8yJA2TPkukd77tg=="], + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.75.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UWzp5wRHFe/ESO3+eEaxXsTkYTGLYjnTsi/I5neEacXSItQ6WNleapfOAeA4x2b8nyhJ4uQxqvtv9pHv8kWJtQ=="], - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.74.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9QggtPkSPXOCTu8Szis7auOK/sC7KdQaN+/TujP7YVVhzCAOhgdRfgv8uEz0r2tk5xdgus5rLYUrCDoZNtiRUw=="], + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.75.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-XEVRwGMLKCUKrvhLAz4F6AIh8MJrQVdSZtAmPpRZt9tGPsUnamPOcl3dS/ZQzJnar/Ymgc//+xho0L60Emzuxg=="], - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.74.0", "", { "os": "linux", "cpu": "none" }, "sha512-VM5VPUJ4DJIWiK+AZn8FScUqMr6OFrCAYybMYjEEi7W13ParI64MByiXTkKMqZpBmvQ9zxl9Ebq2VUOiZRJYUg=="], + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.75.0", "", { "os": "linux", "cpu": "none" }, "sha512-mAG4DUXqfLC8cTjMD2kt3jDmVzFREYtDyeLNdLdsCcBc4Zbl2EMuiFektGBilQwkNjYnMvCqJs55U+Hyb+b+jw=="], - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.74.0", "", { "os": "linux", "cpu": "none" }, "sha512-SaDY1gh9rOA592J54g+gu5hkOFFQBZsMmIYHs+NRHG+Uq0OxtuuCXMWQ3vu1830Eugv5uMXyjG+bv2Z9y4IXjw=="], + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.75.0", "", { "os": "linux", "cpu": "none" }, "sha512-95hrAvriAlI+pekSomTFIn0+bawMDlDwTNVmdjsFusTHyL2JWh7TWvRNG/Lkim72uN8OiCcO9wcaC6omLP5E3w=="], - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.74.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-ZATQeHZCyr6MbDveg0obD5sxLHFOghtOdC5jwVwYlvFWqtFOxctgFEG6Ef/64hYvZrWyhyCckB10AelqLopeDA=="], + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.75.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4b6f2+FrtruAESrCqIKcrarzfrSx+wk2QNcp+RT91/Prc+pMQMAfyZ1rG1c3tFQNl8Bc616tx40uNXyxNBRPbQ=="], - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.74.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+aIvJyrdeD7LwCQ2WYLMUWNmnbeDRSPb40aBYtPjD9+PTqUwgJnk+HK5yLfSMeqXrMrDhE9uTmtt2y50tvjhHw=="], + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.75.0", "", { "os": "linux", "cpu": "x64" }, "sha512-nshAhrUvXFUWOvqQ2soIw7HFNWvpvEV4o0cYSqPtzLiPF5gKyYTDOOTJ6Rn8g8K/iGvPIrbDA4v8+5MvnjJrrg=="], - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.74.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XyktaR8lhK2qWiCK0Tk8oYD+/cgn+oHA6ddRnxSSXUKkkojkV78CmShZUxQF+yrBFs0SuW+JBOPG6hecyc/iZg=="], + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.75.0", "", { "os": "linux", "cpu": "x64" }, "sha512-e4jNxLKnxLC6sYBQRxrI2pgIIxnmMtF8U/VwNYcjTT/CLS+spH624cYVnj07bTKwaEWT37/e025isOs6j/0xqA=="], - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.74.0", "", { "os": "none", "cpu": "arm64" }, "sha512-mzbjrPl4neaVUiJ1fUiEUxTGaSZBoiKtaoB6jmIpz9S+VOA2vDYmJpihQ82w6178V5jxziclTg8Cgj5yF6tTDg=="], + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.75.0", "", { "os": "none", "cpu": "arm64" }, "sha512-hZ2lH+1qLf/DiEP9UWuQTK2JWj/BgvMB4jhIV4SmNU1wfEiYYX4TynQyAZXx0j9X4qRYizAL042SKaV+8ynh4w=="], - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.74.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vUAe9okpS2Oa5+lX67lqHMuNUvfkleRKwrUDJ/WJBsgmddvZ1mrsh2HVmuFDRzqFELhaJhFaCNOuR6a7L3rtIA=="], + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.75.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Ilj6PNzGDS3bCU0MSJH7Msh0NhH+T/mRp2shwg+q+GHeVlPwP5LEboW96aW+3kVKFk6zYZy1Xi5pZkqZh6X8KQ=="], - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.74.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yyXXJyYYSXL4I8K8jAWjJs+J3fa9gH2JmEbo4f5adm+1tNC9itseicBNuwK7BDHvqQ5J534s+yDULu89vYL2ZQ=="], + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.75.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-QVit2nOEOiPhkmsrksPSkoGCdnZRNkspt8fwoYyP09te1VEbnSj4LAxua4rc8FKTmWkySVe05j8iz9GXYfF1AQ=="], - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.74.0", "", { "os": "win32", "cpu": "x64" }, "sha512-VTC9IYTIMrVUk/i6Ms1ohzzDKZFkWn0KU2OBbPBzgmVZ2V30165T/zK4LztTr0Xgp9fZ1qQZ1rsZAu/rEmySlA=="], + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.75.0", "", { "os": "win32", "cpu": "x64" }, "sha512-DSxnNkBUAYARPwJtR12Ig3deWr8w0H997xP6jy33i+e0SyYJw8FKuz4+cZtpmPEhQmvlPJE3X/2vNxDmLkd/rA=="], "@playwright/test": ["@playwright/test@1.61.1", "", { "dependencies": { "playwright": "1.61.1" }, "bin": { "playwright": "cli.js" } }, "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig=="], @@ -207,7 +207,7 @@ "@sveltejs/adapter-auto": ["@sveltejs/adapter-auto@7.0.1", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ=="], - "@sveltejs/kit": ["@sveltejs/kit@2.69.3", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.9", "@types/cookie": "^0.6.0", "acorn": "^8.16.0", "cookie": "^0.6.0", "devalue": "^5.8.1", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-cphwqMRcE19/9VkrIPr5qZhQ0SptSSDfDzRUpYHu9OJDFGuYBFyJzK+KQA27wB4YG32O/yF2QjBkDmTyo0vtCw=="], + "@sveltejs/kit": ["@sveltejs/kit@2.70.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.9", "@types/cookie": "^0.6.0", "acorn": "^8.16.0", "cookie": "^0.6.0", "devalue": "^5.8.1", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-nY9SPHGOZro3doud9vZXDBwl9tCZIouuJztjgSHs6PAIrv9M/z5O7eOhPV5xU7CgVHA976Jwu3BA1hIFvXztkA=="], "@sveltejs/load-config": ["@sveltejs/load-config@0.2.0", "", {}, "sha512-1LgZ/qUqSoq+QorD83lk2hka79Px0wXNW2q5V1nZlxGhQgw1jrsIbVz5YiCeucVLo4XvFLjXukUaQjIiqowkcg=="], @@ -215,101 +215,101 @@ "@swc/helpers": ["@swc/helpers@0.5.21", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg=="], - "@tailwindcss/node": ["@tailwindcss/node@4.3.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "5.21.6", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.2" } }, "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg=="], + "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="], - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.2", "@tailwindcss/oxide-darwin-arm64": "4.3.2", "@tailwindcss/oxide-darwin-x64": "4.3.2", "@tailwindcss/oxide-freebsd-x64": "4.3.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", "@tailwindcss/oxide-linux-x64-musl": "4.3.2", "@tailwindcss/oxide-wasm32-wasi": "4.3.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" } }, "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag=="], + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="], - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.2", "", { "os": "android", "cpu": "arm64" }, "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA=="], + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.3", "", { "os": "android", "cpu": "arm64" }, "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw=="], - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w=="], + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw=="], - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ=="], + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw=="], - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA=="], + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw=="], - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.2", "", { "os": "linux", "cpu": "arm" }, "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w=="], + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3", "", { "os": "linux", "cpu": "arm" }, "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ=="], - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw=="], + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w=="], - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA=="], + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA=="], - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w=="], + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w=="], - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw=="], + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img=="], - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.2", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw=="], + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.3", "", { "dependencies": { "@emnapi/core": "^1.11.1", "@emnapi/runtime": "^1.11.1", "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ=="], - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ=="], + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ=="], - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.2", "", { "os": "win32", "cpu": "x64" }, "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ=="], + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw=="], - "@tailwindcss/vite": ["@tailwindcss/vite@4.3.2", "", { "dependencies": { "@tailwindcss/node": "4.3.2", "@tailwindcss/oxide": "4.3.2", "tailwindcss": "4.3.2" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-eHpMeX4JXfVNJDEcsouTeCBubJBTcTLigeaw/NTUW6PB5ATKKXdyonnXgTBX2VuRbjz1hjfz6C5XAhr52ImQXA=="], + "@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="], "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], - "@testing-library/jest-dom": ["@testing-library/jest-dom@6.9.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" } }, "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA=="], + "@testing-library/jest-dom": ["@testing-library/jest-dom@6.10.0", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" }, "peerDependencies": { "@testing-library/dom": ">=10 <11" } }, "sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ=="], "@testing-library/svelte": ["@testing-library/svelte@5.4.2", "", { "dependencies": { "@testing-library/dom": "9.x.x || 10.x.x", "@testing-library/svelte-core": "1.1.3" }, "peerDependencies": { "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0", "vite": "*", "vitest": "*" }, "optionalPeers": ["vite", "vitest"] }, "sha512-4o31E4HGo5BU5KwPkulNRocEden+7Tt9JYm9uhln5ajF7DULeyFA46BBWVfKJ8Ms9B3JmOFPTIiVamH7n3KpuQ=="], "@testing-library/svelte-core": ["@testing-library/svelte-core@1.1.3", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0" } }, "sha512-KkMAvXeWorxN2Yn0kdC1lfoAItxpoj4uOWzxK5leDrNxonLvS5nwBFvztrroyTszQ0Wf/EU6iLT8JhY5qcn22g=="], - "@tiptap/core": ["@tiptap/core@3.27.4", "", { "peerDependencies": { "@tiptap/pm": "3.27.4" } }, "sha512-8W/GwlEn0JwNdpyVfTWcXwHYUpj9BWwO++YxtizmgjJzlwigSh7/xLVJMwVykuQHQ2fCq5rkUvmBRtpHOMLUQA=="], + "@tiptap/core": ["@tiptap/core@3.28.0", "", { "peerDependencies": { "@tiptap/pm": "3.28.0" } }, "sha512-gUuD5WAYfbDxNSSJya/emh2KSzXZXLUYKW4fEnc1AQ5FE2twzh4LJ9UlKFIawigrUCAksWI5Fy1hRbv+5m4ZdQ=="], - "@tiptap/extension-blockquote": ["@tiptap/extension-blockquote@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-d1tOHgP3R5cOE+Ot8qL/dkLXRByajgn+j6cCXHqDtmJO2wsK9knmbKQ0SEjbKrU6OgHrTnY/EotNxBEBW9HGoA=="], + "@tiptap/extension-blockquote": ["@tiptap/extension-blockquote@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-y8Xi6Z3AQLXedz0J8Z3kDsu7SKBmL50gKVXx3RK1Oo1cuCGhNChm3syChkAz3PLAbrPUM5rvJDSZdF2jUrDnng=="], - "@tiptap/extension-bold": ["@tiptap/extension-bold@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-wTtJUUAxCAZ01ICH2DNlOBzzHKRQ1ZST8aRYtIhBPzqEUhnJaKGcjnDB4X49fqPi48iXaPxzhsInDl+rVUujWg=="], + "@tiptap/extension-bold": ["@tiptap/extension-bold@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-JhZQmr0AU741bOwjVMfuwJdK4g0TQwwPbeca9aqKHv5zvZw4i4G9G6fESVyMFc3Yag1ffpnq5EtNldHKTnMhlw=="], - "@tiptap/extension-bullet-list": ["@tiptap/extension-bullet-list@3.27.4", "", { "peerDependencies": { "@tiptap/extension-list": "3.27.4" } }, "sha512-rvja0N1RnwGJAVwDdbUfDIJ4NoT+KjPFaZudKiPuEMfMHfbqe4xcbbC2hsfs61JNcl2xmx+ohV6lzD9YxxJl1w=="], + "@tiptap/extension-bullet-list": ["@tiptap/extension-bullet-list@3.28.0", "", { "peerDependencies": { "@tiptap/extension-list": "3.28.0" } }, "sha512-dSVuNiH7PFMmWGkNER9vfUb5bXUHDARvHbJ3l+APEb+ZiusVN1KFdM3nd/RsW/Rt5Gd3XwlIEU/c2Uf7cxYDcw=="], - "@tiptap/extension-code": ["@tiptap/extension-code@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-aPc7opCR1ylK4m4c2lsjLsGpEBD1fLQQKWd5PbZiJvrTF8gkdGZlYLt9A6VukpxeJyHhb22Jaj4fxgKmGMeTtw=="], + "@tiptap/extension-code": ["@tiptap/extension-code@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-AUw2Acof3CQE6Q6Y22saK4lyg0nkeJ4XXniU65TdAi/9TE66TGiO4NQJJNNPgu8+VMEwl5j8VsIFK8sfTcNYtg=="], - "@tiptap/extension-code-block": ["@tiptap/extension-code-block@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-a5caWfWN6Z6usy48vzJDDOhWoA6+rFFCHGpQM7jXn/7rRzYPcvBzTZUGptjEbltj4YqtrQ2tVwTJcCtbb+mknA=="], + "@tiptap/extension-code-block": ["@tiptap/extension-code-block@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-bHITDzT0umTLh+SiEVQzIXkCMt/TzbPM1+HQy9ZxgQDHAJj/vdmfNAnP3RCOrz4lETXyhNQ2b6kxeu3lWckxyA=="], - "@tiptap/extension-color": ["@tiptap/extension-color@3.27.4", "", { "peerDependencies": { "@tiptap/extension-text-style": "3.27.4" } }, "sha512-uGbgErKGKO4OTBGqnXOA1CGXa3IqoBaiPBGcHu/px01fS8EVFu0A7q5HS6vxFiMK6qW5x71sEpCA+FUINMAb3g=="], + "@tiptap/extension-color": ["@tiptap/extension-color@3.28.0", "", { "peerDependencies": { "@tiptap/extension-text-style": "3.28.0" } }, "sha512-YbUMUdrgU04GDYoii1wuFVkiTSQoaEQh04kwgQayEQ46aUBEnnaJitWdp39aGMWYTIXD/c9K9cr5Vg8GSKcVxA=="], - "@tiptap/extension-document": ["@tiptap/extension-document@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-7nAqgfkgb9HADBeCTnOHuTiyZuxfxvMPT3nH4OZeY+cmtkI1On3QffqlmtcUPvNbkhT3o9ehA1hVfCnQ1Ye4LQ=="], + "@tiptap/extension-document": ["@tiptap/extension-document@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-5SAKtlB1Tr/eZFhISL86HqmUup6rItvPtuPyRjmZo/VgbMwXEwiyAh1sMgFp5VNaeSMM14vJSyQpjhSaOmaBqg=="], - "@tiptap/extension-dropcursor": ["@tiptap/extension-dropcursor@3.27.4", "", { "peerDependencies": { "@tiptap/extensions": "3.27.4" } }, "sha512-RiZasQJuUTUO3aME16Bn8eJH7cYnvhT5JCFDFq0ya/1iFI9wUQA2NJC5tb5TrZ74+sQwkYU9VzexnchM481Y9w=="], + "@tiptap/extension-dropcursor": ["@tiptap/extension-dropcursor@3.28.0", "", { "peerDependencies": { "@tiptap/extensions": "3.28.0" } }, "sha512-JA+dXQjjfJBpD0nVsZeddGVXRsmanESM9+8CtM35hI9wJnYMXay/B+5GUhswO20zhT3zhB2ZOTGe9knu6A8nIQ=="], - "@tiptap/extension-font-family": ["@tiptap/extension-font-family@3.27.4", "", { "peerDependencies": { "@tiptap/extension-text-style": "3.27.4" } }, "sha512-Xf935Udqbk22fe5xWo3AM8FsVrdtW9afHhGLXvKQvzUpxk36y87VDmj8V0AKwlLpKJDq4b9O7Mg2xPdsuj2k8w=="], + "@tiptap/extension-font-family": ["@tiptap/extension-font-family@3.28.0", "", { "peerDependencies": { "@tiptap/extension-text-style": "3.28.0" } }, "sha512-SkKnS8RG/ECeuupteMOBCXbj9PxcpumE/3h2I+dYvLVRM+KM6YmAQ6Toq8zRHXcDT28iu42OSn2MlDfpuYsmqg=="], - "@tiptap/extension-gapcursor": ["@tiptap/extension-gapcursor@3.27.4", "", { "peerDependencies": { "@tiptap/extensions": "3.27.4" } }, "sha512-svLwSKcFhzpcJeXvxxKkRFuQpykmXrQefVhEsaXq0L95yJIIAGKMRmQC3mxKdzL2j0P9cY7V41bNVSyOAyvclw=="], + "@tiptap/extension-gapcursor": ["@tiptap/extension-gapcursor@3.28.0", "", { "peerDependencies": { "@tiptap/extensions": "3.28.0" } }, "sha512-Wo73kM4q8z4Va9i4+0n1cO0UEMVUVBHPqM6cAqEYXjB4T48LQkKjRsiQydCezm185rQAsmm1dyi72gtvVQfdMg=="], - "@tiptap/extension-hard-break": ["@tiptap/extension-hard-break@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-W+Z9pmDgqjbdu3NeZOQrzA15iM4w60Yd8l2CYzxcdApPVIfYzb2S3a7+u1RqW9wnTYb6xyZjASmFNfxXS4P4cg=="], + "@tiptap/extension-hard-break": ["@tiptap/extension-hard-break@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-JHIFjX1luJgQ4VFEkIeXZpbc54Qiw+69P8FmlazYTh7AIJ6iLCpMFgQFELnivEAZ+/vS0lMPQubg0rCeM3UrHw=="], - "@tiptap/extension-heading": ["@tiptap/extension-heading@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-RgvpxzuYk6QEK+az+eiXpWvGlUso42zNcGnjyUrvskoZjS47MbhSg8ylRYQSRtXE0ETlXhAx4J7iGlGr72kyIw=="], + "@tiptap/extension-heading": ["@tiptap/extension-heading@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-rKjGG/Ik2lNaXBNVmONEDm5DBfGDLM1NWgSf5RRfBISrH8Lm1xqFruOB9tIaB0YUoSV3SBOiwTF9svmzvKSoRA=="], - "@tiptap/extension-horizontal-rule": ["@tiptap/extension-horizontal-rule@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-2eQU/55nE5mhMJHALtLMuBL3dcVJUDVVT7n+uZYMaYE63BtCvC4VS08YLFSR7JZSVJIlgVAmdt5nAw0B+rEPNA=="], + "@tiptap/extension-horizontal-rule": ["@tiptap/extension-horizontal-rule@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-neBCMWprkppQUoLWyeJZDHqBw+xKX2oNhLD9MbFlhKIr092zgfP4mpCvQnSkn1OHl156KzZMp070+NyLBjgQ7A=="], - "@tiptap/extension-italic": ["@tiptap/extension-italic@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-PeZT4XbyxAp7Lqo/hfA1k5LI27g1RlgS+YgXp2CeHXIrUfSpO5HlZXh02Bvb0pOdl3RFw2tEKtlHzjt8Y1+Nwg=="], + "@tiptap/extension-italic": ["@tiptap/extension-italic@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-Yur/ELz6dNVKQC7m8wGjtoLFxamGjJmA0rUEEOacTH6J39aFmcSxYkEGNDkYHbZFyHFYqbej6eI3VE0h08O0mg=="], - "@tiptap/extension-link": ["@tiptap/extension-link@3.27.4", "", { "dependencies": { "linkifyjs": "^4.3.3" }, "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-6K/FkNwMLWWQbNWKlycrUPTN7YcyVFdFwZncoBXe5WyarRjLTGw7ywafnCI9PDIWSq7ttzVL4NgjN2IN8kBXww=="], + "@tiptap/extension-link": ["@tiptap/extension-link@3.28.0", "", { "dependencies": { "linkifyjs": "^4.3.3" }, "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-hy/PqSeTyl317yseFcHGE+3XVfQKQYaL4uZuj27xlrcO7MZ15drt1h9sUZy1FTBF3mr8676pQu7aoEm/Ww4ZRA=="], - "@tiptap/extension-list": ["@tiptap/extension-list@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-A0BgmRO1RE0yLCx9w7GQITtKfS9wLE5cdngSYDiSpwulcXJhJjKm5mZ4OUZmks2VN4HO5jMl2BWCGt2NSDhA+w=="], + "@tiptap/extension-list": ["@tiptap/extension-list@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-zQ66i5DuhVOndmZ0d7H475Y5Yb+BMx+zfCjFkCzEc6WVef5MumtxBVTkGLQ0ibxUaD71s4QQZbjHWagpaTg0eQ=="], - "@tiptap/extension-list-item": ["@tiptap/extension-list-item@3.27.4", "", { "peerDependencies": { "@tiptap/extension-list": "3.27.4" } }, "sha512-z5TVuPw2mkK0B/x+gFg3uUV7tBdaElDFg0zVgnXZCqlSVTLfIyInOOnG5LTWoAd9BdzBjGrzE3PohDcLVDDGBQ=="], + "@tiptap/extension-list-item": ["@tiptap/extension-list-item@3.28.0", "", { "peerDependencies": { "@tiptap/extension-list": "3.28.0" } }, "sha512-GbXrnMac6knSetZY33NHwOrgXFPqH28uCklQqmOZQlsrdGqezDKk31qoEMr4GsKW9n/lViAeuc07oIzwLwCMng=="], - "@tiptap/extension-list-keymap": ["@tiptap/extension-list-keymap@3.27.4", "", { "peerDependencies": { "@tiptap/extension-list": "3.27.4" } }, "sha512-on7JNDi7Eqz7UdZeZdiO83bQHo0flVDHzjmtR+v/nrCGW9H15D3CHs5+4ozLDiCvTK8tbkBuut/l9AWNxcCE/Q=="], + "@tiptap/extension-list-keymap": ["@tiptap/extension-list-keymap@3.28.0", "", { "peerDependencies": { "@tiptap/extension-list": "3.28.0" } }, "sha512-u9Wks8c/eQAv0RkULNggOyTKDD69WVbcV9H5cbasPDUbq5XbEFVa9ajxhEGfMmQ5et3EX0QL8qBi50K0GqbIjA=="], - "@tiptap/extension-ordered-list": ["@tiptap/extension-ordered-list@3.27.4", "", { "peerDependencies": { "@tiptap/extension-list": "3.27.4" } }, "sha512-bHwLiof0FqJfWzB0act7oEKMTZatEKQ4IYCvmyF5EktjMs4kxEatkPp4Yx/1LSYSjLy1MMT7oLELyaz2FFYyXA=="], + "@tiptap/extension-ordered-list": ["@tiptap/extension-ordered-list@3.28.0", "", { "peerDependencies": { "@tiptap/extension-list": "3.28.0" } }, "sha512-OZNYrKKL9D01ySOujlNbKlLS9/3wGgKNYeoHZUg0e+Ta8WPVvL3W1zH6TgiU5sF2ZSGUBoq3w7mdaO/iROlUkw=="], - "@tiptap/extension-paragraph": ["@tiptap/extension-paragraph@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-8Dnr1J5s/s4XYYuEF3b784NnCxLjXOlQpmGyXRxTAzW7JaOP08tIUJWVNvSMekfXc2vXa33HUbqjxyyWZEQ6LQ=="], + "@tiptap/extension-paragraph": ["@tiptap/extension-paragraph@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-8UMlQIjzqf6r2hSJ/VeJ00RqaOrOB1J5rTk02Vcw2pYeHkOqp+B0ff0HFu4abT9x1q4oXrBAgMsxRtgh/kR14Q=="], - "@tiptap/extension-placeholder": ["@tiptap/extension-placeholder@3.27.4", "", { "peerDependencies": { "@tiptap/extensions": "3.27.4" } }, "sha512-7hBoFLeddCv1WzkqB0x3coZ1Hp9WZ9wLoRXIUtUhRKMpzFq2IlTtW1iw88g9pTJnL98bCCElN4DZ4mYtaQvmgA=="], + "@tiptap/extension-placeholder": ["@tiptap/extension-placeholder@3.28.0", "", { "peerDependencies": { "@tiptap/extensions": "3.28.0" } }, "sha512-zueiqNeCHOshDa8dGGSa/0cOBZkMjPrxQhemjF4tj2yZ6EeWHBPtCE5h/uQCagEePxsoaJtvaCRh88199zrgBw=="], - "@tiptap/extension-strike": ["@tiptap/extension-strike@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-8OXwcPKuV3ToBBgyvDxH1jQdObK5FIKCGiyIim6qNWiOpi9BhM3XYD+aO1khjv8qIjtoI/DYbizF4ewj09fX2g=="], + "@tiptap/extension-strike": ["@tiptap/extension-strike@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-VVj2ZZU9QYqiHLcjqMqRYvuHSsokj/AgUl+6TzLrKjlWwyZ18D4H2vkyI0g70iVTKnUpZ3sEy8WA/rqjgBjqBg=="], - "@tiptap/extension-text": ["@tiptap/extension-text@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-lKQH/hP4FBXsziHypd6Ywj8JFvMLM5GVkK1xsH6yApNuXbHq95rd42ZOYWpYILIBib7tlaz93z61d74UrJiuiw=="], + "@tiptap/extension-text": ["@tiptap/extension-text@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-Jqp1LgfY1mnp4TQHoy+vnHyfn6qnnAM6nHgGwbY5zA8b/Xf1Etll6pziTx9p1J1qcfAgSrnjOyAmA++H7VQqww=="], - "@tiptap/extension-text-style": ["@tiptap/extension-text-style@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-Wmj64TQXY85gc7lUNbubW32sDCnVOJlpGraMeARRC9Z0EKBX1JpAxddo/64F17bn3kzLxXVszBFyLRcNgTdU2g=="], + "@tiptap/extension-text-style": ["@tiptap/extension-text-style@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-UreMyqZSv770+CXJK/l1qeHUdaNMQAVkxSOPWpiY9FiT8B4OQyjA7WBOlWrzbvVTzfJvXWk2Y3SWgVRx+/Cd9A=="], - "@tiptap/extension-underline": ["@tiptap/extension-underline@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4" } }, "sha512-nRJGvRyEXDtINlHTW+C2oWcL3vmX1URVxAPpkD3Zwn5Rb/vEeOU/pk/w97I0iid816MR4iVbvl1XhbUVegK9gQ=="], + "@tiptap/extension-underline": ["@tiptap/extension-underline@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0" } }, "sha512-rwxCS6vTh2DJkNIYQX7JSrrRSmm76e2y48aZeuZO5ShkvLWMuJ3/zqDHRxAQVDiJhuE2Cp8NrTmPYlUc9YrT0A=="], - "@tiptap/extensions": ["@tiptap/extensions@3.27.4", "", { "peerDependencies": { "@tiptap/core": "3.27.4", "@tiptap/pm": "3.27.4" } }, "sha512-d8opkg2iGtVwJmNGIqv0blfRxnvWOJp1brz+Z8CsP4ojSS2ZtaE46d6JSQ5OeJ7nMpjhT+9wh4UQcA7OSEO59w=="], + "@tiptap/extensions": ["@tiptap/extensions@3.28.0", "", { "peerDependencies": { "@tiptap/core": "3.28.0", "@tiptap/pm": "3.28.0" } }, "sha512-DJT1khCK+O/pT1gQlAnoKAx6zwDkgv7GtnhSfkqm1/4KHC3x+SSJnBIgBl9oGHymA+DxWbW1EULU4V3d/kT2uQ=="], - "@tiptap/pm": ["@tiptap/pm@3.27.4", "", { "dependencies": { "prosemirror-changeset": "^2.4.1", "prosemirror-commands": "^1.7.1", "prosemirror-dropcursor": "^1.8.2", "prosemirror-gapcursor": "^1.4.1", "prosemirror-history": "^1.5.0", "prosemirror-inputrules": "^1.5.1", "prosemirror-keymap": "^1.2.3", "prosemirror-model": "^1.25.9", "prosemirror-schema-list": "^1.5.1", "prosemirror-state": "^1.4.4", "prosemirror-tables": "^1.8.5", "prosemirror-transform": "^1.12.0", "prosemirror-view": "^1.41.9" } }, "sha512-UB8lcyomfWk7YGI2PZKNqcYXfyRA+PFj+QntlsUXyrsiA5JJIaE8SHKYjxKlGG/xtW3EtPm1b0p38T9Mk4xiFw=="], + "@tiptap/pm": ["@tiptap/pm@3.28.0", "", { "dependencies": { "prosemirror-changeset": "^2.4.1", "prosemirror-commands": "^1.7.1", "prosemirror-dropcursor": "^1.8.2", "prosemirror-gapcursor": "^1.4.1", "prosemirror-history": "^1.5.0", "prosemirror-inputrules": "^1.5.1", "prosemirror-keymap": "^1.2.3", "prosemirror-model": "^1.25.9", "prosemirror-schema-list": "^1.5.1", "prosemirror-state": "^1.4.4", "prosemirror-tables": "^1.8.5", "prosemirror-transform": "^1.12.0", "prosemirror-view": "^1.41.9" } }, "sha512-ALcpwZMUdat9gjJKlpscpoqXStoLhU246LPEVBDvJdIsoUKvUu3MrzfXik2Y8mtSGfhjtm9O2TRkWxQiFVMwsQ=="], - "@tiptap/starter-kit": ["@tiptap/starter-kit@3.27.4", "", { "dependencies": { "@tiptap/core": "^3.27.4", "@tiptap/extension-blockquote": "^3.27.4", "@tiptap/extension-bold": "^3.27.4", "@tiptap/extension-bullet-list": "^3.27.4", "@tiptap/extension-code": "^3.27.4", "@tiptap/extension-code-block": "^3.27.4", "@tiptap/extension-document": "^3.27.4", "@tiptap/extension-dropcursor": "^3.27.4", "@tiptap/extension-gapcursor": "^3.27.4", "@tiptap/extension-hard-break": "^3.27.4", "@tiptap/extension-heading": "^3.27.4", "@tiptap/extension-horizontal-rule": "^3.27.4", "@tiptap/extension-italic": "^3.27.4", "@tiptap/extension-link": "^3.27.4", "@tiptap/extension-list": "^3.27.4", "@tiptap/extension-list-item": "^3.27.4", "@tiptap/extension-list-keymap": "^3.27.4", "@tiptap/extension-ordered-list": "^3.27.4", "@tiptap/extension-paragraph": "^3.27.4", "@tiptap/extension-strike": "^3.27.4", "@tiptap/extension-text": "^3.27.4", "@tiptap/extension-underline": "^3.27.4", "@tiptap/extensions": "^3.27.4", "@tiptap/pm": "^3.27.4" } }, "sha512-/sb6rFxNt5BO4hWpUwvHh+Yh1kNyCQuuz3oDpGef5HUUjSdu9p9rfNiHWIUKBadK8VXuw5es7N+UlZ4hma+gvA=="], + "@tiptap/starter-kit": ["@tiptap/starter-kit@3.28.0", "", { "dependencies": { "@tiptap/core": "^3.28.0", "@tiptap/extension-blockquote": "^3.28.0", "@tiptap/extension-bold": "^3.28.0", "@tiptap/extension-bullet-list": "^3.28.0", "@tiptap/extension-code": "^3.28.0", "@tiptap/extension-code-block": "^3.28.0", "@tiptap/extension-document": "^3.28.0", "@tiptap/extension-dropcursor": "^3.28.0", "@tiptap/extension-gapcursor": "^3.28.0", "@tiptap/extension-hard-break": "^3.28.0", "@tiptap/extension-heading": "^3.28.0", "@tiptap/extension-horizontal-rule": "^3.28.0", "@tiptap/extension-italic": "^3.28.0", "@tiptap/extension-link": "^3.28.0", "@tiptap/extension-list": "^3.28.0", "@tiptap/extension-list-item": "^3.28.0", "@tiptap/extension-list-keymap": "^3.28.0", "@tiptap/extension-ordered-list": "^3.28.0", "@tiptap/extension-paragraph": "^3.28.0", "@tiptap/extension-strike": "^3.28.0", "@tiptap/extension-text": "^3.28.0", "@tiptap/extension-underline": "^3.28.0", "@tiptap/extensions": "^3.28.0", "@tiptap/pm": "^3.28.0" } }, "sha512-pqvFpValV+ONtlu3l4s73ROm/tEjoGMmt6uHmSJaLbqTcMHkdWuR3flJ/5brr4IDHe1foxmNicMbRxlje7yBYw=="], "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], @@ -403,7 +403,7 @@ "dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], - "enhanced-resolve": ["enhanced-resolve@5.21.6", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ=="], + "enhanced-resolve": ["enhanced-resolve@5.24.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ=="], "entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], @@ -433,7 +433,7 @@ "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], - "html2canvas-pro": ["html2canvas-pro@2.2.4", "", { "dependencies": { "css-line-break": "^2.1.0", "text-segmentation": "^1.0.3" } }, "sha512-fo/VOiQZ3oWykAPvnMNHymUHzLWJE7c7C7VWPh+ydb+NquFTwqY5rHQRoxkgsaXo/iciVryPNffTvLzYg98xhg=="], + "html2canvas-pro": ["html2canvas-pro@2.3.0", "", { "dependencies": { "css-line-break": "^2.1.0", "text-segmentation": "^1.0.3" } }, "sha512-MuI3Gdf6E8tzZRsjdFrqM7FZT4+TgMmaUCbFmTwKe2vTk3QeivkXPRAr2Oy41SumExpaksqNGFykfbMGTn+Zdw=="], "idb": ["idb@8.0.3", "", {}, "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg=="], @@ -519,7 +519,7 @@ "orderedmap": ["orderedmap@2.1.1", "", {}, "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g=="], - "oxlint": ["oxlint@1.74.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.74.0", "@oxlint/binding-android-arm64": "1.74.0", "@oxlint/binding-darwin-arm64": "1.74.0", "@oxlint/binding-darwin-x64": "1.74.0", "@oxlint/binding-freebsd-x64": "1.74.0", "@oxlint/binding-linux-arm-gnueabihf": "1.74.0", "@oxlint/binding-linux-arm-musleabihf": "1.74.0", "@oxlint/binding-linux-arm64-gnu": "1.74.0", "@oxlint/binding-linux-arm64-musl": "1.74.0", "@oxlint/binding-linux-ppc64-gnu": "1.74.0", "@oxlint/binding-linux-riscv64-gnu": "1.74.0", "@oxlint/binding-linux-riscv64-musl": "1.74.0", "@oxlint/binding-linux-s390x-gnu": "1.74.0", "@oxlint/binding-linux-x64-gnu": "1.74.0", "@oxlint/binding-linux-x64-musl": "1.74.0", "@oxlint/binding-openharmony-arm64": "1.74.0", "@oxlint/binding-win32-arm64-msvc": "1.74.0", "@oxlint/binding-win32-ia32-msvc": "1.74.0", "@oxlint/binding-win32-x64-msvc": "1.74.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.24.0", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-odGl2s2x5IOJoj3A0v1k0PGBXVFBZeZ2+AK/+K2MJur7Ghi3bkyX5NuLUWHKqa4js1wjep3hJeuTQJOlr+4+dA=="], + "oxlint": ["oxlint@1.75.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.75.0", "@oxlint/binding-android-arm64": "1.75.0", "@oxlint/binding-darwin-arm64": "1.75.0", "@oxlint/binding-darwin-x64": "1.75.0", "@oxlint/binding-freebsd-x64": "1.75.0", "@oxlint/binding-linux-arm-gnueabihf": "1.75.0", "@oxlint/binding-linux-arm-musleabihf": "1.75.0", "@oxlint/binding-linux-arm64-gnu": "1.75.0", "@oxlint/binding-linux-arm64-musl": "1.75.0", "@oxlint/binding-linux-ppc64-gnu": "1.75.0", "@oxlint/binding-linux-riscv64-gnu": "1.75.0", "@oxlint/binding-linux-riscv64-musl": "1.75.0", "@oxlint/binding-linux-s390x-gnu": "1.75.0", "@oxlint/binding-linux-x64-gnu": "1.75.0", "@oxlint/binding-linux-x64-musl": "1.75.0", "@oxlint/binding-openharmony-arm64": "1.75.0", "@oxlint/binding-win32-arm64-msvc": "1.75.0", "@oxlint/binding-win32-ia32-msvc": "1.75.0", "@oxlint/binding-win32-x64-msvc": "1.75.0" }, "peerDependencies": { "oxlint-tsgolint": ">=7.0.2001", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-m9WzjRcRYA/uqIZDa9tclrieoPJ/ln1QYTKdFx6NUOs8uY5DiHlIwRQoCrHT6OM6O3ww3l2skY5gO7G7ZphE7g=="], "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], @@ -539,11 +539,11 @@ "postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="], - "prettier": ["prettier@3.9.5", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg=="], + "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="], "prettier-plugin-svelte": ["prettier-plugin-svelte@4.1.1", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^5.0.0" } }, "sha512-wXvbXMjSvb4C9ENWTHXyd+ihakKCsJ6rJhLP6/8HFNj4GkZr48jqL9PoKsl2sk7SyCZRTnJ7O2TTowUpOxP/KA=="], - "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.8.0", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-svelte"] }, "sha512-V8ITGH87yuBDF6JpEZTOVlUz/saAwqb8f3HRgUj8Lh+tGCcrmorhsLpYqzygwFwK0PE2Ib6Mv3M7T/uE2tZV1g=="], + "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.8.1", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-svelte"] }, "sha512-iaFMYqDsE4ffdDkn5qup0j5f2aCEBFZrdrZnvu9QKTlWx/iGPeQ4HHu7b7fCPMxeo9nwQBiOAh2nSypdFYWJkw=="], "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], @@ -617,13 +617,13 @@ "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], - "svelte": ["svelte@5.56.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.10", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.12", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-P03YJmUy2JoOxYHb4Ka3oFat1hq2ko2it1MOItSjsJ4B6WgZPLc3+RyyU+57OGWhs3Ieq74EJpZtSnNXdAGgDw=="], + "svelte": ["svelte@5.56.7", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.10", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.12", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-5qERUZX80oQj6XrDMUmD2Uhd/cIpCPDWWKBK3ZHmyRUC9apPyamWM8xMo31mbWsIQxwG2hVoSnOJ/EcnhVkkzQ=="], "svelte-awesome-color-picker": ["svelte-awesome-color-picker@4.1.3", "", { "dependencies": { "colord": "^2.9.3", "svelte-awesome-slider": "2.0.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-fYio6XR2vp9WO0ihT6Vlw1Kj278gEZtqfIRde4YBx5OgGjBdQJxFE8jl6OibPQPrmaz625HZPZaSbRflL88/Mg=="], "svelte-awesome-slider": ["svelte-awesome-slider@2.0.0", "", { "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-YBkOdYm1Feaqsn2JkJBRs+Kc/X3Qy/3GuVmI7GmoYDjBaHkjx9uH4khTuED22z57Hg3gGWeDhp/clIjWDdLNaw=="], - "svelte-check": ["svelte-check@4.7.2", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "@sveltejs/load-config": "^0.2.0", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-GoS4XJdGswlq0rIT1vtFLzJY1bvHtY37McY9H9Gkm1Ggw/ICdZYn8J/Z8Yi0BEL0i3R4+jtaWVePjyppMlij/A=="], + "svelte-check": ["svelte-check@4.7.3", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "@sveltejs/load-config": "^0.2.0", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-DHdTCGX62R0fCxBEaT+USdASAnoaRBaaNczkRJl0K7o3WyoCeVUbVxo6fKqpOll/B+WMWCsiFK0eFrJSNBKZIg=="], "svelte-toolbelt": ["svelte-toolbelt@0.10.6", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.35.1", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.30.2" } }, "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ=="], @@ -631,7 +631,7 @@ "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], - "tailwindcss": ["tailwindcss@4.3.2", "", {}, "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA=="], + "tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="], "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], @@ -679,7 +679,7 @@ "utrie": ["utrie@1.0.2", "", { "dependencies": { "base64-arraybuffer": "^1.0.2" } }, "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw=="], - "vite": ["vite@8.1.4", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.16", "rolldown": "~1.1.4", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ=="], + "vite": ["vite@8.1.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.17", "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw=="], "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], @@ -717,7 +717,7 @@ "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -759,12 +759,14 @@ "vitest/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + "vitest/vite": ["vite@8.1.4", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.16", "rolldown": "~1.1.4", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ=="], "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], "prosemirror-dropcursor/prosemirror-view/prosemirror-model": ["prosemirror-model@1.25.4", "", { "dependencies": { "orderedmap": "^2.0.0" } }, "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA=="], "prosemirror-history/prosemirror-view/prosemirror-model": ["prosemirror-model@1.25.4", "", { "dependencies": { "orderedmap": "^2.0.0" } }, "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA=="], + + "vitest/vite/picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], } } diff --git a/package-lock.json b/package-lock.json index 9b97dc4..e30e442 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,42 +8,43 @@ "name": "tools", "version": "0.0.1", "dependencies": { - "@tiptap/core": "^3.27.4", - "@tiptap/extension-placeholder": "^3.27.4", - "@tiptap/pm": "^3.27.4", - "@tiptap/starter-kit": "^3.27.4", + "@tiptap/core": "^3.28.0", + "@tiptap/extension-placeholder": "^3.28.0", + "@tiptap/pm": "^3.28.0", + "@tiptap/starter-kit": "^3.28.0", "bits-ui": "^2.18.1", - "html2canvas-pro": "^2.2.4", + "html2canvas-pro": "^2.3.0", "idb": "^8.0.3", "svelte-awesome-color-picker": "^4.1.3", "tippy.js": "^6.3.7", "typescript-color-gradient": "^4.2.0" }, "devDependencies": { - "@iconify-json/tabler": "^1.2.35", + "@iconify-json/tabler": "^1.2.37", "@playwright/test": "^1.61.1", "@sveltejs/adapter-auto": "^7.0.1", - "@sveltejs/kit": "^2.69.3", + "@sveltejs/kit": "^2.70.1", "@sveltejs/vite-plugin-svelte": "^7.2.0", - "@tailwindcss/vite": "^4.3.2", - "@testing-library/jest-dom": "^6.9.1", + "@tailwindcss/vite": "^4.3.3", + "@testing-library/jest-dom": "^6.10.0", "@testing-library/svelte": "^5.4.2", - "@tiptap/extension-color": "^3.27.4", - "@tiptap/extension-font-family": "^3.27.4", - "@tiptap/extension-text-style": "^3.27.4", + "@tiptap/extension-color": "^3.28.0", + "@tiptap/extension-font-family": "^3.28.0", + "@tiptap/extension-text-style": "^3.28.0", "@types/node": "^26.1.1", + "@vitest/coverage-v8": "4.1.10", "file-type": "^22.0.1", "jsdom": "^29.1.1", - "oxlint": "^1.74.0", - "prettier": "^3.9.5", + "oxlint": "^1.75.0", + "prettier": "^3.9.6", "prettier-plugin-svelte": "^4.1.1", - "prettier-plugin-tailwindcss": "^0.8.0", - "svelte": "^5.56.5", - "svelte-check": "^4.7.2", - "tailwindcss": "^4.3.2", + "prettier-plugin-tailwindcss": "^0.8.1", + "svelte": "^5.56.7", + "svelte-check": "^4.7.3", + "tailwindcss": "^4.3.3", "typescript": "^6.0.3", "unplugin-icons": "^23.0.1", - "vite": "^8.1.4", + "vite": "^8.1.5", "vitest": "^4.1.10" } }, @@ -134,6 +135,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", @@ -144,6 +155,22 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/runtime": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", @@ -154,6 +181,30 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@borewit/text-codec": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", @@ -393,9 +444,9 @@ "license": "MIT" }, "node_modules/@iconify-json/tabler": { - "version": "1.2.35", - "resolved": "https://registry.npmjs.org/@iconify-json/tabler/-/tabler-1.2.35.tgz", - "integrity": "sha512-/sJMqHvh5ZWrEERVfDCT5NjVDeKJdhosFtKjJofAVl+P/3AzLiryOQw7WvrfDF25Xa5N/eoOQ15Y1jnhYXxBoQ==", + "version": "1.2.37", + "resolved": "https://registry.npmjs.org/@iconify-json/tabler/-/tabler-1.2.37.tgz", + "integrity": "sha512-tXc0jGhrxec6eTKxMI9We/r3cEItyU5dG8ngDOEKsL36a6+/xwk4sR7PIZROVajzxmvyUBsn659adDIfcswiUw==", "dev": true, "license": "MIT", "dependencies": { @@ -505,9 +556,9 @@ } }, "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.74.0.tgz", - "integrity": "sha512-+gHd12muVI9ZLBaWLPkHt3Fj7jihFjgQ1MGtBaRL8vWrWrI0P7dLUty/cHrHS0oqPYIRgQUJsPu2CExQuMcwNw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.75.0.tgz", + "integrity": "sha512-lutovtFzJqlRaqpZrCqSSGaHZzl9nIxxpjLzhSRLunN6dCLylj0uzlCyQGaQDIys7rrv8kVXiFO+R4Zpn0bX7g==", "cpu": [ "arm" ], @@ -522,9 +573,9 @@ } }, "node_modules/@oxlint/binding-android-arm64": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.74.0.tgz", - "integrity": "sha512-xjKdoMB+H+RCOByv/7l7nfIGW9mlOisqYdcyC75UqYuQecLpReAeEYUf2CNeDEI3KtmUgxpRw/+c63y4AeF/Bw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.75.0.tgz", + "integrity": "sha512-hXI0hDgHkw4w5nfru72aG7y+2iQJmC4waH/KV6H/hbgA6yAP5jYNx0P9yug15Hs0tWl/+mda3Jjn/2gmDT48tw==", "cpu": [ "arm64" ], @@ -539,9 +590,9 @@ } }, "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.74.0.tgz", - "integrity": "sha512-iUK7wvc6sejMKsC+Pt67mntoF5weFcyEunhZfLJceU6gL419mexz5wBkSx/EnkFBExMLNtOi9fnDSc5xfK0IzQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.75.0.tgz", + "integrity": "sha512-D91BWbK/dMYfCcrghspPIuKs2D9LF4Z/OabVSQjw1AO6PWxArD7teDA48bm0ySFqWDaPVqmQRl5GMWNglTXyrQ==", "cpu": [ "arm64" ], @@ -556,9 +607,9 @@ } }, "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.74.0.tgz", - "integrity": "sha512-ggKc/tn5SJ1u2yG2izC6VKODfYKV8MQ2AicJlNzOjuyrC29udvOef6/JzK2r32xqCnBDLFouR1VCkjzEI0/N9Q==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.75.0.tgz", + "integrity": "sha512-02mpwzf12BonZ6PT0TuQoomvEh2kVl2WGBIKWezCyToIS+rYkQZ6GXnARBAl9A4Ovm2V+Xe7M4KretyqmmcnJQ==", "cpu": [ "x64" ], @@ -573,9 +624,9 @@ } }, "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.74.0.tgz", - "integrity": "sha512-u++dH/43jy9hTLbneaWlS0gla/Bp1JdwJ2zgevCl8nDFUh6qRCGMxcL0f0lb7By3A9p/LfFr+7cG4HU1hG856g==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.75.0.tgz", + "integrity": "sha512-qZJgLnDaBsiL5YESx2t/TZ8eXkL9fEkKoXEdzegROhlz9A0lgyGnZ0dAzJrh7LJAHQl2K9RdRueN2s/9N7+odg==", "cpu": [ "x64" ], @@ -590,9 +641,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.74.0.tgz", - "integrity": "sha512-Sj1zmtFDVTPeIbIz4ZfcXAbFHqCmKCXdCUlAJzvTF7I20NTH1RDpoF2PhkqNODutJzVhJYmm3oz0GwgY+tvE2g==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.75.0.tgz", + "integrity": "sha512-7XlaWA5BJD3XpCfrEqjEe6Zseeb14S7QGa304XfwKignRaKQ+eIj775BQ7nIslggWickl4IsPUFqJ+/gAyNHVg==", "cpu": [ "arm" ], @@ -607,9 +658,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.74.0.tgz", - "integrity": "sha512-//PKyQb/tQXcHArx2f7z+oVI/eMS2Jpv+edNuAtOrgIhWdGcpHxogveAxzmF2rpH1AIHp4Hq04RF/rgJdiICnQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.75.0.tgz", + "integrity": "sha512-av6Tpv8yrcMMMOadOqENBhlsLRcGFXXwoQ0hzHhsmS9FJ4Wioy8we427GbcMe2XTxmL2e60T67H1Dyr3up+tAA==", "cpu": [ "arm" ], @@ -624,9 +675,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.74.0.tgz", - "integrity": "sha512-/k1Me+aX2tjuH10K62mLS0y8cLkJBHX6Ce0xPK+eWeel4bSdEGZ8dv4+hYMzg0GrSmjwy4yAYsDPeEeKBft/2w==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.75.0.tgz", + "integrity": "sha512-WcUhd8fHT5plrA14lANevl+hOl815mVI5t2hU21oFWrZKFXIVV/Sr4rWQV0NzSvzBupbMLNc5ErEA6Ehxh5jMg==", "cpu": [ "arm64" ], @@ -644,9 +695,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.74.0.tgz", - "integrity": "sha512-3tFSjBxc5D8/zvjEuLvOqcA8ZXKD0+6NuaVO/edeamNc49MoAsbfaC9s1UiwODwgF6slGaF8yJA2TPkukd77tg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.75.0.tgz", + "integrity": "sha512-UWzp5wRHFe/ESO3+eEaxXsTkYTGLYjnTsi/I5neEacXSItQ6WNleapfOAeA4x2b8nyhJ4uQxqvtv9pHv8kWJtQ==", "cpu": [ "arm64" ], @@ -664,9 +715,9 @@ } }, "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.74.0.tgz", - "integrity": "sha512-9QggtPkSPXOCTu8Szis7auOK/sC7KdQaN+/TujP7YVVhzCAOhgdRfgv8uEz0r2tk5xdgus5rLYUrCDoZNtiRUw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.75.0.tgz", + "integrity": "sha512-XEVRwGMLKCUKrvhLAz4F6AIh8MJrQVdSZtAmPpRZt9tGPsUnamPOcl3dS/ZQzJnar/Ymgc//+xho0L60Emzuxg==", "cpu": [ "ppc64" ], @@ -684,9 +735,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.74.0.tgz", - "integrity": "sha512-VM5VPUJ4DJIWiK+AZn8FScUqMr6OFrCAYybMYjEEi7W13ParI64MByiXTkKMqZpBmvQ9zxl9Ebq2VUOiZRJYUg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.75.0.tgz", + "integrity": "sha512-mAG4DUXqfLC8cTjMD2kt3jDmVzFREYtDyeLNdLdsCcBc4Zbl2EMuiFektGBilQwkNjYnMvCqJs55U+Hyb+b+jw==", "cpu": [ "riscv64" ], @@ -704,9 +755,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.74.0.tgz", - "integrity": "sha512-SaDY1gh9rOA592J54g+gu5hkOFFQBZsMmIYHs+NRHG+Uq0OxtuuCXMWQ3vu1830Eugv5uMXyjG+bv2Z9y4IXjw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.75.0.tgz", + "integrity": "sha512-95hrAvriAlI+pekSomTFIn0+bawMDlDwTNVmdjsFusTHyL2JWh7TWvRNG/Lkim72uN8OiCcO9wcaC6omLP5E3w==", "cpu": [ "riscv64" ], @@ -724,9 +775,9 @@ } }, "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.74.0.tgz", - "integrity": "sha512-ZATQeHZCyr6MbDveg0obD5sxLHFOghtOdC5jwVwYlvFWqtFOxctgFEG6Ef/64hYvZrWyhyCckB10AelqLopeDA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.75.0.tgz", + "integrity": "sha512-4b6f2+FrtruAESrCqIKcrarzfrSx+wk2QNcp+RT91/Prc+pMQMAfyZ1rG1c3tFQNl8Bc616tx40uNXyxNBRPbQ==", "cpu": [ "s390x" ], @@ -744,9 +795,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.74.0.tgz", - "integrity": "sha512-+aIvJyrdeD7LwCQ2WYLMUWNmnbeDRSPb40aBYtPjD9+PTqUwgJnk+HK5yLfSMeqXrMrDhE9uTmtt2y50tvjhHw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.75.0.tgz", + "integrity": "sha512-nshAhrUvXFUWOvqQ2soIw7HFNWvpvEV4o0cYSqPtzLiPF5gKyYTDOOTJ6Rn8g8K/iGvPIrbDA4v8+5MvnjJrrg==", "cpu": [ "x64" ], @@ -764,9 +815,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.74.0.tgz", - "integrity": "sha512-XyktaR8lhK2qWiCK0Tk8oYD+/cgn+oHA6ddRnxSSXUKkkojkV78CmShZUxQF+yrBFs0SuW+JBOPG6hecyc/iZg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.75.0.tgz", + "integrity": "sha512-e4jNxLKnxLC6sYBQRxrI2pgIIxnmMtF8U/VwNYcjTT/CLS+spH624cYVnj07bTKwaEWT37/e025isOs6j/0xqA==", "cpu": [ "x64" ], @@ -784,9 +835,9 @@ } }, "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.74.0.tgz", - "integrity": "sha512-mzbjrPl4neaVUiJ1fUiEUxTGaSZBoiKtaoB6jmIpz9S+VOA2vDYmJpihQ82w6178V5jxziclTg8Cgj5yF6tTDg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.75.0.tgz", + "integrity": "sha512-hZ2lH+1qLf/DiEP9UWuQTK2JWj/BgvMB4jhIV4SmNU1wfEiYYX4TynQyAZXx0j9X4qRYizAL042SKaV+8ynh4w==", "cpu": [ "arm64" ], @@ -801,9 +852,9 @@ } }, "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.74.0.tgz", - "integrity": "sha512-vUAe9okpS2Oa5+lX67lqHMuNUvfkleRKwrUDJ/WJBsgmddvZ1mrsh2HVmuFDRzqFELhaJhFaCNOuR6a7L3rtIA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.75.0.tgz", + "integrity": "sha512-Ilj6PNzGDS3bCU0MSJH7Msh0NhH+T/mRp2shwg+q+GHeVlPwP5LEboW96aW+3kVKFk6zYZy1Xi5pZkqZh6X8KQ==", "cpu": [ "arm64" ], @@ -818,9 +869,9 @@ } }, "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.74.0.tgz", - "integrity": "sha512-yyXXJyYYSXL4I8K8jAWjJs+J3fa9gH2JmEbo4f5adm+1tNC9itseicBNuwK7BDHvqQ5J534s+yDULu89vYL2ZQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.75.0.tgz", + "integrity": "sha512-QVit2nOEOiPhkmsrksPSkoGCdnZRNkspt8fwoYyP09te1VEbnSj4LAxua4rc8FKTmWkySVe05j8iz9GXYfF1AQ==", "cpu": [ "ia32" ], @@ -835,9 +886,9 @@ } }, "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.74.0.tgz", - "integrity": "sha512-VTC9IYTIMrVUk/i6Ms1ohzzDKZFkWn0KU2OBbPBzgmVZ2V30165T/zK4LztTr0Xgp9fZ1qQZ1rsZAu/rEmySlA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.75.0.tgz", + "integrity": "sha512-DSxnNkBUAYARPwJtR12Ig3deWr8w0H997xP6jy33i+e0SyYJw8FKuz4+cZtpmPEhQmvlPJE3X/2vNxDmLkd/rA==", "cpu": [ "x64" ], @@ -1178,9 +1229,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.69.3", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.69.3.tgz", - "integrity": "sha512-cphwqMRcE19/9VkrIPr5qZhQ0SptSSDfDzRUpYHu9OJDFGuYBFyJzK+KQA27wB4YG32O/yF2QjBkDmTyo0vtCw==", + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.70.1.tgz", + "integrity": "sha512-nY9SPHGOZro3doud9vZXDBwl9tCZIouuJztjgSHs6PAIrv9M/z5O7eOhPV5xU7CgVHA976Jwu3BA1hIFvXztkA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1260,49 +1311,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz", - "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "5.21.6", + "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.3.2" + "tailwindcss": "4.3.3" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz", - "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", "dev": true, "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.2", - "@tailwindcss/oxide-darwin-arm64": "4.3.2", - "@tailwindcss/oxide-darwin-x64": "4.3.2", - "@tailwindcss/oxide-freebsd-x64": "4.3.2", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.2", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.2", - "@tailwindcss/oxide-linux-x64-musl": "4.3.2", - "@tailwindcss/oxide-wasm32-wasi": "4.3.2", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.2" + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz", - "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", "cpu": [ "arm64" ], @@ -1317,9 +1368,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz", - "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", "cpu": [ "arm64" ], @@ -1334,9 +1385,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz", - "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", "cpu": [ "x64" ], @@ -1351,9 +1402,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz", - "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", "cpu": [ "x64" ], @@ -1368,9 +1419,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz", - "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", "cpu": [ "arm" ], @@ -1385,9 +1436,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz", - "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", "cpu": [ "arm64" ], @@ -1405,9 +1456,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz", - "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", "cpu": [ "arm64" ], @@ -1425,9 +1476,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz", - "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", "cpu": [ "x64" ], @@ -1445,9 +1496,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz", - "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", "cpu": [ "x64" ], @@ -1465,9 +1516,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz", - "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -1494,10 +1545,76 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", - "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", "cpu": [ "arm64" ], @@ -1512,9 +1629,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz", - "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", "cpu": [ "x64" ], @@ -1529,15 +1646,15 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.2.tgz", - "integrity": "sha512-eHpMeX4JXfVNJDEcsouTeCBubJBTcTLigeaw/NTUW6PB5ATKKXdyonnXgTBX2VuRbjz1hjfz6C5XAhr52ImQXA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", "dev": true, "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.3.2", - "@tailwindcss/oxide": "4.3.2", - "tailwindcss": "4.3.2" + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" @@ -1581,9 +1698,10 @@ "license": "MIT" }, "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.10.0.tgz", + "integrity": "sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ==", + "deprecated": "Incorrect minor release with breaking changes (Node >=22 and required @testing-library/dom peer). Use 6.9.1 for the 6.x line, or upgrade to 7.0.0.", "dev": true, "license": "MIT", "dependencies": { @@ -1595,9 +1713,12 @@ "redent": "^3.0.0" }, "engines": { - "node": ">=14", + "node": ">=22", "npm": ">=6", "yarn": ">=1" + }, + "peerDependencies": { + "@testing-library/dom": ">=10 <11" } }, "node_modules/@testing-library/svelte": { @@ -1641,89 +1762,89 @@ } }, "node_modules/@tiptap/core": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.27.4.tgz", - "integrity": "sha512-8W/GwlEn0JwNdpyVfTWcXwHYUpj9BWwO++YxtizmgjJzlwigSh7/xLVJMwVykuQHQ2fCq5rkUvmBRtpHOMLUQA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.28.0.tgz", + "integrity": "sha512-gUuD5WAYfbDxNSSJya/emh2KSzXZXLUYKW4fEnc1AQ5FE2twzh4LJ9UlKFIawigrUCAksWI5Fy1hRbv+5m4ZdQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "3.27.4" + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-blockquote": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.27.4.tgz", - "integrity": "sha512-d1tOHgP3R5cOE+Ot8qL/dkLXRByajgn+j6cCXHqDtmJO2wsK9knmbKQ0SEjbKrU6OgHrTnY/EotNxBEBW9HGoA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.28.0.tgz", + "integrity": "sha512-y8Xi6Z3AQLXedz0J8Z3kDsu7SKBmL50gKVXx3RK1Oo1cuCGhNChm3syChkAz3PLAbrPUM5rvJDSZdF2jUrDnng==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-bold": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.27.4.tgz", - "integrity": "sha512-wTtJUUAxCAZ01ICH2DNlOBzzHKRQ1ZST8aRYtIhBPzqEUhnJaKGcjnDB4X49fqPi48iXaPxzhsInDl+rVUujWg==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.28.0.tgz", + "integrity": "sha512-JhZQmr0AU741bOwjVMfuwJdK4g0TQwwPbeca9aqKHv5zvZw4i4G9G6fESVyMFc3Yag1ffpnq5EtNldHKTnMhlw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.27.4.tgz", - "integrity": "sha512-rvja0N1RnwGJAVwDdbUfDIJ4NoT+KjPFaZudKiPuEMfMHfbqe4xcbbC2hsfs61JNcl2xmx+ohV6lzD9YxxJl1w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.28.0.tgz", + "integrity": "sha512-dSVuNiH7PFMmWGkNER9vfUb5bXUHDARvHbJ3l+APEb+ZiusVN1KFdM3nd/RsW/Rt5Gd3XwlIEU/c2Uf7cxYDcw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "3.27.4" + "@tiptap/extension-list": "3.28.0" } }, "node_modules/@tiptap/extension-code": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.27.4.tgz", - "integrity": "sha512-aPc7opCR1ylK4m4c2lsjLsGpEBD1fLQQKWd5PbZiJvrTF8gkdGZlYLt9A6VukpxeJyHhb22Jaj4fxgKmGMeTtw==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.28.0.tgz", + "integrity": "sha512-AUw2Acof3CQE6Q6Y22saK4lyg0nkeJ4XXniU65TdAi/9TE66TGiO4NQJJNNPgu8+VMEwl5j8VsIFK8sfTcNYtg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-code-block": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.27.4.tgz", - "integrity": "sha512-a5caWfWN6Z6usy48vzJDDOhWoA6+rFFCHGpQM7jXn/7rRzYPcvBzTZUGptjEbltj4YqtrQ2tVwTJcCtbb+mknA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.28.0.tgz", + "integrity": "sha512-bHITDzT0umTLh+SiEVQzIXkCMt/TzbPM1+HQy9ZxgQDHAJj/vdmfNAnP3RCOrz4lETXyhNQ2b6kxeu3lWckxyA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-color": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-3.27.4.tgz", - "integrity": "sha512-uGbgErKGKO4OTBGqnXOA1CGXa3IqoBaiPBGcHu/px01fS8EVFu0A7q5HS6vxFiMK6qW5x71sEpCA+FUINMAb3g==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-3.28.0.tgz", + "integrity": "sha512-YbUMUdrgU04GDYoii1wuFVkiTSQoaEQh04kwgQayEQ46aUBEnnaJitWdp39aGMWYTIXD/c9K9cr5Vg8GSKcVxA==", "dev": true, "license": "MIT", "funding": { @@ -1731,39 +1852,39 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-text-style": "3.27.4" + "@tiptap/extension-text-style": "3.28.0" } }, "node_modules/@tiptap/extension-document": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.27.4.tgz", - "integrity": "sha512-7nAqgfkgb9HADBeCTnOHuTiyZuxfxvMPT3nH4OZeY+cmtkI1On3QffqlmtcUPvNbkhT3o9ehA1hVfCnQ1Ye4LQ==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.28.0.tgz", + "integrity": "sha512-5SAKtlB1Tr/eZFhISL86HqmUup6rItvPtuPyRjmZo/VgbMwXEwiyAh1sMgFp5VNaeSMM14vJSyQpjhSaOmaBqg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.27.4.tgz", - "integrity": "sha512-RiZasQJuUTUO3aME16Bn8eJH7cYnvhT5JCFDFq0ya/1iFI9wUQA2NJC5tb5TrZ74+sQwkYU9VzexnchM481Y9w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.28.0.tgz", + "integrity": "sha512-JA+dXQjjfJBpD0nVsZeddGVXRsmanESM9+8CtM35hI9wJnYMXay/B+5GUhswO20zhT3zhB2ZOTGe9knu6A8nIQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "3.27.4" + "@tiptap/extensions": "3.28.0" } }, "node_modules/@tiptap/extension-font-family": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-font-family/-/extension-font-family-3.27.4.tgz", - "integrity": "sha512-Xf935Udqbk22fe5xWo3AM8FsVrdtW9afHhGLXvKQvzUpxk36y87VDmj8V0AKwlLpKJDq4b9O7Mg2xPdsuj2k8w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-font-family/-/extension-font-family-3.28.0.tgz", + "integrity": "sha512-SkKnS8RG/ECeuupteMOBCXbj9PxcpumE/3h2I+dYvLVRM+KM6YmAQ6Toq8zRHXcDT28iu42OSn2MlDfpuYsmqg==", "dev": true, "license": "MIT", "funding": { @@ -1771,79 +1892,79 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-text-style": "3.27.4" + "@tiptap/extension-text-style": "3.28.0" } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.27.4.tgz", - "integrity": "sha512-svLwSKcFhzpcJeXvxxKkRFuQpykmXrQefVhEsaXq0L95yJIIAGKMRmQC3mxKdzL2j0P9cY7V41bNVSyOAyvclw==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.28.0.tgz", + "integrity": "sha512-Wo73kM4q8z4Va9i4+0n1cO0UEMVUVBHPqM6cAqEYXjB4T48LQkKjRsiQydCezm185rQAsmm1dyi72gtvVQfdMg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "3.27.4" + "@tiptap/extensions": "3.28.0" } }, "node_modules/@tiptap/extension-hard-break": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.27.4.tgz", - "integrity": "sha512-W+Z9pmDgqjbdu3NeZOQrzA15iM4w60Yd8l2CYzxcdApPVIfYzb2S3a7+u1RqW9wnTYb6xyZjASmFNfxXS4P4cg==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.28.0.tgz", + "integrity": "sha512-JHIFjX1luJgQ4VFEkIeXZpbc54Qiw+69P8FmlazYTh7AIJ6iLCpMFgQFELnivEAZ+/vS0lMPQubg0rCeM3UrHw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-heading": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.27.4.tgz", - "integrity": "sha512-RgvpxzuYk6QEK+az+eiXpWvGlUso42zNcGnjyUrvskoZjS47MbhSg8ylRYQSRtXE0ETlXhAx4J7iGlGr72kyIw==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.28.0.tgz", + "integrity": "sha512-rKjGG/Ik2lNaXBNVmONEDm5DBfGDLM1NWgSf5RRfBISrH8Lm1xqFruOB9tIaB0YUoSV3SBOiwTF9svmzvKSoRA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.27.4.tgz", - "integrity": "sha512-2eQU/55nE5mhMJHALtLMuBL3dcVJUDVVT7n+uZYMaYE63BtCvC4VS08YLFSR7JZSVJIlgVAmdt5nAw0B+rEPNA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.28.0.tgz", + "integrity": "sha512-neBCMWprkppQUoLWyeJZDHqBw+xKX2oNhLD9MbFlhKIr092zgfP4mpCvQnSkn1OHl156KzZMp070+NyLBjgQ7A==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-italic": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.27.4.tgz", - "integrity": "sha512-PeZT4XbyxAp7Lqo/hfA1k5LI27g1RlgS+YgXp2CeHXIrUfSpO5HlZXh02Bvb0pOdl3RFw2tEKtlHzjt8Y1+Nwg==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.28.0.tgz", + "integrity": "sha512-Yur/ELz6dNVKQC7m8wGjtoLFxamGjJmA0rUEEOacTH6J39aFmcSxYkEGNDkYHbZFyHFYqbej6eI3VE0h08O0mg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-link": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.27.4.tgz", - "integrity": "sha512-6K/FkNwMLWWQbNWKlycrUPTN7YcyVFdFwZncoBXe5WyarRjLTGw7ywafnCI9PDIWSq7ttzVL4NgjN2IN8kBXww==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.28.0.tgz", + "integrity": "sha512-hy/PqSeTyl317yseFcHGE+3XVfQKQYaL4uZuj27xlrcO7MZ15drt1h9sUZy1FTBF3mr8676pQu7aoEm/Ww4ZRA==", "license": "MIT", "dependencies": { "linkifyjs": "^4.3.3" @@ -1853,119 +1974,119 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-list": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.27.4.tgz", - "integrity": "sha512-A0BgmRO1RE0yLCx9w7GQITtKfS9wLE5cdngSYDiSpwulcXJhJjKm5mZ4OUZmks2VN4HO5jMl2BWCGt2NSDhA+w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.28.0.tgz", + "integrity": "sha512-zQ66i5DuhVOndmZ0d7H475Y5Yb+BMx+zfCjFkCzEc6WVef5MumtxBVTkGLQ0ibxUaD71s4QQZbjHWagpaTg0eQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/extension-list-item": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.27.4.tgz", - "integrity": "sha512-z5TVuPw2mkK0B/x+gFg3uUV7tBdaElDFg0zVgnXZCqlSVTLfIyInOOnG5LTWoAd9BdzBjGrzE3PohDcLVDDGBQ==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.28.0.tgz", + "integrity": "sha512-GbXrnMac6knSetZY33NHwOrgXFPqH28uCklQqmOZQlsrdGqezDKk31qoEMr4GsKW9n/lViAeuc07oIzwLwCMng==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "3.27.4" + "@tiptap/extension-list": "3.28.0" } }, "node_modules/@tiptap/extension-list-keymap": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.27.4.tgz", - "integrity": "sha512-on7JNDi7Eqz7UdZeZdiO83bQHo0flVDHzjmtR+v/nrCGW9H15D3CHs5+4ozLDiCvTK8tbkBuut/l9AWNxcCE/Q==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.28.0.tgz", + "integrity": "sha512-u9Wks8c/eQAv0RkULNggOyTKDD69WVbcV9H5cbasPDUbq5XbEFVa9ajxhEGfMmQ5et3EX0QL8qBi50K0GqbIjA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "3.27.4" + "@tiptap/extension-list": "3.28.0" } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.27.4.tgz", - "integrity": "sha512-bHwLiof0FqJfWzB0act7oEKMTZatEKQ4IYCvmyF5EktjMs4kxEatkPp4Yx/1LSYSjLy1MMT7oLELyaz2FFYyXA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.28.0.tgz", + "integrity": "sha512-OZNYrKKL9D01ySOujlNbKlLS9/3wGgKNYeoHZUg0e+Ta8WPVvL3W1zH6TgiU5sF2ZSGUBoq3w7mdaO/iROlUkw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extension-list": "3.27.4" + "@tiptap/extension-list": "3.28.0" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.27.4.tgz", - "integrity": "sha512-8Dnr1J5s/s4XYYuEF3b784NnCxLjXOlQpmGyXRxTAzW7JaOP08tIUJWVNvSMekfXc2vXa33HUbqjxyyWZEQ6LQ==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.28.0.tgz", + "integrity": "sha512-8UMlQIjzqf6r2hSJ/VeJ00RqaOrOB1J5rTk02Vcw2pYeHkOqp+B0ff0HFu4abT9x1q4oXrBAgMsxRtgh/kR14Q==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-placeholder": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.27.4.tgz", - "integrity": "sha512-7hBoFLeddCv1WzkqB0x3coZ1Hp9WZ9wLoRXIUtUhRKMpzFq2IlTtW1iw88g9pTJnL98bCCElN4DZ4mYtaQvmgA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.28.0.tgz", + "integrity": "sha512-zueiqNeCHOshDa8dGGSa/0cOBZkMjPrxQhemjF4tj2yZ6EeWHBPtCE5h/uQCagEePxsoaJtvaCRh88199zrgBw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "3.27.4" + "@tiptap/extensions": "3.28.0" } }, "node_modules/@tiptap/extension-strike": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.27.4.tgz", - "integrity": "sha512-8OXwcPKuV3ToBBgyvDxH1jQdObK5FIKCGiyIim6qNWiOpi9BhM3XYD+aO1khjv8qIjtoI/DYbizF4ewj09fX2g==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.28.0.tgz", + "integrity": "sha512-VVj2ZZU9QYqiHLcjqMqRYvuHSsokj/AgUl+6TzLrKjlWwyZ18D4H2vkyI0g70iVTKnUpZ3sEy8WA/rqjgBjqBg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-text": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.27.4.tgz", - "integrity": "sha512-lKQH/hP4FBXsziHypd6Ywj8JFvMLM5GVkK1xsH6yApNuXbHq95rd42ZOYWpYILIBib7tlaz93z61d74UrJiuiw==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.28.0.tgz", + "integrity": "sha512-Jqp1LgfY1mnp4TQHoy+vnHyfn6qnnAM6nHgGwbY5zA8b/Xf1Etll6pziTx9p1J1qcfAgSrnjOyAmA++H7VQqww==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-text-style": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.27.4.tgz", - "integrity": "sha512-Wmj64TQXY85gc7lUNbubW32sDCnVOJlpGraMeARRC9Z0EKBX1JpAxddo/64F17bn3kzLxXVszBFyLRcNgTdU2g==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.28.0.tgz", + "integrity": "sha512-UreMyqZSv770+CXJK/l1qeHUdaNMQAVkxSOPWpiY9FiT8B4OQyjA7WBOlWrzbvVTzfJvXWk2Y3SWgVRx+/Cd9A==", "dev": true, "license": "MIT", "funding": { @@ -1973,40 +2094,40 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extension-underline": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.27.4.tgz", - "integrity": "sha512-nRJGvRyEXDtINlHTW+C2oWcL3vmX1URVxAPpkD3Zwn5Rb/vEeOU/pk/w97I0iid816MR4iVbvl1XhbUVegK9gQ==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.28.0.tgz", + "integrity": "sha512-rwxCS6vTh2DJkNIYQX7JSrrRSmm76e2y48aZeuZO5ShkvLWMuJ3/zqDHRxAQVDiJhuE2Cp8NrTmPYlUc9YrT0A==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4" + "@tiptap/core": "3.28.0" } }, "node_modules/@tiptap/extensions": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.27.4.tgz", - "integrity": "sha512-d8opkg2iGtVwJmNGIqv0blfRxnvWOJp1brz+Z8CsP4ojSS2ZtaE46d6JSQ5OeJ7nMpjhT+9wh4UQcA7OSEO59w==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.28.0.tgz", + "integrity": "sha512-DJT1khCK+O/pT1gQlAnoKAx6zwDkgv7GtnhSfkqm1/4KHC3x+SSJnBIgBl9oGHymA+DxWbW1EULU4V3d/kT2uQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "3.27.4", - "@tiptap/pm": "3.27.4" + "@tiptap/core": "3.28.0", + "@tiptap/pm": "3.28.0" } }, "node_modules/@tiptap/pm": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.27.4.tgz", - "integrity": "sha512-UB8lcyomfWk7YGI2PZKNqcYXfyRA+PFj+QntlsUXyrsiA5JJIaE8SHKYjxKlGG/xtW3EtPm1b0p38T9Mk4xiFw==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.28.0.tgz", + "integrity": "sha512-ALcpwZMUdat9gjJKlpscpoqXStoLhU246LPEVBDvJdIsoUKvUu3MrzfXik2Y8mtSGfhjtm9O2TRkWxQiFVMwsQ==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.4.1", @@ -2029,35 +2150,35 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "3.27.4", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.27.4.tgz", - "integrity": "sha512-/sb6rFxNt5BO4hWpUwvHh+Yh1kNyCQuuz3oDpGef5HUUjSdu9p9rfNiHWIUKBadK8VXuw5es7N+UlZ4hma+gvA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.28.0.tgz", + "integrity": "sha512-pqvFpValV+ONtlu3l4s73ROm/tEjoGMmt6uHmSJaLbqTcMHkdWuR3flJ/5brr4IDHe1foxmNicMbRxlje7yBYw==", "license": "MIT", "dependencies": { - "@tiptap/core": "^3.27.4", - "@tiptap/extension-blockquote": "^3.27.4", - "@tiptap/extension-bold": "^3.27.4", - "@tiptap/extension-bullet-list": "^3.27.4", - "@tiptap/extension-code": "^3.27.4", - "@tiptap/extension-code-block": "^3.27.4", - "@tiptap/extension-document": "^3.27.4", - "@tiptap/extension-dropcursor": "^3.27.4", - "@tiptap/extension-gapcursor": "^3.27.4", - "@tiptap/extension-hard-break": "^3.27.4", - "@tiptap/extension-heading": "^3.27.4", - "@tiptap/extension-horizontal-rule": "^3.27.4", - "@tiptap/extension-italic": "^3.27.4", - "@tiptap/extension-link": "^3.27.4", - "@tiptap/extension-list": "^3.27.4", - "@tiptap/extension-list-item": "^3.27.4", - "@tiptap/extension-list-keymap": "^3.27.4", - "@tiptap/extension-ordered-list": "^3.27.4", - "@tiptap/extension-paragraph": "^3.27.4", - "@tiptap/extension-strike": "^3.27.4", - "@tiptap/extension-text": "^3.27.4", - "@tiptap/extension-underline": "^3.27.4", - "@tiptap/extensions": "^3.27.4", - "@tiptap/pm": "^3.27.4" + "@tiptap/core": "^3.28.0", + "@tiptap/extension-blockquote": "^3.28.0", + "@tiptap/extension-bold": "^3.28.0", + "@tiptap/extension-bullet-list": "^3.28.0", + "@tiptap/extension-code": "^3.28.0", + "@tiptap/extension-code-block": "^3.28.0", + "@tiptap/extension-document": "^3.28.0", + "@tiptap/extension-dropcursor": "^3.28.0", + "@tiptap/extension-gapcursor": "^3.28.0", + "@tiptap/extension-hard-break": "^3.28.0", + "@tiptap/extension-heading": "^3.28.0", + "@tiptap/extension-horizontal-rule": "^3.28.0", + "@tiptap/extension-italic": "^3.28.0", + "@tiptap/extension-link": "^3.28.0", + "@tiptap/extension-list": "^3.28.0", + "@tiptap/extension-list-item": "^3.28.0", + "@tiptap/extension-list-keymap": "^3.28.0", + "@tiptap/extension-ordered-list": "^3.28.0", + "@tiptap/extension-paragraph": "^3.28.0", + "@tiptap/extension-strike": "^3.28.0", + "@tiptap/extension-text": "^3.28.0", + "@tiptap/extension-underline": "^3.28.0", + "@tiptap/extensions": "^3.28.0", + "@tiptap/pm": "^3.28.0" }, "funding": { "type": "github", @@ -2153,6 +2274,37 @@ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT" }, + "node_modules/@vitest/coverage-v8": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.1.10", + "ast-v8-to-istanbul": "^1.0.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, "node_modules/@vitest/expect": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", @@ -2321,6 +2473,25 @@ "node": ">=12" } }, + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz", + "integrity": "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -2550,9 +2721,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.21.6", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", - "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", + "version": "5.24.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz", + "integrity": "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2692,6 +2863,16 @@ "dev": true, "license": "ISC" }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/html-encoding-sniffer": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", @@ -2705,10 +2886,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/html2canvas-pro": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/html2canvas-pro/-/html2canvas-pro-2.2.4.tgz", - "integrity": "sha512-fo/VOiQZ3oWykAPvnMNHymUHzLWJE7c7C7VWPh+ydb+NquFTwqY5rHQRoxkgsaXo/iciVryPNffTvLzYg98xhg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/html2canvas-pro/-/html2canvas-pro-2.3.1.tgz", + "integrity": "sha512-w7CCWi0B0kCy/joy5cPN2GIDGW0iwbqBppxxc2Vc5UyqYDQ1K13ZVr+MyGR/34Mq03emCTxVbBTpG299/prACw==", "license": "MIT", "dependencies": { "css-line-break": "^2.1.0", @@ -2788,6 +2976,45 @@ "@types/estree": "^1.0.6" } }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -3176,6 +3403,34 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/magicast": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", + "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.3", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdn-data": { "version": "2.27.1", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", @@ -3292,9 +3547,9 @@ "license": "MIT" }, "node_modules/oxlint": { - "version": "1.74.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.74.0.tgz", - "integrity": "sha512-odGl2s2x5IOJoj3A0v1k0PGBXVFBZeZ2+AK/+K2MJur7Ghi3bkyX5NuLUWHKqa4js1wjep3hJeuTQJOlr+4+dA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.75.0.tgz", + "integrity": "sha512-m9WzjRcRYA/uqIZDa9tclrieoPJ/ln1QYTKdFx6NUOs8uY5DiHlIwRQoCrHT6OM6O3ww3l2skY5gO7G7ZphE7g==", "dev": true, "license": "MIT", "bin": { @@ -3307,28 +3562,28 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.74.0", - "@oxlint/binding-android-arm64": "1.74.0", - "@oxlint/binding-darwin-arm64": "1.74.0", - "@oxlint/binding-darwin-x64": "1.74.0", - "@oxlint/binding-freebsd-x64": "1.74.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.74.0", - "@oxlint/binding-linux-arm-musleabihf": "1.74.0", - "@oxlint/binding-linux-arm64-gnu": "1.74.0", - "@oxlint/binding-linux-arm64-musl": "1.74.0", - "@oxlint/binding-linux-ppc64-gnu": "1.74.0", - "@oxlint/binding-linux-riscv64-gnu": "1.74.0", - "@oxlint/binding-linux-riscv64-musl": "1.74.0", - "@oxlint/binding-linux-s390x-gnu": "1.74.0", - "@oxlint/binding-linux-x64-gnu": "1.74.0", - "@oxlint/binding-linux-x64-musl": "1.74.0", - "@oxlint/binding-openharmony-arm64": "1.74.0", - "@oxlint/binding-win32-arm64-msvc": "1.74.0", - "@oxlint/binding-win32-ia32-msvc": "1.74.0", - "@oxlint/binding-win32-x64-msvc": "1.74.0" + "@oxlint/binding-android-arm-eabi": "1.75.0", + "@oxlint/binding-android-arm64": "1.75.0", + "@oxlint/binding-darwin-arm64": "1.75.0", + "@oxlint/binding-darwin-x64": "1.75.0", + "@oxlint/binding-freebsd-x64": "1.75.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.75.0", + "@oxlint/binding-linux-arm-musleabihf": "1.75.0", + "@oxlint/binding-linux-arm64-gnu": "1.75.0", + "@oxlint/binding-linux-arm64-musl": "1.75.0", + "@oxlint/binding-linux-ppc64-gnu": "1.75.0", + "@oxlint/binding-linux-riscv64-gnu": "1.75.0", + "@oxlint/binding-linux-riscv64-musl": "1.75.0", + "@oxlint/binding-linux-s390x-gnu": "1.75.0", + "@oxlint/binding-linux-x64-gnu": "1.75.0", + "@oxlint/binding-linux-x64-musl": "1.75.0", + "@oxlint/binding-openharmony-arm64": "1.75.0", + "@oxlint/binding-win32-arm64-msvc": "1.75.0", + "@oxlint/binding-win32-ia32-msvc": "1.75.0", + "@oxlint/binding-win32-x64-msvc": "1.75.0" }, "peerDependencies": { - "oxlint-tsgolint": ">=0.24.0", + "oxlint-tsgolint": ">=7.0.2001", "vite-plus": "*" }, "peerDependenciesMeta": { @@ -3461,9 +3716,9 @@ } }, "node_modules/prettier": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz", - "integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, "license": "MIT", "bin": { @@ -3491,9 +3746,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.8.0.tgz", - "integrity": "sha512-V8ITGH87yuBDF6JpEZTOVlUz/saAwqb8f3HRgUj8Lh+tGCcrmorhsLpYqzygwFwK0PE2Ib6Mv3M7T/uE2tZV1g==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.8.1.tgz", + "integrity": "sha512-iaFMYqDsE4ffdDkn5qup0j5f2aCEBFZrdrZnvu9QKTlWx/iGPeQ4HHu7b7fCPMxeo9nwQBiOAh2nSypdFYWJkw==", "dev": true, "license": "MIT", "engines": { @@ -3885,6 +4140,19 @@ "node": ">=v12.22.7" } }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/set-cookie-parser": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", @@ -3977,10 +4245,23 @@ "inline-style-parser": "0.2.7" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/svelte": { - "version": "5.56.5", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.5.tgz", - "integrity": "sha512-P03YJmUy2JoOxYHb4Ka3oFat1hq2ko2it1MOItSjsJ4B6WgZPLc3+RyyU+57OGWhs3Ieq74EJpZtSnNXdAGgDw==", + "version": "5.56.7", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.7.tgz", + "integrity": "sha512-5qERUZX80oQj6XrDMUmD2Uhd/cIpCPDWWKBK3ZHmyRUC9apPyamWM8xMo31mbWsIQxwG2hVoSnOJ/EcnhVkkzQ==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", @@ -4030,9 +4311,9 @@ } }, "node_modules/svelte-check": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.7.2.tgz", - "integrity": "sha512-GoS4XJdGswlq0rIT1vtFLzJY1bvHtY37McY9H9Gkm1Ggw/ICdZYn8J/Z8Yi0BEL0i3R4+jtaWVePjyppMlij/A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.7.3.tgz", + "integrity": "sha512-DHdTCGX62R0fCxBEaT+USdASAnoaRBaaNczkRJl0K7o3WyoCeVUbVxo6fKqpOll/B+WMWCsiFK0eFrJSNBKZIg==", "dev": true, "license": "MIT", "dependencies": { @@ -4097,9 +4378,9 @@ "license": "MIT" }, "node_modules/tailwindcss": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz", - "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", "dev": true, "license": "MIT" }, @@ -4380,16 +4661,16 @@ } }, "node_modules/vite": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", - "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", "devOptional": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", - "postcss": "^8.5.16", - "rolldown": "~1.1.4", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "bin": { diff --git a/package.json b/package.json index a059f5a..500a4ac 100644 --- a/package.json +++ b/package.json @@ -10,46 +10,46 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "format": "prettier . --write . --cache", "lint": "oxlint . -W perf", - "test:unit": "vitest", + "test:unit": "vitest --coverage", "test": "npm run test:unit -- --run && npm run test:e2e", "test:e2e": "playwright test" }, "devDependencies": { - "@iconify-json/tabler": "^1.2.35", + "@iconify-json/tabler": "^1.2.37", "@playwright/test": "^1.61.1", "@sveltejs/adapter-auto": "^7.0.1", - "@sveltejs/kit": "^2.69.3", + "@sveltejs/kit": "^2.70.1", "@sveltejs/vite-plugin-svelte": "^7.2.0", - "@tailwindcss/vite": "^4.3.2", - "@testing-library/jest-dom": "^6.9.1", + "@tailwindcss/vite": "^4.3.3", + "@testing-library/jest-dom": "^6.10.0", "@testing-library/svelte": "^5.4.2", - "@tiptap/extension-color": "^3.27.4", - "@tiptap/extension-font-family": "^3.27.4", - "@tiptap/extension-text-style": "^3.27.4", + "@tiptap/extension-color": "^3.28.0", + "@tiptap/extension-font-family": "^3.28.0", + "@tiptap/extension-text-style": "^3.28.0", "@types/node": "^26.1.1", "@vitest/coverage-v8": "4.1.10", "file-type": "^22.0.1", "jsdom": "^29.1.1", - "oxlint": "^1.74.0", - "prettier": "^3.9.5", + "oxlint": "^1.75.0", + "prettier": "^3.9.6", "prettier-plugin-svelte": "^4.1.1", - "prettier-plugin-tailwindcss": "^0.8.0", - "svelte": "^5.56.5", - "svelte-check": "^4.7.2", - "tailwindcss": "^4.3.2", + "prettier-plugin-tailwindcss": "^0.8.1", + "svelte": "^5.56.7", + "svelte-check": "^4.7.3", + "tailwindcss": "^4.3.3", "typescript": "^6.0.3", "unplugin-icons": "^23.0.1", - "vite": "^8.1.4", + "vite": "^8.1.5", "vitest": "^4.1.10" }, "type": "module", "dependencies": { - "@tiptap/core": "^3.27.4", - "@tiptap/extension-placeholder": "^3.27.4", - "@tiptap/pm": "^3.27.4", - "@tiptap/starter-kit": "^3.27.4", + "@tiptap/core": "^3.28.0", + "@tiptap/extension-placeholder": "^3.28.0", + "@tiptap/pm": "^3.28.0", + "@tiptap/starter-kit": "^3.28.0", "bits-ui": "^2.18.1", - "html2canvas-pro": "^2.2.4", + "html2canvas-pro": "^2.3.0", "idb": "^8.0.3", "svelte-awesome-color-picker": "^4.1.3", "tippy.js": "^6.3.7", diff --git a/src/lib/text/nbt/export.ts b/src/lib/text/nbt/export.ts index bcafd90..60f9bdf 100644 --- a/src/lib/text/nbt/export.ts +++ b/src/lib/text/nbt/export.ts @@ -7,7 +7,7 @@ import type { import { type JSONContent } from "@tiptap/core"; import { defaultColorLUT, - isMarkType, + findMarkType, trueMarkOrUndefined, unescapeUnicode, } from "../utils"; @@ -117,8 +117,8 @@ export function addTypeSpecificValues( * @param includeInteractivity if it should have interactive events or not */ function newApplyInteractiveValues(current: MinecraftText, c: JSONContent) { - if (isMarkType(c, "clickEvent")) { - const ce = isMarkType(c, "clickEvent")?.attrs; + if (findMarkType(c, "clickEvent")) { + const ce = findMarkType(c, "clickEvent")?.attrs; current.click_event = { action: ce!.action }; switch (ce!.action) { case "open_url": @@ -140,8 +140,8 @@ function newApplyInteractiveValues(current: MinecraftText, c: JSONContent) { } } - if (isMarkType(c, "hoverEvent")) { - const ce = isMarkType(c, "hoverEvent")?.attrs; + if (findMarkType(c, "hoverEvent")) { + const ce = findMarkType(c, "hoverEvent")?.attrs; current.hover_event = { action: ce!.action, value: ce!.value }; } } @@ -154,13 +154,13 @@ function newApplyInteractiveValues(current: MinecraftText, c: JSONContent) { * @param includeInteractivity if it should have interactive events or not */ function oldApplyInteractiveValues(current: OldMinecraftText, c: JSONContent) { - if (isMarkType(c, "clickEvent")) { - const ce = isMarkType(c, "clickEvent")?.attrs; + if (findMarkType(c, "clickEvent")) { + const ce = findMarkType(c, "clickEvent")?.attrs; current.clickEvent = { action: ce!.action, value: ce!.value }; } - if (isMarkType(c, "hoverEvent")) { - const ce = isMarkType(c, "hoverEvent")?.attrs; + if (findMarkType(c, "hoverEvent")) { + const ce = findMarkType(c, "hoverEvent")?.attrs; current.hoverEvent = { action: ce!.action, contents: ce!.value }; } } @@ -177,7 +177,7 @@ export function convert( exportVersion = get(outputVersion); let out = translateJSON(jsonContent, { exportType, optimise }); if (exportVersion.index >= 1 && !force_json) { - // only remove strings + // only remove string keys out = out.replace(/(?<=[{,]\s*)"[^"]*"\s*:/g, (match) => match.replace(/"/g, ""), ); diff --git a/src/lib/text/nbt/import.ts b/src/lib/text/nbt/import.ts index 8654aaf..701a950 100644 --- a/src/lib/text/nbt/import.ts +++ b/src/lib/text/nbt/import.ts @@ -296,28 +296,27 @@ function applyStyling( } if (text.click_event) { - const cE = text.click_event; + const e = text.click_event; // Check if only one of the properties is set, throw an error if more than one is set if ( - (cE.url && (cE.command || cE.value || cE.page || cE.dialog)) || - (cE.command && (cE.url || cE.value || cE.page || cE.dialog)) || - (cE.value && (cE.url || cE.command || cE.page || cE.dialog)) || - (cE.page && (cE.url || cE.command || cE.value || cE.dialog)) || - (cE.dialog && (cE.url || cE.command || cE.value || cE.page)) + (e.url && (e.command || e.value || e.page || e.dialog)) || + (e.command && (e.url || e.value || e.page || e.dialog)) || + (e.value && (e.url || e.command || e.page || e.dialog)) || + (e.page && (e.url || e.command || e.value || e.dialog)) || + (e.dialog && (e.url || e.command || e.value || e.page)) ) { throw new Error( "Click event can only have one of url, command, value, page, or dialog set.", ); } - const actionSource = - cE.url || cE.command || cE.value || cE.page || cE.dialog; + const actionSource = e.url || e.command || e.value || e.page || e.dialog; finalText.marks?.push({ type: "clickEvent", attrs: { - action: cE.action, + action: e.action, value: actionSource, }, }); diff --git a/src/lib/text/nbt/optimiser.ts b/src/lib/text/nbt/optimiser.ts index 417e4d4..86477ef 100644 --- a/src/lib/text/nbt/optimiser.ts +++ b/src/lib/text/nbt/optimiser.ts @@ -44,14 +44,6 @@ export function optimise( output.push(...flattenMCText(stringyTextElements)); output = mergeTextComponents(output); - // remove leading empty string if followed by a string - if (output.length >= 2 && output[0] === "" && typeof output[1] === "string") - output.shift(); - - if (shouldHaveLeadingEmptyString(output)) { - output.shift(); - } - // if it is item lore then override if (lore) { output.unshift({ italic: false, color: "white", text: "" }); @@ -132,24 +124,6 @@ function propsMatch(a: any, b: any, property: string) { : a === b; } -/** - * Determines if the final output should have the leading empty string removed - * - * @param output the optimized output array - * @returns true if the final output should have the leading empty string removed - */ -function shouldHaveLeadingEmptyString(output: StringyMCText[]): boolean { - return ( - output.length >= 2 && - output[0] == "" && - (typeof output[1] === "string" || - (typeof output[1] === "object" && - !styleProps.some( - (prop) => output[1][prop as keyof StringyMCText] !== undefined, - ))) - ); -} - /** * Flattens the text elements by converting objects with only text property to strings and removing undefined properties * @@ -174,9 +148,11 @@ function flattenMCText(stringyTextElements: StringyMCText[]): StringyMCText[] { } } - // if only text property remains, convert to string output.push( - Object.keys(component).length === 1 ? component.text! : component, + // if only text property remains, convert to string + Object.keys(component).length === 1 && component.text + ? component.text + : component, ); } return output; @@ -193,7 +169,7 @@ function mergeTextComponents(output: StringyMCText[]) { const current = output[i], next = output[i + 1]; - // Merge whitespace to next component + // Merge whitespace and empty strings to next component if ( isDefinedTextObject(current) && typeof next === "string" && @@ -269,7 +245,6 @@ function mergeTextComponents(output: StringyMCText[]) { } } output.splice(i, group.length, merged); - // i--; // TODO: actually fix the bug caused by checking again } } } diff --git a/src/lib/text/utils.ts b/src/lib/text/utils.ts index 1092bcd..17c82a8 100644 --- a/src/lib/text/utils.ts +++ b/src/lib/text/utils.ts @@ -71,33 +71,29 @@ export function defaultColorReverseLUT(color: string): string | undefined { return; } return colorMap.find((e) => e.name.toLowerCase() === color)?.value || color; -} /** - * Checks the type of the mark against `type` +} + +/** + * Finds a mark of a specific type in a JSONContent node. * * @param c the node you want to examine * @param type type to check - * @returns true if it matches + * @returns the mark if found, otherwise undefined */ - -export function isMarkType(c: JSONContent, type: string) { +export function findMarkType(c: JSONContent, type: string) { return c.marks?.find((e) => e.type === type); } export function unescapeUnicode(str: string) { const regex = /\\u(?:([0-9a-fA-F]{4})|\{([0-9a-fA-F]+)\})/g; - return str.replace(regex, (match, p1, p2) => { - // p1 will contain the 4-digit hex if it's \uXXXX - // p2 will contain the variable hex if it's \u{XXXXX} + // p1 will contain the 4-digit hex if it's \uXXXX + // p2 will contain the variable hex if it's \u{XXXXX} + return str.replace(regex, (_, p1: string, p2: string) => { const hex = p1 || p2; // Get the hex value from whichever group matched - if (hex) { - const codePoint = parseInt(hex, 16); - return String.fromCodePoint(codePoint); - } - // If for some reason no hex was captured (shouldn't happen with this regex), - // return the original match to avoid breaking the string. - return match; + const codePoint = parseInt(hex, 16); + return String.fromCodePoint(codePoint); }); } diff --git a/src/tests/unit/data/clean/snbt/interactives.snbt b/src/tests/unit/data/clean/snbt/interactives.snbt new file mode 100644 index 0000000..cf5e8fa --- /dev/null +++ b/src/tests/unit/data/clean/snbt/interactives.snbt @@ -0,0 +1 @@ +["",{text:"click events :3",click_event:{action:"suggest_command",command:"meow meow"}}] \ No newline at end of file diff --git a/src/tests/unit/data/clean/snbt/interactives_old.snbt b/src/tests/unit/data/clean/snbt/interactives_old.snbt new file mode 100644 index 0000000..607a2b8 --- /dev/null +++ b/src/tests/unit/data/clean/snbt/interactives_old.snbt @@ -0,0 +1 @@ +["",{"text":"click events :3","clickEvent":{"action":"suggest_command","value":"meow meow"}}] \ No newline at end of file diff --git a/src/tests/unit/exporting/optimising_mc_json.spec.ts b/src/tests/unit/exporting/optimising_mc_json.spec.ts index 63c68e0..091e2c7 100644 --- a/src/tests/unit/exporting/optimising_mc_json.spec.ts +++ b/src/tests/unit/exporting/optimising_mc_json.spec.ts @@ -13,6 +13,18 @@ describe("optimise", () => { expect(optimise([""])).toEqual([""]); }); + it("should combine with leading empty strings", () => { + expect( + optimise(["", { text: "hello " }, { color: "red", text: "world!" }]), + ).toEqual(["hello ", { color: "red", text: "world!" }]); + }); + + it("should combine whitespace string to next component ", () => { + expect( + optimise(["", { text: "hello" }, " ", { color: "red", text: "world!" }]), + ).toEqual(["hello ", { color: "red", text: "world!" }]); + }); + it("removes undefined properties and flattens objects with only text", () => { const input: StringyMCText[] = [ { text: "Hello", color: undefined, bold: undefined }, diff --git a/src/tests/unit/exporting/type_props.spec.ts b/src/tests/unit/exporting/type_props.spec.ts index ed1d8d5..0453f12 100644 --- a/src/tests/unit/exporting/type_props.spec.ts +++ b/src/tests/unit/exporting/type_props.spec.ts @@ -2,7 +2,7 @@ import { outputVersion } from "$lib/stores"; import { addTypeSpecificValues } from "$lib/text/nbt/export"; import { versions, type MinecraftText } from "$lib/types"; import type { JSONContent } from "@tiptap/core"; -import { expect, it } from "vitest"; +import { describe, expect, it } from "vitest"; it("should add text property for type 'text'", () => { const current: MinecraftText = {}; @@ -71,31 +71,59 @@ it("should add selector property for type 'selector'", () => { expect(result.selector).toBe("@a"); }); -it("should add atlas and sprite for type 'atlas_object'", () => { - outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports atlas_object - const current: MinecraftText = {}; - const c: JSONContent = { - type: "atlas_object", - attrs: { - atlas: "someAtlas", - sprite: "someSprite", - }, - }; +describe("object types", () => { + it("should add atlas and sprite for type 'atlas_object'", () => { + outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports atlas_object + const current: MinecraftText = {}; + const c: JSONContent = { + type: "atlas_object", + attrs: { + atlas: "someAtlas", + sprite: "someSprite", + }, + }; - const result = addTypeSpecificValues(current, c, false); - expect(result.atlas).toBe("someAtlas"); - expect(result.sprite).toBe("someSprite"); -}); + const result = addTypeSpecificValues(current, c, false); + expect(result.atlas).toBe("someAtlas"); + expect(result.sprite).toBe("someSprite"); + }); -it("should add object, player, and hat for type 'player_object'", () => { - outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports player_object - const current: MinecraftText = {}; - const c: JSONContent = { - type: "player_object", - attrs: { player: { name: "Cbble_" }, hat: true }, - }; - const result = addTypeSpecificValues(current, c, false); - expect(result.object).toBe("player"); - expect(result.player).toEqual({ name: "Cbble_" }); - expect(result.hat).toBe(true); + it("should add object, player, and hat for type 'player_object'", () => { + outputVersion.set(versions[versions.length - 1]); // Ensure exportVersion is set to a version that supports player_object + const current: MinecraftText = {}; + const c: JSONContent = { + type: "player_object", + attrs: { player: { name: "Cbble_" }, hat: true }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result.object).toBe("player"); + expect(result.player).toEqual({ name: "Cbble_" }); + expect(result.hat).toBe(true); + }); + + it("should be empty if version does not support 'atlas_object'", () => { + outputVersion.set(versions[0]); + const current: MinecraftText = {}; + const c: JSONContent = { + type: "atlas_object", + attrs: { + atlas: "someAtlas", + sprite: "someSprite", + }, + }; + + const result = addTypeSpecificValues(current, c, false); + expect(result).toEqual({ text: "" }); + }); + + it("should be empty if version does not support 'player_object'", () => { + outputVersion.set(versions[0]); + const current: MinecraftText = {}; + const c: JSONContent = { + type: "player_object", + attrs: { player: { name: "Cbble_" }, hat: true }, + }; + const result = addTypeSpecificValues(current, c, false); + expect(result).toEqual({ text: "" }); + }); }); diff --git a/src/tests/unit/importing/snbt_importing.spec.ts b/src/tests/unit/importing/snbt_importing.spec.ts index 293e8a5..271fbfd 100644 --- a/src/tests/unit/importing/snbt_importing.spec.ts +++ b/src/tests/unit/importing/snbt_importing.spec.ts @@ -99,6 +99,26 @@ it("should return a one length array if passed with a single component", async ( expect(converted[0]).toEqual({ text: "hi", color: "#c0bb1e" }); }); +it("should return valid interactive components", async () => { + const interactiveSNBT = await readTestDataFile( + "clean/snbt/interactives.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(interactiveSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks?.[0]).toBeDefined(); + expect(textNode?.marks?.[0].type).toBe("clickEvent"); +}); + +it("should return valid interactive components with old formats", async () => { + const interactiveSNBT = await readTestDataFile( + "clean/snbt/interactives_old.snbt", + ); + const document = snbtToDocument(convertToTextOrEmpty(interactiveSNBT)); + const textNode = document.content?.[0]?.content?.[0]; + expect(textNode?.marks?.[0]).toBeDefined(); + expect(textNode?.marks?.[0].type).toBe("clickEvent"); +}); + describe("handling text styling marks", () => { it("should bold text styling to a text node", async () => { const allTextStyleSNBT = await readTestDataFile( diff --git a/src/tests/unit/misc/utils.spec.ts b/src/tests/unit/misc/utils.spec.ts index 96b99c6..d9d7361 100644 --- a/src/tests/unit/misc/utils.spec.ts +++ b/src/tests/unit/misc/utils.spec.ts @@ -2,7 +2,7 @@ import { defaultColorLUT, defaultColorReverseLUT, isDefinedTextObject, - isMarkType, + findMarkType, trueMarkOrUndefined, unescapeUnicode, } from "$lib/text/utils"; @@ -56,6 +56,11 @@ describe("unescapeUnicode", () => { const output = unescapeUnicode(input); expect(output).toBe("HELLO"); }); + it("should correctly handle invalid unicode sequences", () => { + const input = "\\uXXXX"; + const output = unescapeUnicode(input); + expect(output).toBe("\\uXXXX"); + }); }); describe("trueMarkOrUndefined", () => { @@ -105,13 +110,13 @@ describe("defaultColorLUT", () => { }); }); -it("isMarkType should correctly identify mark types", () => { +it("findMarkType finds the correct mark", () => { const contentWithMarks: JSONContent = { type: "text", marks: [{ type: "bold" }, { type: "italic" }], text: "Sample Text", }; - expect(isMarkType(contentWithMarks, "bold")).toBeDefined(); - expect(isMarkType(contentWithMarks, "italic")).toBeDefined(); - expect(isMarkType(contentWithMarks, "underline")).toBeUndefined(); + expect(findMarkType(contentWithMarks, "bold")).toBeDefined(); + expect(findMarkType(contentWithMarks, "italic")).toBeDefined(); + expect(findMarkType(contentWithMarks, "underline")).toBeUndefined(); }); diff --git a/vite.config.ts b/vite.config.ts index 5e3b77f..c6597c6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,6 @@ import { svelteTesting } from "@testing-library/svelte/vite"; import { sveltekit } from "@sveltejs/kit/vite"; -import { defineConfig } from "vite"; +import { defineConfig } from "vitest/config"; import Icons from "unplugin-icons/vite"; import tailwindcss from "@tailwindcss/vite"; From 54f81d692eaa541e16f80686e51b5aea19ff4795 Mon Sep 17 00:00:00 2001 From: Cobblestone Date: Wed, 22 Jul 2026 09:59:51 -0400 Subject: [PATCH 04/10] linting expansion --- package.json | 2 +- src/lib/components/text/MiniEditor.svelte | 7 +++-- .../components/text/ShadowColorButton.svelte | 3 --- src/lib/db.ts | 4 +-- src/lib/text/motd.ts | 12 ++++----- src/lib/text/nbt/export.ts | 18 ++++++------- src/lib/text/nbt/import.ts | 20 +++++++------- src/lib/text/nbt/optimiser.ts | 25 ++++++++---------- src/lib/text/utils.ts | 7 ++--- src/lib/tiptap/extensions/FixedTextStyle.ts | 2 +- src/lib/tiptap/extensions/fonts.ts | 2 +- .../tiptap/extensions/marks/ClickEventMark.ts | 6 ++--- .../tiptap/extensions/marks/HoverEventMark.ts | 4 +-- .../extensions/marks/ShadowColorMark.ts | 4 +-- src/lib/types.ts | 3 ++- src/routes/+page.svelte | 26 +++++++++---------- .../unit/exporting/optimising_mc_json.spec.ts | 2 +- .../unit/importing/snbt_importing.spec.ts | 2 +- 18 files changed, 73 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index 500a4ac..17b6519 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "format": "prettier . --write . --cache", - "lint": "oxlint . -W perf", + "lint": "oxlint . -W perf -W suspicious --vitest-plugin", "test:unit": "vitest --coverage", "test": "npm run test:unit -- --run && npm run test:e2e", "test:e2e": "playwright test" diff --git a/src/lib/components/text/MiniEditor.svelte b/src/lib/components/text/MiniEditor.svelte index acf417e..3b247e2 100644 --- a/src/lib/components/text/MiniEditor.svelte +++ b/src/lib/components/text/MiniEditor.svelte @@ -55,7 +55,6 @@ editor = newEditor; }, onUpdate: ({ editor }) => { - // TODO: fix the JSON parsing errors that can happen here value = JSON.stringify(editor.getJSON()); output = JSON.parse(translate(editor.getJSON())); }, @@ -109,9 +108,9 @@ } export function getValue() { - return translate(editor!.getJSON()).replace( - /"(?:[^"\\]*(?:\\.[^"\\]*)*)"\s*:/g, - (match) => match.replace(/"/g, ""), + return translate(editor!.getJSON()).replaceAll( + /"(?:[^"\\]*(?:\\.[^"\\]*)*)"\s*:/gu, + (match) => match.replaceAll(`"`, ""), ); } diff --git a/src/lib/components/text/ShadowColorButton.svelte b/src/lib/components/text/ShadowColorButton.svelte index fede43f..ac1731c 100644 --- a/src/lib/components/text/ShadowColorButton.svelte +++ b/src/lib/components/text/ShadowColorButton.svelte @@ -18,9 +18,6 @@ let { labelElement = $bindable(), - hex, - label, - name = undefined, dir, small, }: Props = $props(); diff --git a/src/lib/db.ts b/src/lib/db.ts index a3102e7..2fe70a3 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -1,7 +1,7 @@ import { openDB } from "idb"; export async function openDataStore() { - const db = await openDB("dph_data-store", 1, { + const fontDatabase = await openDB("dph_data-store", 1, { upgrade(db, _old, _new, _) { db.createObjectStore("fonts", { keyPath: "identifier", @@ -9,5 +9,5 @@ export async function openDataStore() { }, }); - return db; + return fontDatabase; } diff --git a/src/lib/text/motd.ts b/src/lib/text/motd.ts index aea41ec..34c8f5c 100644 --- a/src/lib/text/motd.ts +++ b/src/lib/text/motd.ts @@ -75,20 +75,20 @@ export function translateMOTD(c: JSONContent) { let lowestDEVal = ""; let formatting = ""; - const color = c.marks?.at(0)?.attrs?.color; - for (const c of colorMap) { - if (!color) { + const colorMark = c.marks?.at(0)?.attrs?.color; + for (const color of colorMap) { + if (!colorMark) { continue; } - const dE = deltaE(color, c.value); + const dE = deltaE(colorMark, color.value); if (dE === 0) { - lowestDEVal = `${char}${c.code}`; + lowestDEVal = `${char}${color.code}`; break; } if (dE < lowestDE) { lowestDE = dE; - lowestDEVal = `${char}${c.code}`; + lowestDEVal = `${char}${color.code}`; } } diff --git a/src/lib/text/nbt/export.ts b/src/lib/text/nbt/export.ts index 60f9bdf..75eb5d5 100644 --- a/src/lib/text/nbt/export.ts +++ b/src/lib/text/nbt/export.ts @@ -45,7 +45,7 @@ export function addTypeSpecificValues( break; case "translate": current.translate = c.attrs?.key; - if (c.attrs?.params && c.attrs?.params.length != 0) { + if (c.attrs?.params && c.attrs?.params.length !== 0) { current.with = c.attrs?.params; } if (c.attrs?.fallback) { @@ -170,16 +170,16 @@ function oldApplyInteractiveValues(current: OldMinecraftText, c: JSONContent) { */ export function convert( jsonContent: JSONContent, - exportType: "standard" | "item_lore" = "standard", optimise: boolean, - force_json: boolean = false, + exportType: "standard" | "item_lore" = "standard", + forceJson: boolean = false, ): string { exportVersion = get(outputVersion); let out = translateJSON(jsonContent, { exportType, optimise }); - if (exportVersion.index >= 1 && !force_json) { + if (exportVersion.index >= 1 && !forceJson) { // only remove string keys - out = out.replace(/(?<=[{,]\s*)"[^"]*"\s*:/g, (match) => - match.replace(/"/g, ""), + out = out.replaceAll(/(?<=[{,]\s*)"[^"]*"\s*:/gu, (match) => + match.replaceAll(`"`, ""), ); } return out; @@ -212,10 +212,10 @@ export function translateJSON( const shadowColorMark = c.marks?.find((m) => m.type === "shadowColor"); if (shadowColorMark) { - let colorVal = shadowColorMark.attrs?.shadowColor.replace(/^#/, ""); + let colorVal = shadowColorMark.attrs?.shadowColor.replace(/^#/u, ""); if (colorVal && colorVal.length <= 8) { current.shadow_color = parseInt( - rgbaToArgbHex(colorVal).replace(/^#/, ""), + rgbaToArgbHex(colorVal).replace(/^#/u, ""), 16, ); } @@ -245,7 +245,7 @@ export function translateJSON( let finalResult = JSON.stringify(data); - const shadowColorMatches = finalResult.matchAll(/"shadow_color":(-?\d+)/g); + const shadowColorMatches = finalResult.matchAll(/"shadow_color":(-?\d+)/gu); for (const match of shadowColorMatches) { if (match[1]) { const num = parseInt(match[1]); diff --git a/src/lib/text/nbt/import.ts b/src/lib/text/nbt/import.ts index 701a950..5b4478d 100644 --- a/src/lib/text/nbt/import.ts +++ b/src/lib/text/nbt/import.ts @@ -31,8 +31,9 @@ export function convertToTextOrEmpty(raw: string): StringyMCText[] { if (raw === "") return []; raw = raw - .replace(/([,{]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":') // quote unquoted keys - .replace(/:\s*([a-zA-Z_][a-zA-Z0-9_.:-]*)(?=\s*[,}\]])/g, (_, p1) => { + // quote unquoted keys + .replaceAll(/([,{]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/gu, '$1"$2":') + .replaceAll(/:\s*([a-zA-Z_][a-zA-Z0-9_.:-]*)(?=\s*[,}\]])/gu, (_, p1) => { // quote unquoted strings, ignoring booleans const protectedValues = ["true", "false", "1b", "0b"]; if (protectedValues.includes(p1.toLowerCase())) { @@ -40,16 +41,16 @@ export function convertToTextOrEmpty(raw: string): StringyMCText[] { } return `: "${p1}"`; }); - if (raw.match(/^"\w*"/)) { - return [raw.replace(/"/g, "")]; + if (/^"\w*"/u.test(raw)) { + return [raw.replaceAll(`"`, "")]; } // replace 1b and 0b with true and false literals - raw = raw.replace(/(?<="\w+"\s*:\s*)\b1b\b/g, "true"); - raw = raw.replace(/(?<="\w+"\s*:\s*)\b0b\b/g, "false"); + raw = raw.replaceAll(/(?<="\w+"\s*:\s*)\b1b\b/gu, "true"); + raw = raw.replaceAll(/(?<="\w+"\s*:\s*)\b0b\b/gu, "false"); // remove type suffixes from numbers (e.g., 1.0f, 2.0d, 3l) - raw = raw.replace(/(?<="\w+"\s*:\s*)-?\d+(\.\d+)?[fdl]/gi, (match) => { + raw = raw.replaceAll(/(?<="\w+"\s*:\s*)-?\d+(\.\d+)?[fdl]/giu, (match) => { return match.slice(0, -1); }); @@ -251,7 +252,7 @@ function applyStyling( Array.isArray(text.shadow_color) ? text.shadow_color.map(mapToHexByte).join("") : text.shadow_color.toString(16) - ).replace(/[lL#]/g, ""); + ).replaceAll(/[lL#]/gu, ""); const intValue = parseInt(combinedShadowStr, 16); if (intValue > 0 && intValue < 0xffffffff) { @@ -422,7 +423,8 @@ function fixBrokenNewLines(doc: JSONContent) { function mapToHexByte(value: number): string { if (value < 0.0 || value > 1.0) { - return "00"; // Return "00" for out-of-range values + // Return "00" for out-of-range values + return "00"; } const byteValue = Math.round(value * 255); diff --git a/src/lib/text/nbt/optimiser.ts b/src/lib/text/nbt/optimiser.ts index 86477ef..8872738 100644 --- a/src/lib/text/nbt/optimiser.ts +++ b/src/lib/text/nbt/optimiser.ts @@ -143,7 +143,8 @@ function flattenMCText(stringyTextElements: StringyMCText[]): StringyMCText[] { // MinecraftText with text property for (const [key, value] of Object.entries(component)) { if (value === undefined) { - delete component[key as MCTextKey]; // remove undefined properties + // remove undefined properties + delete component[key as MCTextKey]; } } } @@ -173,7 +174,7 @@ function mergeTextComponents(output: StringyMCText[]) { if ( isDefinedTextObject(current) && typeof next === "string" && - next.match(/^\s*$/) + /^\s*$/u.test(next) ) { current.text += next; output.splice(i + 1, 1); @@ -184,12 +185,12 @@ function mergeTextComponents(output: StringyMCText[]) { // Merge whitespace objects to next component if (isDefinedTextObject(current) && isDefinedTextObject(next)) { // which direction to merge - if (next.text.match(/^\s+$/)) { + if (/^\s+$/u.test(next.text)) { current.text += next.text; output.splice(i + 1, 1); i--; continue; - } else if (current.text.match(/^\s+$/)) { + } else if (/^\s+$/u.test(current.text)) { next.text = current.text + next.text; output.splice(i, 1); i--; @@ -213,7 +214,7 @@ function mergeTextComponents(output: StringyMCText[]) { let group = [current]; collectAllFromIndex(i, group, output, sharedProperties); - if (group.length < 1) { + if (group.length === 0) { continue; } @@ -231,18 +232,14 @@ function mergeTextComponents(output: StringyMCText[]) { const first = extras.shift(); let merged = { ...sharedProperties }; // Rebuild merged component - if (typeof first == "string") { + if (typeof first === "string") { merged.text = first; - if (extras.length > 0) { - if (!merged.extra) merged.extra = extras; - else merged.extra = merged.extra.concat(extras); - } } else { Object.assign(merged, { ...first }); - if (extras.length > 0) { - if (!merged.extra) merged.extra = extras; - else merged.extra = merged.extra.concat(extras); - } + } + if (extras.length > 0) { + if (merged.extra) {merged.extra = merged.extra.concat(extras);} + else {merged.extra = extras;} } output.splice(i, group.length, merged); } diff --git a/src/lib/text/utils.ts b/src/lib/text/utils.ts index 17c82a8..8c253e6 100644 --- a/src/lib/text/utils.ts +++ b/src/lib/text/utils.ts @@ -85,12 +85,13 @@ export function findMarkType(c: JSONContent, type: string) { } export function unescapeUnicode(str: string) { - const regex = /\\u(?:([0-9a-fA-F]{4})|\{([0-9a-fA-F]+)\})/g; + const regex = /\\u(?:([0-9a-fA-F]{4})|\{([0-9a-fA-F]+)\})/gu; // p1 will contain the 4-digit hex if it's \uXXXX // p2 will contain the variable hex if it's \u{XXXXX} return str.replace(regex, (_, p1: string, p2: string) => { - const hex = p1 || p2; // Get the hex value from whichever group matched + // Get the hex value from whichever group matched + const hex = p1 || p2; const codePoint = parseInt(hex, 16); return String.fromCodePoint(codePoint); @@ -126,7 +127,7 @@ export function applyGradient(editor: Editor, gradientColors: string[]) { } } }); - if (!text.length) return; + if (text.length === 0) return; const total = text.length; if (total === 0 || gradientColors.length < 2) return; diff --git a/src/lib/tiptap/extensions/FixedTextStyle.ts b/src/lib/tiptap/extensions/FixedTextStyle.ts index 4f78ee8..44e5b7f 100644 --- a/src/lib/tiptap/extensions/FixedTextStyle.ts +++ b/src/lib/tiptap/extensions/FixedTextStyle.ts @@ -16,7 +16,7 @@ export const FixedTextStyle = TextStyle.extend({ // Helper function to convert rgb() to hex function rgbToHex(rgb: string): string { - const result = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.exec(rgb); + const result = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/u.exec(rgb); return result ? "#" + [1, 2, 3] diff --git a/src/lib/tiptap/extensions/fonts.ts b/src/lib/tiptap/extensions/fonts.ts index 9ad7269..0d381ec 100644 --- a/src/lib/tiptap/extensions/fonts.ts +++ b/src/lib/tiptap/extensions/fonts.ts @@ -20,7 +20,7 @@ export const FontsExtension = Extension.create({ font: { default: null, parseHTML: (element) => - element.style.fontFamily?.replace(/['"]+/g, ""), + element.style.fontFamily?.replaceAll(/['"]+/gu, ""), renderHTML: (attributes) => { if (!attributes.font) { return {}; diff --git a/src/lib/tiptap/extensions/marks/ClickEventMark.ts b/src/lib/tiptap/extensions/marks/ClickEventMark.ts index 29aef19..15ece51 100644 --- a/src/lib/tiptap/extensions/marks/ClickEventMark.ts +++ b/src/lib/tiptap/extensions/marks/ClickEventMark.ts @@ -21,8 +21,8 @@ export const ClickEventMark = Mark.create({ return false; } const el = element as HTMLElement; - const action = el.getAttribute("data-click-event-action"); - const value = el.getAttribute("data-click-event-value"); + const action = el.dataset.clickEventAction; + const value = el.dataset.clickEventValue; if (!action) { return false; } @@ -42,7 +42,7 @@ export const ClickEventMark = Mark.create({ { "data-click-event-action": HTMLAttributes.action, "data-click-event-value": HTMLAttributes.value, - class: "clickEvent", // Optional styling + class: "clickEvent", }, HTMLAttributes, ), diff --git a/src/lib/tiptap/extensions/marks/HoverEventMark.ts b/src/lib/tiptap/extensions/marks/HoverEventMark.ts index 7c28eba..400a51b 100644 --- a/src/lib/tiptap/extensions/marks/HoverEventMark.ts +++ b/src/lib/tiptap/extensions/marks/HoverEventMark.ts @@ -20,8 +20,8 @@ export const HoverEventMark = Mark.create({ return false; } const el = element as HTMLElement; - const action = el.getAttribute("data-hover-event-action"); - const value = JSON.parse(el.getAttribute("data-hover-event-value")!); + const action = el.dataset.hoverEventAction; + const value = JSON.parse(el.dataset.hoverEventValue!); if (!action) { return false; } diff --git a/src/lib/tiptap/extensions/marks/ShadowColorMark.ts b/src/lib/tiptap/extensions/marks/ShadowColorMark.ts index acd9a83..18a22d0 100644 --- a/src/lib/tiptap/extensions/marks/ShadowColorMark.ts +++ b/src/lib/tiptap/extensions/marks/ShadowColorMark.ts @@ -8,7 +8,7 @@ export const ShadowColorMark = Mark.create({ shadowColor: { default: null, parseHTML: (element) => - element.getAttribute("data-shadow-color") || null, + element.dataset.shadowColor || null, renderHTML: (attributes) => { if (!attributes.shadowColor) { return {}; @@ -28,7 +28,7 @@ export const ShadowColorMark = Mark.create({ return false; } const el = element as HTMLElement; - const shadowColor = el.getAttribute("data-shadow-color"); + const shadowColor = el.dataset.shadowColor; if (!shadowColor) { return false; } diff --git a/src/lib/types.ts b/src/lib/types.ts index 5b993e1..8a812c6 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -134,7 +134,8 @@ export type ExternalSources = { selector: string; }; object: { - object?: string; // can be omitted for only atlas objects ONLY + // can be omitted for only atlas objects ONLY + object?: string; atlas: string; sprite: string; player: { diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 783adde..51a0175 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -110,7 +110,7 @@ let unicodeSelectorDialog: Modal = $state()!; let finalOutput = $derived( - editor ? convert(tiptapJSON, "standard", shouldOptimise) : "Loading...", + editor ? convert(tiptapJSON, shouldOptimise) : "Loading...", ); function importToEditor() { @@ -209,9 +209,9 @@ }); function toTitleCase(str: string) { - return str.replace( - /\w\S*/g, - (text) => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase(), + return str.replaceAll( + /\w\S*/gu, + (text) => text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(), ); } @@ -220,7 +220,7 @@ colorDialog?.close(); } - const debounce = (callback: Function, wait: number) => { + const debounce = (callback: (...args: any[]) => void, wait: number) => { let timeoutId: number; return (...args: any[]) => { window.clearTimeout(timeoutId); @@ -338,12 +338,12 @@ } } - function removeAllNodes(editor: Editor | undefined, type: string) { + function removeAllNodes(type: string) { if (!editor) { return; } - let editor_json = editor.getJSON(); - editor_json.content.forEach((paragraph) => { + let editorJson = editor.getJSON(); + editorJson.content.forEach((paragraph) => { if (paragraph.content) { paragraph.content = paragraph.content.filter( (node) => node.type !== type, @@ -351,8 +351,8 @@ } }); - editor?.commands.setContent(editor_json); - tiptapJSON = editor_json; + editor?.commands.setContent(editorJson); + tiptapJSON = editorJson; } let versionPopupConfirmationVisible = $state(false); @@ -363,7 +363,7 @@ return; } - if ($outputVersion.index > version.index && confirm == false) { + if ($outputVersion.index > version.index && confirm === false) { versionPopupConfirmationVisible = true; temporaryVersionConfirmation = version; return; @@ -376,8 +376,8 @@ if (version.index < 2) { // remove object keys - removeAllNodes(editor, "atlas_object"); - removeAllNodes(editor, "player_object"); + removeAllNodes("atlas_object"); + removeAllNodes("player_object"); } tiptapJSON = editor!.getJSON(); diff --git a/src/tests/unit/exporting/optimising_mc_json.spec.ts b/src/tests/unit/exporting/optimising_mc_json.spec.ts index 091e2c7..6c6aae9 100644 --- a/src/tests/unit/exporting/optimising_mc_json.spec.ts +++ b/src/tests/unit/exporting/optimising_mc_json.spec.ts @@ -19,7 +19,7 @@ describe("optimise", () => { ).toEqual(["hello ", { color: "red", text: "world!" }]); }); - it("should combine whitespace string to next component ", () => { + it("should combine whitespace string to next component", () => { expect( optimise(["", { text: "hello" }, " ", { color: "red", text: "world!" }]), ).toEqual(["hello ", { color: "red", text: "world!" }]); diff --git a/src/tests/unit/importing/snbt_importing.spec.ts b/src/tests/unit/importing/snbt_importing.spec.ts index 271fbfd..6ec4fbc 100644 --- a/src/tests/unit/importing/snbt_importing.spec.ts +++ b/src/tests/unit/importing/snbt_importing.spec.ts @@ -10,7 +10,7 @@ it("should return a basic document", async () => { expect(document).toEqual(expectedDocument); }); -it("should return a basic document (empty str)", async () => { +it("should return a basic document (empty str)", () => { const document = snbtToDocument(convertToTextOrEmpty("")); const expectedDocument = { content: [], type: "doc" }; expect(document).toEqual(expectedDocument); From dda7b5c565d6fe3f15d7c688b0d25e6a163b3c39 Mon Sep 17 00:00:00 2001 From: Cobblestone Date: Wed, 22 Jul 2026 10:03:49 -0400 Subject: [PATCH 05/10] formatting --- src/lib/components/text/ShadowColorButton.svelte | 6 +----- src/lib/text/nbt/optimiser.ts | 7 +++++-- src/lib/tiptap/extensions/marks/ShadowColorMark.ts | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/lib/components/text/ShadowColorButton.svelte b/src/lib/components/text/ShadowColorButton.svelte index ac1731c..5429b3a 100644 --- a/src/lib/components/text/ShadowColorButton.svelte +++ b/src/lib/components/text/ShadowColorButton.svelte @@ -16,11 +16,7 @@ small?: boolean; } - let { - labelElement = $bindable(), - dir, - small, - }: Props = $props(); + let { labelElement = $bindable(), dir, small }: Props = $props(); +
+ +
+ + +
+
diff --git a/src/lib/tiptap/extensions/nodes/BlockNBTNode.ts b/src/lib/tiptap/extensions/nodes/BlockNBTNode.ts index cb8254e..2f9bde6 100644 --- a/src/lib/tiptap/extensions/nodes/BlockNBTNode.ts +++ b/src/lib/tiptap/extensions/nodes/BlockNBTNode.ts @@ -39,14 +39,14 @@ export const BlockNBTNode = Node.create({ "data-nbt-node": "true", contenteditable: "false", style: ` - background-color: #18181b; - padding: 1px 5px; - border-radius: 4px; - font-size: 1rem; - display: inline-block; - vertical-align: var(--custom-source-align, middle); - text-decoration: inherit; - `, + background-color: #18181b; + padding: 1px 5px; + border-radius: 4px; + font-size: 1rem; + display: inline-block; + vertical-align: var(--custom-source-align, middle); + text-decoration: inherit; + `, }), ["span", {}, `NBT: ${nbt}, ${block}`], ]; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 4323837..c958c97 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,30 +1,23 @@