diff --git a/package-lock.json b/package-lock.json index f0fb2ba54..aba354715 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,6 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", @@ -70,7 +69,6 @@ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -130,7 +128,6 @@ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "dev": true, - "peer": true, "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", @@ -147,7 +144,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.27.3" }, @@ -160,7 +156,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", @@ -177,7 +172,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -199,7 +193,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "regexpu-core": "^6.2.0", @@ -217,7 +210,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", @@ -234,7 +226,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -244,7 +235,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", "dev": true, - "peer": true, "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" @@ -258,7 +248,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, - "peer": true, "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" @@ -272,7 +261,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", @@ -290,7 +278,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.27.1" }, @@ -303,7 +290,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -313,7 +299,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", @@ -331,7 +316,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", @@ -349,7 +333,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "dev": true, - "peer": true, "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" @@ -380,7 +363,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -390,7 +372,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", @@ -405,7 +386,6 @@ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" @@ -434,7 +414,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" @@ -451,7 +430,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -467,7 +445,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -483,7 +460,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", @@ -501,7 +477,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" @@ -518,7 +493,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" }, @@ -544,7 +518,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -560,7 +533,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -576,7 +548,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -593,7 +564,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -609,7 +579,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", @@ -627,7 +596,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", @@ -645,7 +613,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -661,7 +628,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -677,7 +643,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -694,7 +659,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" @@ -711,7 +675,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", @@ -732,7 +695,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" @@ -749,7 +711,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.0" @@ -766,7 +727,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -783,7 +743,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -799,7 +758,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -816,7 +774,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -832,7 +789,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" @@ -849,7 +805,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -865,7 +820,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -881,7 +835,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -898,7 +851,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", @@ -916,7 +868,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -932,7 +883,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -948,7 +898,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -964,7 +913,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -980,7 +928,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -997,7 +944,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1014,7 +960,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", @@ -1033,7 +978,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1050,7 +994,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1067,7 +1010,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1083,7 +1025,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1099,7 +1040,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1115,7 +1055,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", @@ -1135,7 +1074,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" @@ -1152,7 +1090,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1168,7 +1105,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -1185,7 +1121,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1201,7 +1136,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1218,7 +1152,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -1236,7 +1169,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1252,7 +1184,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1268,7 +1199,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1285,7 +1215,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1301,7 +1230,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1317,7 +1245,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" @@ -1334,7 +1261,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1350,7 +1276,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1366,7 +1291,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1382,7 +1306,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, @@ -1398,7 +1321,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1415,7 +1337,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1432,7 +1353,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" @@ -1534,7 +1454,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -1557,7 +1476,6 @@ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", @@ -1572,7 +1490,6 @@ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1680,7 +1597,6 @@ "url": "https://opencollective.com/csstools" } ], - "peer": true, "engines": { "node": ">=18" }, @@ -1702,7 +1618,6 @@ "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", "dev": true, - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/JounQin" @@ -1714,7 +1629,6 @@ "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" @@ -1726,7 +1640,6 @@ "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1737,7 +1650,6 @@ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1747,7 +1659,6 @@ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", "integrity": "sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==", "dev": true, - "peer": true, "dependencies": { "comment-parser": "1.4.1", "esquery": "^1.5.0", @@ -2178,7 +2089,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.8.0.tgz", "integrity": "sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==", "dev": true, - "peer": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2197,7 +2107,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2210,7 +2119,6 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2220,7 +2128,6 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2244,7 +2151,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2255,7 +2161,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2268,7 +2173,6 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2310,7 +2214,6 @@ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, - "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -2325,7 +2228,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2336,7 +2238,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2349,7 +2250,6 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "peer": true, "engines": { "node": ">=12.22" }, @@ -2363,8 +2263,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "peer": true + "dev": true }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", @@ -2436,7 +2335,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" @@ -2447,7 +2345,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -2458,7 +2355,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -2473,7 +2369,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2483,8 +2378,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@mdi/js": { "version": "7.4.47", @@ -2633,7 +2527,6 @@ "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", @@ -2800,7 +2693,6 @@ "resolved": "https://registry.npmjs.org/@nextcloud/eslint-plugin/-/eslint-plugin-2.2.1.tgz", "integrity": "sha512-RX+0FxpL1h2EzjNLeW0VSGTkbyWIq7WgV7QAjtyUmDbSGwf1ds9Zy5OcRkgXRHRIu/W0gB0DhS2iz9qXHphCzA==", "dev": true, - "peer": true, "dependencies": { "fast-xml-parser": "^4.2.5", "requireindex": "^1.2.0", @@ -2819,7 +2711,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -3087,7 +2978,6 @@ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, - "peer": true, "dependencies": { "eslint-scope": "5.1.1" } @@ -3097,7 +2987,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -3111,7 +3000,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "peer": true, "engines": { "node": ">= 8" } @@ -3121,7 +3009,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -3135,7 +3022,6 @@ "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, - "peer": true, "engines": { "node": ">=12.4.0" } @@ -3153,7 +3039,6 @@ "dev": true, "hasInstallScript": true, "optional": true, - "peer": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -3195,7 +3080,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3216,7 +3100,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3237,7 +3120,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3258,7 +3140,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3279,7 +3160,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3300,7 +3180,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3321,7 +3200,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3342,7 +3220,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3363,7 +3240,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3384,7 +3260,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3405,7 +3280,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3426,7 +3300,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3447,7 +3320,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -3814,8 +3686,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@rushstack/node-core-library": { "version": "5.14.0", @@ -3846,6 +3717,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -3992,7 +3864,6 @@ "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -4067,8 +3938,7 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/mdast": { "version": "4.0.4", @@ -4088,6 +3958,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.13.tgz", "integrity": "sha512-yCAeZl7a0DxgNVteXFHt9+uyFbqXGy/ShC4BlcHkoE0AfGXYv/BUiplV72DjMYXHDBXFjhvr6DD1NiRVfB4j8g==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -4144,7 +4015,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.18.0", @@ -4207,7 +4077,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" @@ -4225,7 +4094,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/typescript-estree": "7.18.0", "@typescript-eslint/utils": "7.18.0", @@ -4253,7 +4121,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, - "peer": true, "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -4267,7 +4134,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", @@ -4296,7 +4162,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -4309,7 +4174,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.18.0", @@ -4332,7 +4196,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" @@ -4350,7 +4213,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4374,8 +4236,7 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-android-arm64": { "version": "1.11.1", @@ -4388,8 +4249,7 @@ "optional": true, "os": [ "android" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.11.1", @@ -4402,8 +4262,7 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { "version": "1.11.1", @@ -4416,8 +4275,7 @@ "optional": true, "os": [ "darwin" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { "version": "1.11.1", @@ -4430,8 +4288,7 @@ "optional": true, "os": [ "freebsd" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { "version": "1.11.1", @@ -4444,8 +4301,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { "version": "1.11.1", @@ -4458,8 +4314,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { "version": "1.11.1", @@ -4472,8 +4327,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { "version": "1.11.1", @@ -4486,8 +4340,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { "version": "1.11.1", @@ -4500,8 +4353,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { "version": "1.11.1", @@ -4514,8 +4366,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { "version": "1.11.1", @@ -4528,8 +4379,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { "version": "1.11.1", @@ -4542,8 +4392,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { "version": "1.11.1", @@ -4556,8 +4405,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { "version": "1.11.1", @@ -4570,8 +4418,7 @@ "optional": true, "os": [ "linux" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { "version": "1.11.1", @@ -4582,7 +4429,6 @@ ], "dev": true, "optional": true, - "peer": true, "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, @@ -4601,8 +4447,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { "version": "1.11.1", @@ -4615,8 +4460,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { "version": "1.11.1", @@ -4629,8 +4473,7 @@ "optional": true, "os": [ "win32" - ], - "peer": true + ] }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.1", @@ -5061,6 +4904,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5073,7 +4917,6 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -5083,7 +4926,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5187,7 +5029,6 @@ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "peer": true, "engines": { "node": ">=14" } @@ -5202,7 +5043,6 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" @@ -5228,7 +5068,6 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", @@ -5251,7 +5090,6 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -5261,7 +5099,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", @@ -5283,7 +5120,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -5302,7 +5138,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -5321,7 +5156,6 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", @@ -5383,7 +5217,6 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -5393,7 +5226,6 @@ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" } @@ -5433,7 +5265,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", @@ -5448,7 +5279,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", "core-js-compat": "^3.43.0" @@ -5462,7 +5292,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, @@ -5533,8 +5362,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "peer": true + "dev": true }, "node_modules/brace-expansion": { "version": "2.0.2", @@ -5549,7 +5377,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "peer": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -5714,6 +5541,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -5781,7 +5609,6 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, - "peer": true, "engines": { "node": ">=6" }, @@ -5800,7 +5627,6 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.0.0" } @@ -5810,7 +5636,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -5828,7 +5653,6 @@ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.4.tgz", "integrity": "sha512-Gd7ccIUkZ9TE2odLQVS+PDjIvQCdJKUlLdJRVvZu0aipj07Qfx+XIej7hhDrKGGoIxV5m5fT/kOJNJPQhQneRg==", "dev": true, - "peer": true, "dependencies": { "hookified": "^1.11.0", "keyv": "^5.5.0" @@ -5839,7 +5663,6 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", "dev": true, - "peer": true, "dependencies": { "@keyv/serialize": "^1.1.0" } @@ -5895,7 +5718,6 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -5949,7 +5771,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6010,7 +5831,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -6066,8 +5886,7 @@ "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -6103,7 +5922,6 @@ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, - "peer": true, "engines": { "node": ">= 12.0.0" } @@ -6124,8 +5942,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/confbox": { "version": "0.2.2", @@ -6159,8 +5976,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/core-js": { "version": "3.37.0", @@ -6196,7 +6012,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, - "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -6320,7 +6135,6 @@ "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, - "peer": true, "engines": { "node": ">=12 || >=16" } @@ -6330,7 +6144,6 @@ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, - "peer": true, "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" @@ -6344,7 +6157,6 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "peer": true, "bin": { "cssesc": "bin/cssesc" }, @@ -6371,7 +6183,6 @@ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -6389,7 +6200,6 @@ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -6407,7 +6217,6 @@ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -6480,8 +6289,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/define-data-property": { "version": "1.1.4", @@ -6549,7 +6357,6 @@ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "optional": true, - "peer": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -6591,7 +6398,6 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "peer": true, "dependencies": { "path-type": "^4.0.0" }, @@ -6604,7 +6410,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -6617,7 +6422,6 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -6649,15 +6453,13 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "peer": true + ] }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "peer": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -6682,7 +6484,6 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, - "peer": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -6817,7 +6618,6 @@ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6827,7 +6627,6 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "peer": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -6837,7 +6636,6 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", @@ -6953,7 +6751,6 @@ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, - "peer": true, "dependencies": { "hasown": "^2.0.2" }, @@ -6966,7 +6763,6 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, - "peer": true, "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", @@ -7039,7 +6835,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -7109,7 +6904,6 @@ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.5.4" }, @@ -7125,7 +6919,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -7182,7 +6975,6 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -7194,7 +6986,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -7239,7 +7030,6 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, - "peer": true, "dependencies": { "debug": "^3.2.7" }, @@ -7257,7 +7047,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -7271,7 +7060,6 @@ "https://github.com/sponsors/ota-meshi", "https://opencollective.com/eslint" ], - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.11.0", @@ -7323,7 +7111,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7334,7 +7121,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -7344,7 +7130,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -7357,7 +7142,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7370,7 +7154,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.10.1.tgz", "integrity": "sha512-x8wxIpv00Y50NyweDUpa+58ffgSAI5sqe+zcZh33xphD0AVh+1kqr1ombaTRb7Fhpove1zfUuujlX9DWWBP5ag==", "dev": true, - "peer": true, "dependencies": { "@es-joy/jsdoccomment": "~0.41.0", "are-docs-informative": "^0.0.2", @@ -7394,7 +7177,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -7436,7 +7218,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7447,7 +7228,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7460,7 +7240,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -7512,7 +7291,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -7525,7 +7303,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -7539,7 +7316,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -7549,7 +7325,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7560,7 +7335,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -7577,7 +7351,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -7590,7 +7363,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -7600,7 +7372,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7613,7 +7384,6 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "peer": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -7631,7 +7401,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -7644,7 +7413,6 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, - "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -7657,7 +7425,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -7667,7 +7434,6 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -7680,7 +7446,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -7690,7 +7455,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -7724,7 +7488,6 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7784,7 +7547,6 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -7801,7 +7563,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "peer": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -7813,15 +7574,13 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fast-uri": { "version": "3.1.0", @@ -7861,7 +7620,6 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.9.1" } @@ -7871,7 +7629,6 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "peer": true, "dependencies": { "reusify": "^1.0.4" } @@ -7920,7 +7677,6 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -7933,7 +7689,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "peer": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7962,7 +7717,6 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, - "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -7976,8 +7730,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/floating-vue": { "version": "5.2.2", @@ -8108,8 +7861,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -8138,7 +7890,6 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -8159,7 +7910,6 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8169,7 +7919,6 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -8214,7 +7963,6 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -8232,7 +7980,6 @@ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, - "peer": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -8266,7 +8013,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -8279,7 +8025,6 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, - "peer": true, "dependencies": { "global-prefix": "^3.0.0" }, @@ -8292,7 +8037,6 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, - "peer": true, "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -8307,7 +8051,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -8320,7 +8063,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -8336,7 +8078,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, - "peer": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -8353,7 +8094,6 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "peer": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -8373,8 +8113,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/gopd": { "version": "1.2.0", @@ -8397,8 +8136,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/happy-dom": { "version": "20.3.1", @@ -8406,6 +8144,7 @@ "integrity": "sha512-tLvsizNno05Hij0PoB0QN/S8xf0YU2AGvO11/JlJDw5McA/gzyn0Ni1RwbTI1/zteUbOekJH0t6q8HFvjbxsGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "^20.0.0", "@types/whatwg-mimetype": "^3.0.2", @@ -8422,7 +8161,6 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -8456,7 +8194,6 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, - "peer": true, "dependencies": { "dunder-proto": "^1.0.0" }, @@ -8623,8 +8360,7 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.12.0.tgz", "integrity": "sha512-hMr1Y9TCLshScrBbV2QxJ9BROddxZ12MX9KsCtuGGy/3SmmN5H1PllKerrVlSotur9dlE8hmUKAOSa3WDzsZmQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/hot-patcher": { "version": "2.0.1", @@ -8636,7 +8372,6 @@ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" }, @@ -8656,7 +8391,6 @@ "url": "https://github.com/sponsors/fb55" } ], - "peer": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -8673,7 +8407,8 @@ "node_modules/ical.js": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.2.1.tgz", - "integrity": "sha512-yK/UlPbEs316igb/tjRgbFA8ZV75rCsBJp/hWOatpyaPNlgw0dGDmU+FoicOcwX4xXkeXOkYiOmCqNPFpNPkQg==" + "integrity": "sha512-yK/UlPbEs316igb/tjRgbFA8ZV75rCsBJp/hWOatpyaPNlgw0dGDmU+FoicOcwX4xXkeXOkYiOmCqNPFpNPkQg==", + "peer": true }, "node_modules/ieee754": { "version": "1.2.1", @@ -8700,7 +8435,6 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "peer": true, "engines": { "node": ">= 4" } @@ -8709,15 +8443,13 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, - "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -8743,7 +8475,6 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.19" } @@ -8754,7 +8485,6 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "peer": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -8782,7 +8512,6 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, - "peer": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", @@ -8846,7 +8575,6 @@ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -8863,15 +8591,13 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, - "peer": true, "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", @@ -8891,7 +8617,6 @@ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, - "peer": true, "dependencies": { "has-bigints": "^1.0.2" }, @@ -8907,7 +8632,6 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -8929,7 +8653,6 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, - "peer": true, "dependencies": { "builtin-modules": "^3.3.0" }, @@ -8945,7 +8668,6 @@ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.7.1" } @@ -8955,7 +8677,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -8995,7 +8716,6 @@ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", @@ -9013,7 +8733,6 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -9039,7 +8758,6 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9049,7 +8767,6 @@ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -9092,7 +8809,6 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "peer": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -9114,7 +8830,6 @@ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9143,7 +8858,6 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9156,7 +8870,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "peer": true, "engines": { "node": ">=0.12.0" } @@ -9166,7 +8879,6 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -9183,7 +8895,6 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -9204,7 +8915,6 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9232,7 +8942,6 @@ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9245,7 +8954,6 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -9261,7 +8969,6 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" @@ -9292,7 +8999,6 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", @@ -9325,7 +9031,6 @@ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9338,7 +9043,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3" }, @@ -9354,7 +9058,6 @@ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" @@ -9442,8 +9145,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/js-yaml": { "version": "4.1.1", @@ -9451,7 +9153,6 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -9464,7 +9165,6 @@ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, - "peer": true, "engines": { "node": ">=12.0.0" } @@ -9474,7 +9174,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -9486,36 +9185,31 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -9540,7 +9234,6 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -9550,7 +9243,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9559,8 +9251,7 @@ "version": "0.37.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/kolorist": { "version": "1.8.0", @@ -9578,7 +9269,6 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -9591,8 +9281,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/linkify-it": { "version": "5.0.0", @@ -9649,22 +9338,19 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/longest-streak": { "version": "3.1.0", @@ -9694,7 +9380,6 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "peer": true, "dependencies": { "yallist": "^3.0.2" } @@ -9757,7 +9442,6 @@ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true, - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9986,8 +9670,7 @@ "version": "2.12.2", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/mdurl": { "version": "2.0.0", @@ -10011,7 +9694,6 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "peer": true, "engines": { "node": ">= 8" } @@ -10442,7 +10124,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "peer": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -10456,7 +10137,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "peer": true, "engines": { "node": ">=8.6" }, @@ -10533,7 +10213,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10623,7 +10302,6 @@ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", "dev": true, - "peer": true, "bin": { "napi-postinstall": "lib/cli.js" }, @@ -10638,8 +10316,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nested-property": { "version": "4.0.0", @@ -10651,8 +10328,7 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "node_modules/node-domexception": { "version": "1.0.0", @@ -10760,7 +10436,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10770,7 +10445,6 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "peer": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -10840,7 +10514,6 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10859,7 +10532,6 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10874,7 +10546,6 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -10904,7 +10575,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "peer": true, "dependencies": { "wrappy": "1" } @@ -10914,7 +10584,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, - "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -10938,7 +10607,6 @@ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", @@ -11038,7 +10706,6 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -11091,7 +10758,6 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -11125,7 +10791,6 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11177,7 +10842,6 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -11303,6 +10967,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -11317,7 +10982,6 @@ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.8.0.tgz", "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==", "dev": true, - "peer": true, "dependencies": { "htmlparser2": "^8.0.0", "js-tokens": "^9.0.0", @@ -11332,29 +10996,25 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, - "peer": true, "engines": { "node": ">=12.0" }, @@ -11385,7 +11045,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "engines": { "node": ">=12.0" }, @@ -11398,7 +11057,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -11411,15 +11069,13 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -11560,8 +11216,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/randombytes": { "version": "2.1.0", @@ -11601,7 +11256,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -11615,7 +11269,6 @@ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -11637,15 +11290,13 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regenerate-unicode-properties": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, - "peer": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -11658,7 +11309,6 @@ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", @@ -11679,7 +11329,6 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, - "peer": true, "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", @@ -11696,15 +11345,13 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/regjsparser": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, - "peer": true, "dependencies": { "jsesc": "~3.0.2" }, @@ -11717,7 +11364,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -11841,7 +11487,6 @@ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.5" } @@ -11876,7 +11521,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -11886,7 +11530,6 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -11896,7 +11539,6 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -11906,7 +11548,6 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "peer": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -11918,7 +11559,6 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -11934,7 +11574,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -11946,7 +11585,6 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11967,7 +11605,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11990,6 +11627,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.0.tgz", "integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -12122,7 +11760,6 @@ "url": "https://feross.org/support" } ], - "peer": true, "dependencies": { "queue-microtask": "^1.2.2" } @@ -12132,7 +11769,6 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -12172,7 +11808,6 @@ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, - "peer": true, "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" @@ -12232,7 +11867,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -12259,7 +11893,6 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, - "peer": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -12275,7 +11908,6 @@ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", "dev": true, - "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", @@ -12427,7 +12059,6 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -12437,7 +12068,6 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -12608,8 +12238,7 @@ "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stackback": { "version": "0.0.2", @@ -12629,7 +12258,6 @@ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, - "peer": true, "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" @@ -12748,7 +12376,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -12770,7 +12397,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", @@ -12789,7 +12415,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -12845,7 +12470,6 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -12977,7 +12601,6 @@ "resolved": "https://registry.npmjs.org/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz", "integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==", "dev": true, - "peer": true, "engines": { "node": "^12 || >=14" }, @@ -13004,7 +12627,6 @@ "url": "https://github.com/sponsors/stylelint" } ], - "peer": true, "engines": { "node": ">=18.12.0" }, @@ -13041,7 +12663,6 @@ "resolved": "https://registry.npmjs.org/stylelint-config-recommended-vue/-/stylelint-config-recommended-vue-1.6.1.tgz", "integrity": "sha512-lLW7hTIMBiTfjenGuDq2kyHA6fBWd/+Df7MO4/AWOxiFeXP9clbpKgg27kHfwA3H7UNMGC7aeP3mNlZB5LMmEQ==", "dev": true, - "peer": true, "dependencies": { "semver": "^7.3.5", "stylelint-config-html": ">=1.0.0", @@ -13063,7 +12684,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -13076,7 +12696,6 @@ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.12.1.tgz", "integrity": "sha512-UJUfBFIvXfly8WKIgmqfmkGKPilKB4L5j38JfsDd+OCg2GBdU0vGUV08Uw82tsRZzd4TbsUURVVNGeOhJVF7pA==", "dev": true, - "peer": true, "dependencies": { "css-tree": "^3.0.1", "is-plain-object": "^5.0.0", @@ -13098,22 +12717,19 @@ "version": "0.36.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.36.0.tgz", "integrity": "sha512-A+9jP+IUmuQsNdsLdcg6Yt7voiMF/D4K83ew0OpJtpu+l34ef7LaohWV0Rc6KNvzw6ZDizkqfyB5JznZnzuKQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stylelint-scss/node_modules/mdn-data": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.24.0.tgz", "integrity": "sha512-i97fklrJl03tL1tdRVw0ZfLLvuDsdb6wxL+TrJ+PKkCbLrp2PCu2+OYdCKychIUm19nSM/35S6qz7pJpnXttoA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stylelint-scss/node_modules/postcss-selector-parser": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13149,7 +12765,6 @@ "url": "https://opencollective.com/csstools" } ], - "peer": true, "engines": { "node": ">=18" }, @@ -13161,22 +12776,19 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stylelint/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "10.1.4", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.4.tgz", "integrity": "sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==", "dev": true, - "peer": true, "dependencies": { "flat-cache": "^6.1.13" } @@ -13186,7 +12798,6 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.13.tgz", "integrity": "sha512-gmtS2PaUjSPa4zjObEIn4WWliKyZzYljgxODBfxugpK6q6HU9ClXzgCJ+nlcPKY9Bt090ypTOLIFWkV0jbKFjw==", "dev": true, - "peer": true, "dependencies": { "cacheable": "^1.10.4", "flatted": "^3.3.3", @@ -13198,7 +12809,6 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, - "peer": true, "engines": { "node": ">= 4" } @@ -13222,7 +12832,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "engines": { "node": ">=18.0" }, @@ -13249,7 +12858,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -13259,7 +12867,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13274,7 +12881,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -13287,7 +12893,6 @@ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -13315,8 +12920,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tabbable": { "version": "6.4.0", @@ -13329,7 +12933,6 @@ "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, - "peer": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -13346,7 +12949,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -13362,22 +12964,19 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "peer": true + "dev": true }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "peer": true + "dev": true }, "node_modules/table/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13391,8 +12990,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/timers-browserify": { "version": "2.0.12", @@ -13467,7 +13065,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "peer": true, "dependencies": { "is-number": "^7.0.0" }, @@ -13508,7 +13105,6 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, - "peer": true, "engines": { "node": ">=16" }, @@ -13529,7 +13125,6 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, - "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -13542,7 +13137,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -13555,8 +13149,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "node_modules/tty-browserify": { "version": "0.0.1", @@ -13569,7 +13162,6 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -13582,7 +13174,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, @@ -13609,7 +13200,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", @@ -13629,7 +13219,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -13651,7 +13240,6 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -13702,7 +13290,6 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", @@ -13727,7 +13314,6 @@ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -13737,7 +13323,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "peer": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -13751,7 +13336,6 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -13761,7 +13345,6 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -13887,7 +13470,6 @@ "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", "dev": true, "hasInstallScript": true, - "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, @@ -14041,6 +13623,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", "dev": true, + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -14256,6 +13839,7 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.26", "@vue/compiler-sfc": "3.5.26", @@ -14283,7 +13867,6 @@ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.3.4", "eslint-scope": "^7.1.1", @@ -14308,7 +13891,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -14325,7 +13907,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -14338,7 +13919,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -14348,7 +13928,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -14475,7 +14054,6 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, - "peer": true, "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", @@ -14495,7 +14073,6 @@ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, - "peer": true, "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", @@ -14523,7 +14100,6 @@ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, - "peer": true, "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -14579,7 +14155,6 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14682,15 +14257,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -14726,7 +14299,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -14744,8 +14316,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/yocto-queue": { "version": "0.1.0", diff --git a/src/components/AppSidebar/RecurrenceItem.vue b/src/components/AppSidebar/RecurrenceItem.vue new file mode 100644 index 000000000..039fee91c --- /dev/null +++ b/src/components/AppSidebar/RecurrenceItem.vue @@ -0,0 +1,558 @@ + + + + + + + diff --git a/src/components/Repeat/Repeat.vue b/src/components/Repeat/Repeat.vue new file mode 100644 index 000000000..5d03bd8d1 --- /dev/null +++ b/src/components/Repeat/Repeat.vue @@ -0,0 +1,504 @@ + + + + + + + diff --git a/src/components/Repeat/RepeatEndRepeat.vue b/src/components/Repeat/RepeatEndRepeat.vue new file mode 100644 index 000000000..77682403a --- /dev/null +++ b/src/components/Repeat/RepeatEndRepeat.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/components/Repeat/RepeatExceptionWarning.vue b/src/components/Repeat/RepeatExceptionWarning.vue new file mode 100644 index 000000000..d9c094245 --- /dev/null +++ b/src/components/Repeat/RepeatExceptionWarning.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/src/components/Repeat/RepeatFirstLastSelect.vue b/src/components/Repeat/RepeatFirstLastSelect.vue new file mode 100644 index 000000000..0c9632673 --- /dev/null +++ b/src/components/Repeat/RepeatFirstLastSelect.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/components/Repeat/RepeatForkWarning.vue b/src/components/Repeat/RepeatForkWarning.vue new file mode 100644 index 000000000..2c99ed8f0 --- /dev/null +++ b/src/components/Repeat/RepeatForkWarning.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/src/components/Repeat/RepeatFreqInterval.vue b/src/components/Repeat/RepeatFreqInterval.vue new file mode 100644 index 000000000..3bda58783 --- /dev/null +++ b/src/components/Repeat/RepeatFreqInterval.vue @@ -0,0 +1,89 @@ + + + + + + + diff --git a/src/components/Repeat/RepeatFreqMonthlyOptions.vue b/src/components/Repeat/RepeatFreqMonthlyOptions.vue new file mode 100644 index 000000000..f2908aa92 --- /dev/null +++ b/src/components/Repeat/RepeatFreqMonthlyOptions.vue @@ -0,0 +1,206 @@ + + + + + + + diff --git a/src/components/Repeat/RepeatFreqSelect.vue b/src/components/Repeat/RepeatFreqSelect.vue new file mode 100644 index 000000000..f2ed0e5bf --- /dev/null +++ b/src/components/Repeat/RepeatFreqSelect.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/components/Repeat/RepeatFreqWeeklyOptions.vue b/src/components/Repeat/RepeatFreqWeeklyOptions.vue new file mode 100644 index 000000000..5919fed9e --- /dev/null +++ b/src/components/Repeat/RepeatFreqWeeklyOptions.vue @@ -0,0 +1,115 @@ + + + + + + + diff --git a/src/components/Repeat/RepeatFreqYearlyOptions.vue b/src/components/Repeat/RepeatFreqYearlyOptions.vue new file mode 100644 index 000000000..d2b3a9797 --- /dev/null +++ b/src/components/Repeat/RepeatFreqYearlyOptions.vue @@ -0,0 +1,250 @@ + + + + + + + diff --git a/src/components/Repeat/RepeatOnTheSelect.vue b/src/components/Repeat/RepeatOnTheSelect.vue new file mode 100644 index 000000000..2295f5706 --- /dev/null +++ b/src/components/Repeat/RepeatOnTheSelect.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/src/components/Repeat/RepeatSummary.vue b/src/components/Repeat/RepeatSummary.vue new file mode 100644 index 000000000..b0bce1d68 --- /dev/null +++ b/src/components/Repeat/RepeatSummary.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/components/Repeat/RepeatUnsupportedWarning.vue b/src/components/Repeat/RepeatUnsupportedWarning.vue new file mode 100644 index 000000000..4f516a4b8 --- /dev/null +++ b/src/components/Repeat/RepeatUnsupportedWarning.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/src/components/TaskBody.vue b/src/components/TaskBody.vue index 6b0848504..bf6978419 100644 --- a/src/components/TaskBody.vue +++ b/src/components/TaskBody.vue @@ -75,13 +75,14 @@ License along with this library. If not, see . + -
+
{{ dueDateShort }} {{ dueDateLong }}
@@ -212,6 +213,7 @@ import Plus from 'vue-material-design-icons/Plus.vue' import TextBoxOutline from 'vue-material-design-icons/TextBoxOutline.vue' import SortVariant from 'vue-material-design-icons/SortVariant.vue' import CalendarClock from 'vue-material-design-icons/CalendarClock.vue' +import Repeat from 'vue-material-design-icons/Repeat.vue' import Star from 'vue-material-design-icons/StarOutline.vue' import Undo from 'vue-material-design-icons/Undo.vue' @@ -244,6 +246,7 @@ export default { TextBoxOutline, SortVariant, CalendarClock, + Repeat, Star, Undo, }, @@ -275,9 +278,10 @@ export default { }), dueDateShort() { + const taskDate = this.task.startMoment.isValid() ? this.task.startMoment : this.task.dueMoment if (!this.task.completed) { - return this.task.dueMoment.isValid() - ? this.task.dueMoment.calendar(null, { + return taskDate.isValid() + ? taskDate.calendar(null, { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Yesterday]'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. @@ -313,9 +317,10 @@ export default { if (this.task.allDay) { return this.dueDateShort } + const taskDate = this.task.startMoment.isValid() ? this.task.startMoment : this.task.dueMoment if (!this.task.completed) { - return this.task.dueMoment.isValid() - ? this.task.dueMoment.calendar(null, { + return taskDate.isValid() + ? taskDate.calendar(null, { // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. lastDay: t('tasks', '[Yesterday at] LT'), // TRANSLATORS This is a string for moment.js. The square brackets escape the string from moment.js. Please translate the string and keep the brackets. diff --git a/src/filters/recurrenceRuleFormat.js b/src/filters/recurrenceRuleFormat.js new file mode 100644 index 000000000..c5f62dcc4 --- /dev/null +++ b/src/filters/recurrenceRuleFormat.js @@ -0,0 +1,173 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { translate as t, translatePlural as n } from '@nextcloud/l10n' + +/** + * Get translated ordinal number (first, second, third, etc.) + * + * @param {number} ordinal The ordinal number (1-5 for first-fifth, -1 for last, -2 for second to last) + * @return {string} Translated ordinal string + */ +export function getTranslatedOrdinalNumber(ordinal) { + switch (ordinal) { + case 1: + return t('tasks', 'first') + case 2: + return t('tasks', 'second') + case 3: + return t('tasks', 'third') + case 4: + return t('tasks', 'fourth') + case 5: + return t('tasks', 'fifth') + case -1: + return t('tasks', 'last') + case -2: + return t('tasks', 'second to last') + default: + return String(ordinal) + } +} + +/** + * Get translated frequency string + * + * @param {string} frequency The frequency (DAILY, WEEKLY, MONTHLY, YEARLY) + * @param {number} interval The interval + * @return {string} Translated frequency string + */ +function getTranslatedFrequency(frequency, interval) { + switch (frequency) { + case 'DAILY': + return n('tasks', 'day', 'days', interval) + case 'WEEKLY': + return n('tasks', 'week', 'weeks', interval) + case 'MONTHLY': + return n('tasks', 'month', 'months', interval) + case 'YEARLY': + return n('tasks', 'year', 'years', interval) + default: + return frequency + } +} + +/** + * Get translated day name + * + * @param {string} day The day abbreviation (MO, TU, WE, TH, FR, SA, SU) + * @return {string} Translated day name + */ +function getTranslatedDayName(day) { + const dayNames = { + MO: t('tasks', 'Monday'), + TU: t('tasks', 'Tuesday'), + WE: t('tasks', 'Wednesday'), + TH: t('tasks', 'Thursday'), + FR: t('tasks', 'Friday'), + SA: t('tasks', 'Saturday'), + SU: t('tasks', 'Sunday'), + } + return dayNames[day] || day +} + +/** + * Get translated month name + * + * @param {number} month The month number (1-12) + * @return {string} Translated month name + */ +function getTranslatedMonthName(month) { + const monthNames = [ + t('tasks', 'January'), + t('tasks', 'February'), + t('tasks', 'March'), + t('tasks', 'April'), + t('tasks', 'May'), + t('tasks', 'June'), + t('tasks', 'July'), + t('tasks', 'August'), + t('tasks', 'September'), + t('tasks', 'October'), + t('tasks', 'November'), + t('tasks', 'December'), + ] + return monthNames[month - 1] || String(month) +} + +/** + * Format a recurrence rule into a human-readable string + * + * @param {object} recurrenceRule The recurrence rule object + * @param {string} locale The locale (unused, kept for API compatibility) + * @return {string} Human-readable recurrence description + */ +export default function formatRecurrenceRule(recurrenceRule, locale) { + if (!recurrenceRule || recurrenceRule.frequency === 'NONE') { + return t('tasks', 'Does not repeat') + } + + const { frequency, interval, byDay, byMonthDay, byMonth, bySetPosition, count, until } = recurrenceRule + + let result = '' + + // Build the base frequency string + if (interval === 1) { + switch (frequency) { + case 'DAILY': + result = t('tasks', 'Daily') + break + case 'WEEKLY': + result = t('tasks', 'Weekly') + break + case 'MONTHLY': + result = t('tasks', 'Monthly') + break + case 'YEARLY': + result = t('tasks', 'Yearly') + break + default: + result = frequency + } + } else { + result = t('tasks', 'Every {interval} {frequency}', { + interval, + frequency: getTranslatedFrequency(frequency, interval), + }) + } + + // Add by-day information for weekly + if (frequency === 'WEEKLY' && byDay && byDay.length > 0) { + const dayNames = byDay.map(getTranslatedDayName).join(', ') + result += ' ' + t('tasks', 'on {days}', { days: dayNames }) + } + + // Add by-month-day or by-set-position information for monthly + if (frequency === 'MONTHLY') { + if (byMonthDay && byMonthDay.length > 0) { + result += ' ' + t('tasks', 'on day {days}', { days: byMonthDay.join(', ') }) + } else if (bySetPosition !== null && byDay && byDay.length > 0) { + const ordinal = getTranslatedOrdinalNumber(bySetPosition) + const dayNames = byDay.map(getTranslatedDayName).join(', ') + result += ' ' + t('tasks', 'on the {ordinal} {dayNames}', { ordinal, dayNames }) + } + } + + // Add by-month information for yearly + if (frequency === 'YEARLY' && byMonth && byMonth.length > 0) { + const monthNames = byMonth.map(getTranslatedMonthName).join(', ') + result += ' ' + t('tasks', 'in {months}', { months: monthNames }) + } + + // Add end condition + if (count !== null) { + result += ', ' + n('tasks', '{count} time', '{count} times', count, { count }) + } else if (until !== null) { + const untilDate = until instanceof Date ? until : new Date(until) + result += ', ' + t('tasks', 'until {date}', { date: untilDate.toLocaleDateString() }) + } + + return result +} diff --git a/src/models/recurrenceRule.js b/src/models/recurrenceRule.js new file mode 100644 index 000000000..1a0d893ca --- /dev/null +++ b/src/models/recurrenceRule.js @@ -0,0 +1,518 @@ +/** + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +import { getWeekDayFromDate } from '../utils/recurrence.js' + +/** + * Converts a DateTimeValue to a JavaScript Date object + * + * @param {object} dateTimeValue The DateTimeValue object + * @return {Date} + */ +function getDateFromDateTimeValue(dateTimeValue) { + return new Date( + dateTimeValue.year, + dateTimeValue.month - 1, + dateTimeValue.day, + dateTimeValue.hour, + dateTimeValue.minute, + 0, + 0, + ) +} + +/** + * Creates a complete recurrence-rule-object based on given props + * + * @param {object} props Recurrence-rule-object-props already provided + * @return {object} + */ +function getDefaultRecurrenceRuleObject(props = {}) { + return { // The calendar-js recurrence-rule value + recurrenceRuleValue: null, + // The frequency of the recurrence-rule (DAILY, WEEKLY, ...) + frequency: 'NONE', + // The interval of the recurrence-rule, must be a positive integer + interval: 1, + // Positive integer if recurrence-rule limited by count, null otherwise + count: null, + // Date if recurrence-rule limited by date, null otherwise + // We do not store a timezone here, since we only care about the date part + until: null, + // List of byDay components to limit/expand the recurrence-rule + byDay: [], + // List of byMonth components to limit/expand the recurrence-rule + byMonth: [], + // List of byMonthDay components to limit/expand the recurrence-rule + byMonthDay: [], + // A position to limit the recurrence-rule (e.g. -1 for last Friday) + bySetPosition: null, + // Whether or not the rule is not supported for editing + isUnsupported: false, + ...props, + } +} + +/** + * Maps a calendar-js recurrence-rule-value to an recurrence-rule-object + * + * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value + * @param {DateTimeValue} baseDate The base-date used to fill unset values + * @return {object} + */ +function mapRecurrenceRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) { + switch (recurrenceRuleValue.frequency) { + case 'DAILY': + return mapDailyRuleValueToRecurrenceRuleObject(recurrenceRuleValue) + + case 'WEEKLY': + return mapWeeklyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) + + case 'MONTHLY': + return mapMonthlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) + + case 'YEARLY': + return mapYearlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) + + default: // SECONDLY, MINUTELY, HOURLY + return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, { + isUnsupported: true, + }) + } +} + +const FORBIDDEN_BY_PARTS_DAILY = [ + 'BYSECOND', + 'BYMINUTE', + 'BYHOUR', + 'BYDAY', + 'BYMONTHDAY', + 'BYYEARDAY', + 'BYWEEKNO', + 'BYMONTH', + 'BYSETPOS', +] +const FORBIDDEN_BY_PARTS_WEEKLY = [ + 'BYSECOND', + 'BYMINUTE', + 'BYHOUR', + 'BYMONTHDAY', + 'BYYEARDAY', + 'BYWEEKNO', + 'BYMONTH', + 'BYSETPOS', +] +const FORBIDDEN_BY_PARTS_MONTHLY = [ + 'BYSECOND', + 'BYMINUTE', + 'BYHOUR', + 'BYYEARDAY', + 'BYWEEKNO', + 'BYMONTH', +] +const FORBIDDEN_BY_PARTS_YEARLY = [ + 'BYSECOND', + 'BYMINUTE', + 'BYHOUR', + 'BYYEARDAY', + 'BYWEEKNO', +] + +const SUPPORTED_BY_DAY_WEEKLY = [ + 'SU', + 'MO', + 'TU', + 'WE', + 'TH', + 'FR', + 'SA', +] + +const SUPPORTED_BY_MONTHDAY_MONTHLY = [...Array(31).keys().map((i) => i + 1)] + +const SUPPORTED_BY_MONTH_YEARLY = [...Array(12).keys().map((i) => i + 1)] + +/** + * Maps a daily calendar-js recurrence-rule-value to an recurrence-rule-object + * + * @param recurrenceRuleValue + * @return {object} + */ +function mapDailyRuleValueToRecurrenceRuleObject(recurrenceRuleValue) { + /** + * We only support DAILY rules without any by-parts in the editor. + * If the recurrence-rule contains any by-parts, mark it as unsupported. + */ + const isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_DAILY) + + return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, { + isUnsupported, + }) +} + +/** + * Maps a weekly calendar-js recurrence-rule-value to an recurrence-rule-object + * + * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value + * @param {DateTimeValue} baseDate The base-date used to fill unset values + * @return {object} + */ +function mapWeeklyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) { + /** + * For WEEKLY recurrences, our editor only allows BYDAY + * + * As defined in RFC5545 3.3.10. Recurrence Rule: + * > Each BYDAY value can also be preceded by a positive (+n) or + * > negative (-n) integer. If present, this indicates the nth + * > occurrence of a specific day within the MONTHLY or YEARLY "RRULE". + * + * RFC 5545 specifies other components, which can be used along WEEKLY. + * Among them are BYMONTH and BYSETPOS. We don't support those. + */ + const containsUnsupportedByParts = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_WEEKLY) + const containsInvalidByDayPart = recurrenceRuleValue.getComponent('BYDAY') + .some((weekday) => !SUPPORTED_BY_DAY_WEEKLY.includes(weekday)) + + const isUnsupported = containsUnsupportedByParts || containsInvalidByDayPart + + const byDay = recurrenceRuleValue.getComponent('BYDAY') + .filter((weekday) => SUPPORTED_BY_DAY_WEEKLY.includes(weekday)) + + // If the BYDAY is empty, add the day that the task occurs in + // E.g. if the task is on a Wednesday, automatically set BYDAY:WE + if (byDay.length === 0) { + byDay.push(getWeekDayFromDate(baseDate.jsDate)) + } + + return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, { + byDay, + isUnsupported, + }) +} + +/** + * Maps a monthly calendar-js recurrence-rule-value to an recurrence-rule-object + * + * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value + * @param {DateTimeValue} baseDate The base-date used to fill unset values + * @return {object} + */ +function mapMonthlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) { + /** + * We only supports BYMONTHDAY, BYDAY, BYSETPOS in order to expand the monthly rule. + * It supports either BYMONTHDAY or the combination of BYDAY and BYSETPOS. They have to be used exclusively + * and cannot be combined. + * + * We do not support other BY-parts like BYMONTH + * + * For monthly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers. + * The Nextcloud-editor supports at most one BYDAY component with an integer. + * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS. + * e.g. + * BYDAY=3WE => BYDAY=WE,BYSETPOS=3 + * + * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5 + * Other values are not supported + * + * BYDAY is limited to "MO", "TU", "WE", "TH", "FR", "SA", "SU", + * "MO,TU,WE,TH,FR,SA,SU", "MO,TU,WE,TH,FR", "SA,SU" + * + * BYMONTHDAY is limited to "1", "2", ..., "31" + */ + let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_MONTHLY) + + let byDay = [] + let bySetPosition = null + let byMonthDay = [] + + // This handles the first case, where we have a BYMONTHDAY rule + if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTHDAY'])) { + // verify there is no BYDAY or BYSETPOS at the same time + if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY', 'BYSETPOS'])) { + isUnsupported = true + } + + const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY') + .some((monthDay) => !SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay)) + isUnsupported = isUnsupported || containsInvalidByMonthDay + + byMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY') + .filter((monthDay) => SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay)) + .map((monthDay) => monthDay) + + // This handles cases where we have both BYDAY and BYSETPOS + } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) { + if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) { + byDay = recurrenceRuleValue.getComponent('BYDAY') + } else { + byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'] + isUnsupported = true + } + + const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS') + if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) { + bySetPosition = setPositionArray[0] + } else { + bySetPosition = 1 + isUnsupported = true + } + + // This handles cases where we only have a BYDAY + } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) { + const byDayArray = recurrenceRuleValue.getComponent('BYDAY') + + if (byDayArray.length > 1) { + byMonthDay.push(baseDate.day) + isUnsupported = true + } else { + const firstElement = byDayArray[0] + + const match = /^(-?\d)([A-Z]{2})$/.exec(firstElement) + if (match) { + const matchedBySetPosition = match[1] + const matchedByDay = match[2] + + if (isAllowedBySetPos(matchedBySetPosition)) { + byDay = [matchedByDay] + bySetPosition = parseInt(matchedBySetPosition, 10) + } else { + byDay = [matchedByDay] + bySetPosition = 1 + isUnsupported = true + } + } else { + byMonthDay.push(baseDate.day) + isUnsupported = true + } + } + + // This is a fallback where we just default BYMONTHDAY to the start date of the event + } else { + byMonthDay.push(baseDate.day) + } + + return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, { + byDay, + bySetPosition, + byMonthDay, + isUnsupported, + }) +} + +/** + * Maps a yearly calendar-js recurrence-rule-value to an recurrence-rule-object + * + * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value + * @param {DateTimeValue} baseDate The base-date used to fill unset values + * @return {object} + */ +function mapYearlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate) { + /** + * We only supports BYMONTH, BYDAY, BYSETPOS in order to expand the yearly rule. + * It supports a combination of them. + * + * We do not support other BY-parts. + * + * For yearly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers. + * The Nextcloud-editor supports at most one BYDAY component with an integer. + * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS. + * e.g. + * BYDAY=3WE => BYDAY=WE,BYSETPOS=3 + * + * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5 + * Other values are not supported + * + * BYDAY is limited to "MO", "TU", "WE", "TH", "FR", "SA", "SU", + * "MO,TU,WE,TH,FR,SA,SU", "MO,TU,WE,TH,FR", "SA,SU" + */ + let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_YEARLY) + + let byDay = [] + let bySetPosition = null + let byMonth = [] + let byMonthDay = [] + + if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTH'])) { + // This handles the first case, where we have a BYMONTH rule + + const containsInvalidByMonth = recurrenceRuleValue.getComponent('BYMONTH') + .some((month) => !SUPPORTED_BY_MONTH_YEARLY.includes(month)) + isUnsupported = isUnsupported || containsInvalidByMonth + + byMonth = recurrenceRuleValue.getComponent('BYMONTH') + .filter((month) => SUPPORTED_BY_MONTH_YEARLY.includes(month)) + .map((month) => month) + } else { + // This is a fallback where we just default BYMONTH to the start date of the event + + byMonth.push(baseDate.month) + } + + if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTHDAY'])) { + // This handles the first case, where we have a BYMONTHDAY rule + + // verify there is no BYDAY or BYSETPOS at the same time + if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY', 'BYSETPOS'])) { + isUnsupported = true + } + + const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY') + .some((monthDay) => !SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay)) + isUnsupported = isUnsupported || containsInvalidByMonthDay + + byMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY') + .filter((monthDay) => SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay)) + .map((monthDay) => monthDay) + } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) { + // This handles cases where we have both BYDAY and BYSETPOS + + if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) { + byDay = recurrenceRuleValue.getComponent('BYDAY') + } else { + byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'] + isUnsupported = true + } + + const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS') + if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) { + bySetPosition = setPositionArray[0] + } else { + bySetPosition = 1 + isUnsupported = true + } + } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) { + // This handles cases where we only have a BYDAY + + const byDayArray = recurrenceRuleValue.getComponent('BYDAY') + + if (byDayArray.length > 1) { + byMonthDay.push(baseDate.day) + isUnsupported = true + } else { + const firstElement = byDayArray[0] + + const match = /^(-?\d)([A-Z]{2})$/.exec(firstElement) + if (match) { + const matchedBySetPosition = match[1] + const matchedByDay = match[2] + + if (isAllowedBySetPos(matchedBySetPosition)) { + byDay = [matchedByDay] + bySetPosition = parseInt(matchedBySetPosition, 10) + } else { + byDay = [matchedByDay] + bySetPosition = 1 + isUnsupported = true + } + } else { + byMonthDay.push(baseDate.day) + isUnsupported = true + } + } + } else { + // This is a fallback where we just default BYMONTHDAY to the start date of the event + byMonthDay.push(baseDate.day) + } + + return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, { + byDay, + bySetPosition, + byMonth, + byMonthDay, + isUnsupported, + }) +} + +/** + * Checks if the given parameter is a supported BYDAY value + * + * @param {string[]} byDay The byDay component to check + * @return {boolean} + */ +function isAllowedByDay(byDay) { + return [ + 'MO', + 'TU', + 'WE', + 'TH', + 'FR', + 'SA', + 'SU', + 'FR,MO,SA,SU,TH,TU,WE', + 'FR,MO,TH,TU,WE', + 'SA,SU', + ].includes(byDay.slice().sort().join(',')) +} + +/** + * Checks if the given parameter is a supported BYSETPOS value + * + * @param {string} bySetPos The bySetPos component to check + * @return {boolean} + */ +function isAllowedBySetPos(bySetPos) { + return [ + '-2', + '-1', + '1', + '2', + '3', + '4', + '5', + ].includes(bySetPos.toString()) +} + +/** + * Checks if the recurrence-rule contains any of the given components + * + * @param {RecurValue} recurrenceRule The recurrence-rule value to check for the given components + * @param {string[]} components List of components to check for + * @return {boolean} + */ +function containsRecurrenceComponent(recurrenceRule, components) { + for (const component of components) { + const componentValue = recurrenceRule.getComponent(component) + if (componentValue.length > 0) { + return true + } + } + + return false +} + +/** + * Returns a full recurrence-rule-object with default values derived from recurrenceRuleValue + * and additional props + * + * @param {RecurValue} recurrenceRuleValue The recurrence-rule value to get default values from + * @param {object} props The properties to provide on top of default one + * @return {object} + */ +function getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, props) { + const isUnsupported = recurrenceRuleValue.count !== null && recurrenceRuleValue.until !== null + let isUnsupportedProps = {} + + if (isUnsupported) { + isUnsupportedProps = { + isUnsupported, + } + } + + return getDefaultRecurrenceRuleObject({ + recurrenceRuleValue, + frequency: recurrenceRuleValue.frequency, + interval: parseInt(recurrenceRuleValue.interval, 10) || 1, + count: recurrenceRuleValue.count, + until: recurrenceRuleValue.until + ? getDateFromDateTimeValue(recurrenceRuleValue.until) + : null, + ...props, + ...isUnsupportedProps, + }) +} + +export { + getDefaultRecurrenceRuleObject, + mapRecurrenceRuleValueToRecurrenceRuleObject, +} diff --git a/src/models/task.js b/src/models/task.js index e3652b25b..242c793c4 100644 --- a/src/models/task.js +++ b/src/models/task.js @@ -27,7 +27,12 @@ import moment from '@nextcloud/moment' import ICAL from 'ical.js' +import { RecurValue, DateTimeValue } from '@nextcloud/calendar-js' import { randomUUID } from '../utils/crypto.js' +import { + getDefaultRecurrenceRuleObject, + mapRecurrenceRuleValueToRecurrenceRuleObject, +} from './recurrenceRule.js' export default class Task { @@ -121,6 +126,40 @@ export default class Task { this._location = this.vtodo.getFirstPropertyValue('location') || '' this._customUrl = this.vtodo.getFirstPropertyValue('url') || '' + // Check for RECURRENCE-ID property (this is an exception instance) + this._recurrenceId = this.vtodo.getFirstPropertyValue('recurrence-id') + + // Extract recurrence-rule only if this is NOT an exception instance + if (this.vtodo && !this._recurrenceId) { + const recurrenceRules = this.vtodo.getAllProperties('rrule') + const firstRecurrenceRule = recurrenceRules?.[0] + + if (firstRecurrenceRule) { + try { + // Get the ICAL.Recur value and convert directly to RecurValue + const icalRecur = firstRecurrenceRule.getFirstValue() + const recurValue = RecurValue.fromICALJs(icalRecur) + + // Get reference date for the mapping function + const referenceDate = this._due || this._start + const jsDate = referenceDate?.toJSDate() || null + + this._recurrenceRule = mapRecurrenceRuleValueToRecurrenceRuleObject(recurValue, jsDate) + this._hasMultipleRRules = recurrenceRules.length > 1 + } catch (e) { + console.warn('Failed to parse recurrence rule:', e) + this._recurrenceRule = getDefaultRecurrenceRuleObject() + this._hasMultipleRRules = false + } + } + } + + // Set default if not already set + if (!this._recurrenceRule) { + this._recurrenceRule = getDefaultRecurrenceRuleObject() + this._hasMultipleRRules = false + } + let sortOrder = this.vtodo.getFirstPropertyValue('x-apple-sort-order') if (sortOrder === null) { sortOrder = this.getSortOrder() @@ -502,6 +541,12 @@ export default class Task { this.vtodo.updatePropertyWithValue('dtstart', start) } else { this.vtodo.removeProperty('dtstart') + // Remove RRULE when start date is removed (if no due date exists) + if (!this._due) { + this.vtodo.removeAllProperties('rrule') + this._recurrenceRule = getDefaultRecurrenceRuleObject() + this._hasMultipleRRules = false + } } this._start = start this._startMoment = moment(start, 'YYYYMMDDTHHmmssZ') @@ -528,6 +573,12 @@ export default class Task { this.vtodo.updatePropertyWithValue('due', due) } else { this.vtodo.removeProperty('due') + // Remove RRULE when due date is removed (if no start date exists) + if (!this._start) { + this.vtodo.removeAllProperties('rrule') + this._recurrenceRule = getDefaultRecurrenceRuleObject() + this._hasMultipleRRules = false + } } this._due = due this._dueMoment = moment(due, 'YYYYMMDDTHHmmssZ') @@ -771,6 +822,76 @@ export default class Task { this._sortOrder = sortOrder } + /** + * Gets the recurrence rule + * + * @return {object} The recurrence rule + */ + get recurrenceRule() { + return this._recurrenceRule + } + + /** + * Sets the recurrence rule + * + * @param {object} recurrenceRule The recurrence rule + */ + set recurrenceRule(recurrenceRule) { + // Auto-set DTSTART if no date exists (Thunderbird compatibility) + if (!this._start && !this._due && recurrenceRule.frequency !== 'NONE') { + const now = ICAL.Time.now() + now.isDate = true // Make it all-day by default + this.setStart(now) + } + this._recurrenceRule = recurrenceRule + } + + /** + * Checks if the task is recurring + * + * @return {boolean} True if recurring + */ + get isRecurring() { + return this._recurrenceRule && this._recurrenceRule.frequency !== 'NONE' + } + + /** + * Checks if the task has multiple recurrence rules + * + * @return {boolean} True if has multiple RRULEs + */ + get hasMultipleRRules() { + return this._hasMultipleRRules + } + + /** + * Returns the recurrence ID of this task (if it's an exception instance) + * + * @return {ICAL.Time|null} + */ + get recurrenceId() { + return this._recurrenceId + } + + /** + * Checks if this task is a recurring exception instance + * + * @return {boolean} + */ + get isRecurrenceException() { + return this._recurrenceId !== null + } + + /** + * Checks if a recurrence exception can be created for this task + * + * @return {boolean} True if exception can be created + */ + get canCreateRecurrenceException() { + // Can create exception if task is recurring and not completed + return this.isRecurring && !this.completed + } + /** * Construct the default value for the sort order * from the created date. diff --git a/src/store/tasks.js b/src/store/tasks.js index 4b33b7dc4..2bf2a793f 100644 --- a/src/store/tasks.js +++ b/src/store/tasks.js @@ -24,9 +24,11 @@ import { Calendar } from './calendars.js' import { findVTODObyUid } from './cdav-requests.js' import { isParentInList, momentToICALTime, parseString } from './storeHelper.js' +import { getDefaultRecurrenceRuleObject } from '../models/recurrenceRule.js' import SyncStatus from '../models/syncStatus.js' import Task from '../models/task.js' +import { DateTimeValue, RecurValue } from '@nextcloud/calendar-js' import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import { translate as t } from '@nextcloud/l10n' @@ -34,6 +36,50 @@ import moment from '@nextcloud/moment' import ICAL from 'ical.js' +/** + * Clone an ICAL.Time without triggering timezone lookups. + * ical.js may not have all timezones registered, causing errors when + * clone() tries to resolve timezone components. + * + * This function converts to local time first to handle the case where + * the ICAL.Time is stored in UTC - we need the local hour values, not UTC. + * + * @param {ICAL.Time} time The ICAL.Time to clone + * @param {boolean} [isDate] Override isDate property (optional) + * @return {ICAL.Time} A new ICAL.Time with the same local values + */ +function cloneTimeWithoutTimezone(time, isDate = null) { + let year = time.year + let month = time.month + let day = time.day + let hour = time.hour + let minute = time.minute + let second = time.second + + // If the time is in UTC, convert to local time without triggering timezone lookups + // We check for UTC timezone by looking at the zone property + if (time.zone && time.zone.tzid === 'UTC') { + // Create a Date from UTC values, then extract local time components + const jsDate = new Date(Date.UTC(year, month - 1, day, hour, minute, second)) + year = jsDate.getFullYear() + month = jsDate.getMonth() + 1 + day = jsDate.getDate() + hour = jsDate.getHours() + minute = jsDate.getMinutes() + second = jsDate.getSeconds() + } + + return new ICAL.Time({ + year, + month, + day, + hour, + minute, + second, + isDate: isDate !== null ? isDate : time.isDate, + }) +} + const state = { tasks: {}, searchQuery: '', @@ -1144,6 +1190,12 @@ const actions = { await context.dispatch('setPercentComplete', { task: subTask, complete: 100 }) } })) + + // Handle recurring tasks + if (task.isRecurring && task.recurrenceRule.recurrenceRuleValue) { + await context.dispatch('handleRecurringTaskCompletion', { task }) + return // The handler will update the task + } } context.commit('setComplete', { task, complete }) context.dispatch('updateTask', task) @@ -1445,7 +1497,7 @@ const actions = { context.commit('setStart', { task, start: newStart }) context.dispatch('updateTask', task) } - // Adjust due date + // Adjust due date if start is not set but due is } else if (due.isValid()) { diff = due.diff(moment().startOf('day'), 'days') diff = diff < 0 ? 0 : diff @@ -1454,9 +1506,9 @@ const actions = { context.commit('setDue', { task, due: newDue }) context.dispatch('updateTask', task) } - // Set the due date to appropriate value + // Set the start date to appropriate value (make start the default) } else { - context.commit('setDue', { task, due: day }) + context.commit('setStart', { task, start: day }) context.dispatch('updateTask', task) } }, @@ -1535,6 +1587,302 @@ const actions = { } }, + /** + * Sets the recurrence rule for a task + * + * @param {object} context The store context + * @param {object} data Destructuring object + * @param {Task} data.task The task to update + * @param {object} data.recurrenceRule The recurrence rule data + */ + async setRecurrenceRule(context, { task, recurrenceRule }) { + // Create base RecurValue with frequency and interval + const recurrenceValue = RecurValue.fromData({ + freq: recurrenceRule.frequency, + interval: recurrenceRule.interval || 1, + }) + + // Use setComponent() for by-parts (following Calendar app pattern) + // Add BYDAY if provided (for weekly, monthly, yearly) + if (recurrenceRule.byDay && recurrenceRule.byDay.length > 0) { + recurrenceValue.setComponent('BYDAY', recurrenceRule.byDay) + } + + // Add BYMONTH if provided (for yearly) + if (recurrenceRule.byMonth && recurrenceRule.byMonth.length > 0) { + recurrenceValue.setComponent('BYMONTH', recurrenceRule.byMonth) + } + + // Add BYMONTHDAY if provided (for monthly, yearly) + if (recurrenceRule.byMonthDay && recurrenceRule.byMonthDay.length > 0) { + recurrenceValue.setComponent('BYMONTHDAY', recurrenceRule.byMonthDay) + } + + // Add BYSETPOS if provided (for "on the first/last" options) + if (recurrenceRule.bySetPosition !== null && recurrenceRule.bySetPosition !== undefined) { + recurrenceValue.setComponent('BYSETPOS', [recurrenceRule.bySetPosition]) + } + + // Set end condition + if (recurrenceRule.until) { + recurrenceValue.until = DateTimeValue.fromJSDate(new Date(recurrenceRule.until), { zone: 'utc' }) + } else if (recurrenceRule.count) { + recurrenceValue.count = recurrenceRule.count + } + + // Convert RecurValue to ICAL.Recur + const icalRecur = recurrenceValue.toICALJs() + + // Add or update the RRULE property on the vtodo + task.vtodo.removeAllProperties('rrule') + task.vtodo.updatePropertyWithValue('rrule', icalRecur) + + // Update the task model + task._recurrenceRule = { + recurrenceRuleValue: recurrenceValue, + frequency: recurrenceRule.frequency, + interval: recurrenceRule.interval || 1, + count: recurrenceRule.count || null, + until: recurrenceRule.until || null, + byDay: recurrenceRule.byDay || [], + byMonth: recurrenceRule.byMonth || [], + byMonthDay: recurrenceRule.byMonthDay || [], + bySetPosition: recurrenceRule.bySetPosition || null, + isUnsupported: false, + } + task._hasMultipleRRules = false + + await context.dispatch('updateTask', task) + }, + + /** + * Removes the recurrence rule from a task + * + * @param {object} context The store context + * @param {object} data Destructuring object + * @param {Task} data.task The task to update + */ + async removeRecurrenceRule(context, { task }) { + // Remove the RRULE property from vtodo + task.vtodo.removeAllProperties('rrule') + + // Reset the recurrence rule in the task model + task._recurrenceRule = getDefaultRecurrenceRuleObject() + task._hasMultipleRRules = false + + await context.dispatch('updateTask', task) + }, + + /** + * Handles completion of a recurring task by creating an exception instance with RECURRENCE-ID + * This is compatible with Thunderbird and other CalDAV clients + * + * @param {object} context The store context + * @param {object} data Destructuring object + * @param {Task} data.task The task that was completed + */ + async handleRecurringTaskCompletion(context, { task }) { + // Only process if task is recurring + if (!task.isRecurring || !task.recurrenceRule.recurrenceRuleValue) { + return + } + + try { + // Get the instance date (the current due/start date) + const instanceDate = task.due || task.start + + if (!instanceDate) { + // Task has no date - just mark it complete without creating exception + console.warn('Recurring task has no due/start date - cannot create exception or advance to next occurrence') + context.commit('setComplete', { task, complete: 100 }) + context.dispatch('updateTask', task) + return + } + + // Get the calendar + const calendar = task.calendar + if (!calendar) { + console.error('Cannot find calendar for task') + return + } + + // Create a new exception VTODO for this completed instance + const comp = new ICAL.Component('vcalendar') + comp.updatePropertyWithValue('prodid', '-//Nextcloud Tasks') + comp.updatePropertyWithValue('version', '2.0') + + const vtodo = new ICAL.Component('vtodo') + comp.addSubcomponent(vtodo) + + // Copy properties from master task + vtodo.updatePropertyWithValue('uid', task.uid) + vtodo.updatePropertyWithValue('summary', task.summary) + + if (task.description) { + vtodo.updatePropertyWithValue('description', task.description) + } + if (task.location) { + vtodo.updatePropertyWithValue('location', task.location) + } + if (task.url) { + vtodo.updatePropertyWithValue('url', task.url) + } + if (task.priority) { + vtodo.updatePropertyWithValue('priority', task.priority) + } + if (task.class) { + vtodo.updatePropertyWithValue('class', task.class) + } + + // Set completion properties + vtodo.updatePropertyWithValue('status', 'COMPLETED') + vtodo.updatePropertyWithValue('percent-complete', 100) + const completedDate = ICAL.Time.now() + vtodo.updatePropertyWithValue('completed', completedDate) + + // Set RECURRENCE-ID to mark this as an exception instance + const recurrenceId = cloneTimeWithoutTimezone(instanceDate) + vtodo.updatePropertyWithValue('recurrence-id', recurrenceId) + + // Set the original due/start date for this instance + if (task.due) { + vtodo.updatePropertyWithValue('due', cloneTimeWithoutTimezone(task.due, task.allDay)) + } + if (task.start) { + vtodo.updatePropertyWithValue('dtstart', cloneTimeWithoutTimezone(task.start, task.allDay)) + } + + // Set created and last-modified + vtodo.updatePropertyWithValue('created', ICAL.Time.now()) + vtodo.updatePropertyWithValue('last-modified', ICAL.Time.now()) + vtodo.updatePropertyWithValue('dtstamp', ICAL.Time.now()) + + // Create the exception task on the server + const vData = comp.toString() + await context.dispatch('appendTaskToCalendar', { + calendar, + taskData: vData, + }) + + // Reload the task to get fresh ETag after exception was created + const freshTask = context.getters.getTaskByUri(task.uri) + if (!freshTask) { + console.error('Cannot find task after creating exception') + return + } + + // Now update the master task to show next occurrence + if (!freshTask.recurrenceRule?.recurrenceRuleValue) { + console.warn('Cannot advance recurring task: no recurrence rule value') + return + } + + // Convert RecurValue to ICAL.Recur to get the iterator + const icalRecur = freshTask.recurrenceRule.recurrenceRuleValue.toICALJs() + + // Check if recurrence rule has a COUNT limit + // When using COUNT, the iterator counts from startTime, which breaks when we + // advance the task's dates. We need to handle COUNT by decrementing it. + const hasCountLimit = icalRecur.count !== null && icalRecur.count > 0 + + // For COUNT-limited rules, check if we've reached the limit + if (hasCountLimit && icalRecur.count <= 1) { + // This is the last occurrence - mark master task as completed + freshTask.setComplete(100) + freshTask.setCompleted(true) + freshTask.setStatus('COMPLETED') + await context.dispatch('updateTask', freshTask) + return + } + + // Create a floating time to avoid timezone lookup issues + // Recurrence rules operate on local time (e.g., "repeat daily" = same local time each day) + const startTime = cloneTimeWithoutTimezone(instanceDate) + + const iterator = icalRecur.iterator(startTime) + + // Skip current occurrence + iterator.next() + + // Get next occurrence (ical.js iterator returns ICAL.Time directly, or null when done) + // For UNTIL rules, this correctly returns null when we've passed the end date + // For COUNT rules, we ignore the iterator's count tracking since we handle it separately + const nextOccurrence = iterator.next() + if (nextOccurrence) { + // Build moment directly from floating time components to preserve local time + // toJSDate() on floating times interprets values as UTC, causing timezone shift + const nextMoment = moment({ + year: nextOccurrence.year, + month: nextOccurrence.month - 1, // moment months are 0-indexed + date: nextOccurrence.day, + hour: nextOccurrence.hour, + minute: nextOccurrence.minute, + second: nextOccurrence.second, + }) + + // Calculate offset between start and due if both are set + let startOffset = null + if (freshTask.start && freshTask.due) { + const currentStart = freshTask.startMoment + const currentDue = freshTask.dueMoment + if (currentStart.isValid() && currentDue.isValid()) { + startOffset = currentDue.diff(currentStart) + } + } + + // Update the appropriate date field + if (freshTask.due) { + context.commit('setDue', { + task: freshTask, + due: nextMoment, + allDay: freshTask.allDay, + }) + } else if (freshTask.start) { + // If only start date exists, update that + context.commit('setStart', { + task: freshTask, + start: nextMoment, + allDay: freshTask.allDay, + }) + } + + // Update start date if both dates were set, maintaining the offset + if (freshTask.due && startOffset !== null) { + const nextStart = nextMoment.clone().subtract(startOffset, 'ms') + context.commit('setStart', { + task: freshTask, + start: nextStart, + allDay: freshTask.allDay, + }) + } + + // Reset completion status on master task + freshTask.setComplete(0) + freshTask.setCompleted(false) + freshTask.setStatus(null) + + // Decrement COUNT if the rule has a count limit + // This ensures the count reflects remaining occurrences + if (hasCountLimit) { + const rruleProp = freshTask.vtodo.getFirstProperty('rrule') + if (rruleProp) { + const rruleValue = rruleProp.getFirstValue() + rruleValue.count = rruleValue.count - 1 + } + } + + // Save the updated master task + await context.dispatch('updateTask', freshTask) + } else { + // No more occurrences - keep task completed + // The exception will show as completed, master can be left as-is + } + } catch (error) { + console.error('Error handling recurring task completion:', error) + showError(t('tasks', 'Error processing recurring task')) + } + }, + /** * Moves a task to a new calendar or parent task * diff --git a/src/utils/recurrence.js b/src/utils/recurrence.js new file mode 100644 index 000000000..90bf3ec28 --- /dev/null +++ b/src/utils/recurrence.js @@ -0,0 +1,55 @@ +/** + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +/** + * Gets the ByDay and BySetPosition + * + * @param {Date} jsDate The date to get the weekday of + * @return {object} + */ +export function getBySetPositionAndBySetFromDate(jsDate) { + const byDay = getWeekDayFromDate(jsDate) + let bySetPosition = 1 + let dayOfMonth = jsDate.getDate() + for (; dayOfMonth > 7; dayOfMonth -= 7) { + bySetPosition++ + } + + return { + byDay, + bySetPosition, + } +} + +/** + * Gets the string-representation of the weekday of a given date + * + * @param {Date} jsDate The date to get the weekday of + * @return {string} + */ +export function getWeekDayFromDate(jsDate) { + // If no date provided, default to Monday + if (!jsDate) { + return 'MO' + } + switch (jsDate.getDay()) { + case 0: + return 'SU' + case 1: + return 'MO' + case 2: + return 'TU' + case 3: + return 'WE' + case 4: + return 'TH' + case 5: + return 'FR' + case 6: + return 'SA' + default: + throw TypeError('Invalid date-object given') + } +} diff --git a/src/views/AppSidebar.vue b/src/views/AppSidebar.vue index ca93aff9e..4c4e3e12b 100644 --- a/src/views/AppSidebar.vue +++ b/src/views/AppSidebar.vue @@ -66,6 +66,13 @@ License along with this library. If not, see . :read-only="readOnly" :property-string="t('tasks', 'All day')" @set-checked="toggleAllDay(task)" /> + + + { 'use strict' + it('RecurValue should be available', () => { + expect(RecurValue).toBeDefined() + expect(typeof RecurValue.fromData).toEqual('function') + + // Test creating a simple recurrence rule + const recurValue = RecurValue.fromData({ freq: 'DAILY', interval: 1 }) + expect(recurValue).toBeDefined() + expect(recurValue.frequency).toEqual('DAILY') + }) + + it('Should manually parse RRULE', () => { + const ics = loadICS('vcalendars/vcalendar-recurring-daily') + const jCal = ICAL.parse(ics) + const vCalendar = new ICAL.Component(jCal) + const vtodo = vCalendar.getFirstSubcomponent('vtodo') + const rruleProp = vtodo.getFirstProperty('rrule') + const icalRecur = rruleProp.getFirstValue() + + // Try to convert to RecurValue + const recurData = { + freq: icalRecur.freq, + interval: icalRecur.interval || 1, + } + const recurValue = RecurValue.fromData(recurData) + + expect(recurValue).toBeDefined() + expect(recurValue.frequency).toEqual('DAILY') + }) + + it('Should parse RRULE when task is created', () => { + // Log to see what's happening + const origWarn = console.warn + const warnings = [] + console.warn = (...args) => { warnings.push(args.join(' ')); origWarn(...args) } + + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + + console.warn = origWarn + + // Check if there were warnings + if (warnings.length > 0) { + console.log('Warnings during task creation:', warnings) + } + + // The task should have recurrence parsed + console.log('Task isRecurring:', task.isRecurring) + console.log('Task recurrenceRule:', JSON.stringify(task.recurrenceRule, null, 2)) + + expect(task.isRecurring).toEqual(true) + }) + it('Should set status to "COMPLETED" on completion.', () => { const task = new Task(loadICS('vcalendars/vcalendar-default'), {}) task.complete = 100 @@ -279,4 +331,488 @@ describe('task', () => { task.customUrl = expected expect(task.customUrl).toEqual(expected) }) + + describe('Recurring Tasks', () => { + it('Should load RRULE from ICS file', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + // Debug: check what we actually got + const rruleProp = task.vtodo.getFirstProperty('rrule') + console.log('RRULE property:', rruleProp) + if (rruleProp) { + const rruleValue = rruleProp.getFirstValue() + console.log('RRULE value:', rruleValue) + console.log('RRULE value.freq:', rruleValue.freq) + console.log('RRULE value.interval:', rruleValue.interval) + console.log('RRULE value.parts:', rruleValue.parts) + console.log('RRULE value.toString():', rruleValue.toString()) + } + console.log('Task due:', task.due) + console.log('Task _due:', task._due) + console.log('Task recurrenceRule:', task.recurrenceRule) + expect(rruleProp).toBeDefined() + }) + + it('Should parse daily recurrence rule', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule).toBeDefined() + expect(task.recurrenceRule.frequency).toEqual('DAILY') + expect(task.recurrenceRule.interval).toEqual(1) + }) + + it('Should parse weekly recurrence rule with interval', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-weekly'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('WEEKLY') + expect(task.recurrenceRule.interval).toEqual(2) + }) + + it('Should parse recurrence rule with count', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-count'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.count).toEqual(5) + }) + + it('Should parse recurrence rule with until date', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-until'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.until).toBeDefined() + }) + + it('Should not be recurring without RRULE', () => { + const task = new Task(loadICS('vcalendars/vcalendar-default'), {}) + expect(task.isRecurring).toEqual(false) + expect(task.recurrenceRule.frequency).toEqual('NONE') + }) + + it('Should have recurrenceRuleValue when recurring', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.recurrenceRuleValue).toBeDefined() + expect(task.recurrenceRule.recurrenceRuleValue.frequency).toEqual('DAILY') + }) + + it('Should detect multiple RRULE properties', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + expect(task.hasMultipleRRules).toEqual(false) + }) + + it('Should parse RRULE with DTSTART instead of DUE', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-dtstart'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('DAILY') + }) + + it('Should parse RRULE even without due or start date (Thunderbird compatibility)', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-no-date'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('DAILY') + }) + + it('Should be able to create recurrence exceptions when recurring', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + expect(task.canCreateRecurrenceException).toEqual(true) + }) + + it('Should not be able to create recurrence exceptions when not recurring', () => { + const task = new Task(loadICS('vcalendars/vcalendar-default'), {}) + expect(task.canCreateRecurrenceException).toEqual(false) + }) + + it('Should parse weekly recurrence with multiple BYDAY values', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-weekly-byday'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('WEEKLY') + expect(task.recurrenceRule.byDay).toContain('MO') + expect(task.recurrenceRule.byDay).toContain('WE') + expect(task.recurrenceRule.byDay).toContain('FR') + expect(task.recurrenceRule.byDay.length).toEqual(3) + }) + + it('Should parse monthly recurrence with multiple BYMONTHDAY values', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-monthly-bymonthday'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('MONTHLY') + expect(task.recurrenceRule.byMonthDay).toContain(1) + expect(task.recurrenceRule.byMonthDay).toContain(15) + expect(task.recurrenceRule.byMonthDay.length).toEqual(2) + }) + + it('Should parse monthly recurrence with BYSETPOS (first Monday)', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-monthly-bysetpos'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('MONTHLY') + expect(task.recurrenceRule.byDay).toContain('MO') + expect(task.recurrenceRule.bySetPosition).toEqual(1) + }) + + it('Should parse yearly recurrence with BYMONTH', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-yearly-bymonth'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.frequency).toEqual('YEARLY') + expect(task.recurrenceRule.byMonth).toContain(1) + expect(task.recurrenceRule.byMonth).toContain(7) + expect(task.recurrenceRule.byMonthDay).toContain(15) + }) + + it('Should create RecurValue with multiple BYDAY using setComponent', () => { + // Test that setComponent correctly sets multiple BYDAY values + const recurrenceValue = RecurValue.fromData({ + freq: 'WEEKLY', + interval: 1, + }) + + // Use setComponent like we do in setRecurrenceRule + recurrenceValue.setComponent('BYDAY', ['MO', 'WE', 'FR']) + + // Verify the components are set + const byDayComponent = recurrenceValue.getComponent('BYDAY') + expect(byDayComponent).toContain('MO') + expect(byDayComponent).toContain('WE') + expect(byDayComponent).toContain('FR') + expect(byDayComponent.length).toEqual(3) + + // Convert to ICAL and verify the string output + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + expect(rruleString).toContain('BYDAY=MO,WE,FR') + }) + + it('Should create RecurValue with BYMONTHDAY using setComponent', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'MONTHLY', + interval: 1, + }) + + recurrenceValue.setComponent('BYMONTHDAY', [1, 15]) + + const byMonthDayComponent = recurrenceValue.getComponent('BYMONTHDAY') + expect(byMonthDayComponent).toContain(1) + expect(byMonthDayComponent).toContain(15) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + expect(rruleString).toContain('BYMONTHDAY=1,15') + }) + + it('Should create RecurValue with BYSETPOS using setComponent', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'MONTHLY', + interval: 1, + }) + + recurrenceValue.setComponent('BYDAY', ['MO']) + recurrenceValue.setComponent('BYSETPOS', [1]) + + const byDayComponent = recurrenceValue.getComponent('BYDAY') + expect(byDayComponent).toContain('MO') + + const bySetPosComponent = recurrenceValue.getComponent('BYSETPOS') + expect(bySetPosComponent).toContain(1) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + expect(rruleString).toContain('BYDAY=MO') + expect(rruleString).toContain('BYSETPOS=1') + }) + + it('Should iterate UNTIL-bounded recurrence using cloned time (preserves timezone)', () => { + // This tests the fix for: "TypeError: can't access property getAllSubcomponents, this.component is null" + // The error occurred when creating a floating time without timezone info for UNTIL comparison + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-until'), {}) + expect(task.isRecurring).toEqual(true) + + // Get the ICAL.Recur from the recurrence rule + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + expect(icalRecur.until).toBeDefined() + + // Clone the due date to preserve timezone info (the fix) + const startTime = task.due.clone() + + // Create iterator and verify it works without throwing + const iterator = icalRecur.iterator(startTime) + expect(iterator).toBeDefined() + + // Should be able to call next() without error + const firstOccurrence = iterator.next() + expect(firstOccurrence).toBeDefined() + + // Should eventually return null when past UNTIL date + let occurrenceCount = 1 + let occurrence = iterator.next() + while (occurrence !== null && occurrenceCount < 100) { + occurrenceCount++ + occurrence = iterator.next() + } + // UNTIL is 7 days after the start, so we should have ~7 occurrences for daily + expect(occurrenceCount).toBeLessThanOrEqual(8) + }) + + it('Should be able to decrement COUNT in RRULE for tracking remaining occurrences', () => { + // This tests the fix for: "max occurrences appear to be ignored" + // The COUNT needs to be decremented when advancing to next occurrence + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-count'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.count).toEqual(5) + + // Get the RRULE property from vtodo + const rruleProp = task.vtodo.getFirstProperty('rrule') + expect(rruleProp).toBeDefined() + + const rruleValue = rruleProp.getFirstValue() + expect(rruleValue.count).toEqual(5) + + // Simulate decrementing COUNT (as done in handleRecurringTaskCompletion) + rruleValue.count = rruleValue.count - 1 + expect(rruleValue.count).toEqual(4) + + // Verify the change persists + const rruleValueAfter = rruleProp.getFirstValue() + expect(rruleValueAfter.count).toEqual(4) + }) + + it('Should detect when COUNT reaches 1 (last occurrence)', () => { + // This verifies the logic for stopping recurrence when count limit is reached + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-count'), {}) + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + + expect(icalRecur.count).toEqual(5) + const hasCountLimit = icalRecur.count !== null && icalRecur.count > 0 + expect(hasCountLimit).toEqual(true) + + // When count is 1, this is the last occurrence + icalRecur.count = 1 + const isLastOccurrence = hasCountLimit && icalRecur.count <= 1 + expect(isLastOccurrence).toEqual(true) + }) + }) + + describe('RECURRENCE-ID Exception Instances', () => { + it('Should parse RECURRENCE-ID property', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurrence-exception'), {}) + expect(task.isRecurrenceException).toEqual(true) + expect(task.recurrenceId).toBeTruthy() + }) + + it('Should NOT parse RRULE when RECURRENCE-ID is present', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurrence-exception'), {}) + expect(task.isRecurrenceException).toEqual(true) + expect(task.isRecurring).toEqual(false) + }) + + it('Should not have RECURRENCE-ID on normal tasks', () => { + const task = new Task(loadICS('vcalendars/vcalendar-default'), {}) + expect(task.isRecurrenceException).toEqual(false) + expect(task.recurrenceId).toBeNull() + }) + }) + + describe('setRecurrenceRule Logic', () => { + it('Should create RRULE with weekly BYDAY for multiple days', () => { + // Test the logic used in setRecurrenceRule store action + const recurrenceValue = RecurValue.fromData({ + freq: 'WEEKLY', + interval: 1, + }) + + // Set multiple days (Mon, Wed, Fri) + recurrenceValue.setComponent('BYDAY', ['MO', 'WE', 'FR']) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + + expect(rruleString).toContain('FREQ=WEEKLY') + expect(rruleString).toContain('BYDAY=MO,WE,FR') + }) + + it('Should create RRULE with monthly BYMONTHDAY for multiple days', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'MONTHLY', + interval: 1, + }) + + // Set multiple month days (1st and 15th) + recurrenceValue.setComponent('BYMONTHDAY', [1, 15]) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + + expect(rruleString).toContain('FREQ=MONTHLY') + expect(rruleString).toContain('BYMONTHDAY=1,15') + }) + + it('Should create RRULE with yearly BYMONTH for multiple months', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'YEARLY', + interval: 1, + }) + + // Set multiple months (Jan and Jul) with day 15 + recurrenceValue.setComponent('BYMONTH', [1, 7]) + recurrenceValue.setComponent('BYMONTHDAY', [15]) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + + expect(rruleString).toContain('FREQ=YEARLY') + expect(rruleString).toContain('BYMONTH=1,7') + expect(rruleString).toContain('BYMONTHDAY=15') + }) + + it('Should create RRULE with COUNT limit', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'DAILY', + interval: 1, + }) + + recurrenceValue.count = 10 + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + + expect(rruleString).toContain('FREQ=DAILY') + expect(rruleString).toContain('COUNT=10') + }) + + it('Should create RRULE with UNTIL date', () => { + const recurrenceValue = RecurValue.fromData({ + freq: 'DAILY', + interval: 1, + }) + + // Set UNTIL to a specific date + recurrenceValue.until = DateTimeValue.fromJSDate(new Date('2026-12-31T23:59:59Z'), { zone: 'utc' }) + + const icalRecur = recurrenceValue.toICALJs() + const rruleString = icalRecur.toString() + + expect(rruleString).toContain('FREQ=DAILY') + expect(rruleString).toContain('UNTIL=') + expect(rruleString).toContain('20261231') + }) + + it('Should update task vtodo RRULE property', () => { + // Create a non-recurring task + const task = new Task(loadICS('vcalendars/vcalendar-default'), {}) + expect(task.isRecurring).toEqual(false) + + // Build a recurrence value like setRecurrenceRule does + const recurrenceValue = RecurValue.fromData({ + freq: 'WEEKLY', + interval: 2, + }) + recurrenceValue.setComponent('BYDAY', ['MO', 'FR']) + + // Convert to ICAL and update task + const icalRecur = recurrenceValue.toICALJs() + task.vtodo.removeAllProperties('rrule') + task.vtodo.updatePropertyWithValue('rrule', icalRecur) + + // Verify the RRULE was set + const rruleProp = task.vtodo.getFirstProperty('rrule') + expect(rruleProp).toBeDefined() + + const rruleValue = rruleProp.getFirstValue() + expect(rruleValue.freq).toEqual('WEEKLY') + expect(rruleValue.interval).toEqual(2) + }) + }) + + describe('handleRecurringTaskCompletion Logic', () => { + it('Should advance daily recurrence to next day', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-daily'), {}) + expect(task.isRecurring).toEqual(true) + + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + const startTime = task.due.clone() + + // Get iterator - first next() returns start, second returns next occurrence + const iterator = icalRecur.iterator(startTime) + iterator.next() // Skip the start date + const nextOccurrence = iterator.next() + + expect(nextOccurrence).toBeDefined() + // Next occurrence should be 1 day after start + const dayDiff = (nextOccurrence.toUnixTime() - startTime.toUnixTime()) / 86400 + expect(dayDiff).toEqual(1) + }) + + it('Should advance weekly recurrence to next week', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-weekly'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.interval).toEqual(2) // Every 2 weeks + + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + const startTime = task.due.clone() + + // Get iterator - first next() returns start, second returns next occurrence + const iterator = icalRecur.iterator(startTime) + iterator.next() // Skip the start date + const nextOccurrence = iterator.next() + + expect(nextOccurrence).toBeDefined() + // Next occurrence should be 2 weeks (14 days) after start + const dayDiff = (nextOccurrence.toUnixTime() - startTime.toUnixTime()) / 86400 + expect(dayDiff).toEqual(14) + }) + + it('Should stop iteration when UNTIL date is reached', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-until'), {}) + expect(task.isRecurring).toEqual(true) + + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + expect(icalRecur.until).toBeDefined() + + const startTime = task.due.clone() + const iterator = icalRecur.iterator(startTime) + + // Count occurrences until iterator returns null + let count = 0 + while (iterator.next() !== null && count < 100) { + count++ + } + + // Should have limited occurrences (UNTIL is 7 days after start for daily) + expect(count).toBeLessThan(10) + expect(count).toBeGreaterThan(0) + }) + + it('Should correctly identify last COUNT occurrence', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-with-count'), {}) + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + + // Initial count is 5 + expect(icalRecur.count).toEqual(5) + + // Simulate completing occurrences + icalRecur.count = 2 + expect(icalRecur.count <= 1).toEqual(false) // Not last yet + + icalRecur.count = 1 + expect(icalRecur.count <= 1).toEqual(true) // This is the last occurrence + }) + + it('Should handle weekly recurrence with multiple BYDAY correctly', () => { + const task = new Task(loadICS('vcalendars/vcalendar-recurring-weekly-byday'), {}) + expect(task.isRecurring).toEqual(true) + expect(task.recurrenceRule.byDay).toContain('MO') + expect(task.recurrenceRule.byDay).toContain('WE') + expect(task.recurrenceRule.byDay).toContain('FR') + + const icalRecur = task.recurrenceRule.recurrenceRuleValue.toICALJs() + const startTime = task.due.clone() + + const iterator = icalRecur.iterator(startTime) + + // Get multiple occurrences + const occurrences = [] + for (let i = 0; i < 5; i++) { + const occ = iterator.next() + if (occ) occurrences.push(occ) + } + + // Should have 5 occurrences + expect(occurrences.length).toEqual(5) + }) + }) })