diff --git a/index.html b/index.html index e7df18a..097dba8 100644 --- a/index.html +++ b/index.html @@ -735,8 +735,8 @@
@@ -948,11 +948,11 @@ - - - - - + + + + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5383387 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3093 @@ +{ + "name": "p1---kino", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "p1---kino", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "npm-run-all": "^4.1.5", + "serve": "^14.2.6", + "typescript": "^6.0.3" + } + }, + "node_modules/@zeit/schemas": { + "version": "2.36.0", + "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", + "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/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, + "license": "MIT" + }, + "node_modules/ansi-align/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, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", + "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.0", + "chalk": "^5.0.1", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk-template/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chalk-template/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk-template/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", + "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arch": "^2.2.0", + "execa": "^5.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "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, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "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, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-port-reachable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", + "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/serve": { + "version": "14.2.6", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.6.tgz", + "integrity": "sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zeit/schemas": "2.36.0", + "ajv": "8.18.0", + "arg": "5.0.2", + "boxen": "7.0.0", + "chalk": "5.0.1", + "chalk-template": "0.4.0", + "clipboardy": "3.0.0", + "compression": "1.8.1", + "is-port-reachable": "4.0.0", + "serve-handler": "6.1.7", + "update-check": "1.5.4" + }, + "bin": { + "serve": "build/main.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/serve-handler": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.5", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve/node_modules/chalk": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", + "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "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, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "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, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/update-check": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", + "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "registry-auth-token": "3.3.2", + "registry-url": "3.1.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "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, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4c21d1a --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "p1---kino", + "version": "1.0.0", + "description": "", + "main": "main.js", + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "serve": "serve .", + "run": "npm-run-all --parallel watch serve" + }, + "repository": { + "type": "git", + "url": "ssh://git@gitea.starfour.de:2222/Aaron/Kino-Website.git" + }, + "keywords": [], + "author": "Aaron und Jannis", + "license": "ISC", + "type": "commonjs", + "devDependencies": { + "npm-run-all": "^4.1.5", + "serve": "^14.2.6", + "typescript": "^6.0.3" + } +} diff --git a/src/account.ts b/src/account.ts new file mode 100644 index 0000000..2af62f6 --- /dev/null +++ b/src/account.ts @@ -0,0 +1,466 @@ +import type { User } from "./interfaces"; + +function readStorageJson(key: string, fallbackValue: any) { + const raw = localStorage.getItem(key); + + if (!raw || raw === "undefined" || raw === "null") { + return fallbackValue; + } + + try { + return JSON.parse(raw); + } catch (error) { + console.warn(`Konnte LocalStorage-Wert fuer ${key} nicht lesen.`, error); + return fallbackValue; + } +} + +function normalizeUser(user: User): User { + return { + firstName: user.firstName || "", + lastName: user.lastName || "", + email: user.email || "", + hashedPassword: user.hashedPassword || "", + orders: Array.isArray(user.orders) ? user.orders : [], + paymentMethods: Array.isArray(user.paymentMethods) ? user.paymentMethods : [] + }; +} + +function escapeHtml(value: string) { + return String(value || "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); +} + +function formatEuro(value: string) { + return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`; +} + +function persistUsers() { + localStorage.setItem("eagleUsers", JSON.stringify(users)); +} + +function persistCurrentUser() { + if (currentUser) { + localStorage.setItem("currentUser", JSON.stringify(currentUser)); + } else { + localStorage.removeItem("currentUser"); + } +} + +let users = readStorageJson("eagleUsers", []); +if (!Array.isArray(users)) { + users = []; +} +users = users.map(normalizeUser).filter(Boolean); + +const rawCurrentUser = readStorageJson("currentUser", null); +var currentUser: User | null = rawCurrentUser ? normalizeUser(rawCurrentUser) : null; +if (currentUser && currentUser.email) { + const currentEmail = currentUser.email; + const storedMatch = users.find((user: { email: string; }) => { + return user.email === currentEmail; + }); + if (storedMatch) { + currentUser = storedMatch; + } else { + users.push(currentUser); + persistUsers(); + } +} + +async function hashMessage(message: string) { + const msgBuffer = new TextEncoder().encode(message); // Encode as UTF-8 + const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); // Hash + const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert to bytes + return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // Hex string +} + +function getInputValue(id: string): string { + const el = document.getElementById(id) as HTMLInputElement | null; + return el?.value.trim() ?? ""; +} + +async function registerUser() { +const firstName = getInputValue("reg-firstname"); +const lastName = getInputValue("reg-lastname"); +const email = getInputValue("reg-email").toLowerCase(); +const password = document.querySelector("#reg-password")?.value ?? ""; + + if (!firstName || !lastName || !email || !password) { + alert("Bitte fuelle alle Felder aus."); + return; + } + + if (!email.includes("@")) { + alert("Bitte gib eine gueltige E-Mail-Adresse ein."); + return; + } + + const existingUser = users.find((user: User) => user.email.toLowerCase() === email); + if (existingUser) { + alert("E-Mail bereits registriert"); + return; + } + + const hashedPassword = await hashMessage(password); + + const newUser = { + firstName, + lastName, + email, + hashedPassword, + orders: [], + paymentMethods: [] + }; + + users.push(newUser); + currentUser = newUser; + + persistUsers(); + persistCurrentUser(); + + alert("Registrierung erfolgreich"); + document.getElementById("register-modal")?.classList.add("hidden"); + + openAccountDashboard(); +} + +async function loginUser() { + const email = (document.querySelector("#login-email")?.value.trim() || "").toLowerCase(); + const password = document.querySelector("#login-password")?.value || ""; + const hashedPassword = await hashMessage(password); + + const user = users.find( + (entry: User) => entry.email.toLowerCase() === email && entry.hashedPassword === hashedPassword + ); + + if (!user) { + document.getElementById("login-error")?.classList.remove("hidden"); + return; + } + + currentUser = user; + persistCurrentUser(); + openAccountDashboard(); +} + +function openAccountDashboard() { + const accountView = document.getElementById("account-view"); + if (!accountView) { + return; + } + + if (!currentUser) { + accountView.innerHTML = ""; + return; + } + + accountView.innerHTML = /*html*/` + + `; + + renderPersonalInfo(); +} + +function renderPersonalInfo() { + const target = document.getElementById("account-tab-content"); + if (!target || !currentUser) { + return; + } + + target.innerHTML = ` + + `; +} + +function renderOrders() { + const target = document.getElementById("account-tab-content"); + if (!target || !currentUser) { + return; + } + + const orders = Array.isArray(currentUser.orders) ? currentUser.orders : []; + + if (!orders.length) { + target.innerHTML = ` + + `; + return; + } + + const orderHtml = orders + .map((order, index) => { + const movieItems = Array.isArray(order.items) + ? order.items.filter((item: any) => item.category === "movie") + : []; + const previewItem = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null); + const previewTitle = previewItem?.title || "Bestellung"; + const ticketsCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0); + + return ` + + `; + }) + .join(""); + + target.innerHTML = ` + + `; + + const detailTarget = document.getElementById("order-ticket-details"); + const orderButtons = Array.from(target.querySelectorAll(".order-item-btn")); + + const renderOrderTicket = (orderIndex: number) => { + const order = orders[orderIndex]; + if (!order || !detailTarget) { + return; + } + + const movieItems = Array.isArray(order.items) + ? order.items.filter((item: any) => item.category === "movie") + : []; + const primaryMovie = movieItems[0] || (Array.isArray(order.items) ? order.items[0] : null); + const poster = primaryMovie?.img || ""; + const seats = movieItems.map((item: any) => item.seatId).filter(Boolean).join(", ") || "-"; + const ticketCount = movieItems.length || (Array.isArray(order.items) ? order.items.length : 0); + const hall = primaryMovie?.hall || "-"; + const time = primaryMovie?.time ? `${primaryMovie.time} Uhr` : "-"; + + detailTarget.innerHTML = ` +
+
+ ${poster + ? `${escapeHtml(primaryMovie?.title || ` + : `
Kein Poster
`} +
+
+
EAGLE'S IMAX | Bestell-Details
+

${escapeHtml(primaryMovie?.title || "Bestellung")}

+
+

Datum${escapeHtml(order.date || "-")}

+

Saal${escapeHtml(hall)}

+

Uhrzeit${escapeHtml(time)}

+

Tickets${ticketCount}x

+

Sitze${escapeHtml(seats)}

+

Gesamt${formatEuro(order.total || 0)}

+
+
+
+ `; + + detailTarget.classList.remove("hidden"); + orderButtons.forEach((button) => { + button.classList.toggle("active", Number(button.dataset.orderIndex) === orderIndex); + }); + }; + + orderButtons.forEach((button) => { + button.addEventListener("click", () => { + const orderIndex = Number(button.dataset.orderIndex || -1); + if (orderIndex >= 0) { + renderOrderTicket(orderIndex); + } + }); + }); + +} + +function renderPayments() { + const target = document.getElementById("account-tab-content"); + if (!target || !currentUser) { + return; + } + + target.innerHTML = /*html*/` + + + + + + + + + + `; + + const modals = Array.from(target.querySelectorAll(".pay-modal-overlay")); + const triggers = Array.from(target.querySelectorAll(".account-pay-trigger")); + const closeButtons = Array.from(target.querySelectorAll("[data-pay-close]")); + + const closeAllPaymentModals = () => { + modals.forEach((modal) => modal.classList.add("hidden")); + document.body.style.overflow = "auto"; + }; + + triggers.forEach((trigger) => { + trigger.addEventListener("click", () => { + closeAllPaymentModals(); + const targetId = trigger.getAttribute("data-pay-modal"); + const modal = targetId ? target.querySelector(`#${targetId}`) : null; + + if (modal) { + modal.classList.remove("hidden"); + document.body.style.overflow = "hidden"; + } + }); + }); + + closeButtons.forEach((button) => { + button.addEventListener("click", closeAllPaymentModals); + }); + + modals.forEach((modal) => { + modal.addEventListener("click", (event) => { + if (event.target === modal) { + closeAllPaymentModals(); + } + }); + }); +} + +function logoutUser() { + persistCurrentUser(); + window.location.reload(); +} diff --git a/src/booking.js b/src/booking.js new file mode 100644 index 0000000..52aa109 --- /dev/null +++ b/src/booking.js @@ -0,0 +1,352 @@ +let currentBookingContext = null; +let currentHallLayout = null; + +function openBooking(movie, hall, time) { + const titleEl = document.getElementById("modal-movie-title"); + const infoEl = document.getElementById("modal-info-text"); + + if (titleEl) { + titleEl.innerText = movie; + } + + if (infoEl) { + infoEl.innerText = `${hall} • ${time} Uhr`; + } + + currentBookingContext = { movie, hall, time }; + + createSeats(hall, time); + renderBookingLegend(); + updateBookingSummary(); + + document.getElementById("booking-modal")?.classList.remove("hidden"); +} + +function getRowLabel(rowIndex) { + return String(rowIndex + 1); +} + +function buildHallLayout(hallName, baseConfig) { + const rows = Number(baseConfig.rows || 0); + const totalCols = Number(baseConfig.left || 0) + Number(baseConfig.right || 0); + const isDeluxe = /deluxe/i.test(hallName); + + const left = isDeluxe + ? Math.max(3, Number(baseConfig.left || 0) - 1) + : Number(baseConfig.left || 0); + const right = Math.max(0, totalCols - left); + + const vipRows = rows > 0 ? [rows] : []; + + const dboxMap = new Set(); + const markDboxRange = (rowNumber, startCol, width) => { + if (!rowNumber || width <= 0) { + return; + } + + const maxCol = Math.min(totalCols, startCol + width - 1); + for (let col = startCol; col <= maxCol; col++) { + dboxMap.add(`${rowNumber}-${col}`); + } + }; + + if (isDeluxe) { + const configuredDboxSeats = Array.isArray(baseConfig.dbox) + ? baseConfig.dbox.reduce((sum, section) => sum + Number(section.w || 0), 0) + : 0; + + const totalDboxSeats = Math.max(4, configuredDboxSeats || 0); + + const firstRow = Math.max(1, rows - 2); + const secondRow = Math.max(1, rows - 1); + const targetRows = [firstRow, secondRow] + .filter((rowNumber, index, arr) => arr.indexOf(rowNumber) === index) + .filter((rowNumber) => !vipRows.includes(rowNumber)); + + const rowCount = Math.max(1, targetRows.length); + const seatsPerFirstRows = Math.ceil(totalDboxSeats / rowCount); + let remaining = totalDboxSeats; + + targetRows.forEach((rowNumber, index) => { + const seatsForRow = index === targetRows.length - 1 + ? remaining + : Math.min(seatsPerFirstRows, remaining); + remaining -= seatsForRow; + + const startCol = left + Math.max(1, Math.floor((right - seatsForRow) / 2) + 1); + markDboxRange(rowNumber, startCol, seatsForRow); + }); + } else if (Array.isArray(baseConfig.dbox)) { + baseConfig.dbox.forEach((section) => { + const rowNumber = Number(section.r || 0); + const width = Number(section.w || 0); + const startCol = Number(section.c || 0); + markDboxRange(rowNumber, startCol, width); + }); + } + + return { + rows, + left, + right, + totalCols, + vipRows, + dboxMap, + isImax: Boolean(baseConfig.isImax) + }; +} + +function getSeatType(layout, rowNumber, colNumber) { + if (layout.dboxMap.has(`${rowNumber}-${colNumber}`)) { + return "dbox"; + } + + if (layout.vipRows.includes(rowNumber)) { + return "vip"; + } + + if (layout.isImax) { + return "imax"; + } + + return "normal"; +} + +function createSeatElement({ seatId, seatType, occupiedSeats }) { + const seat = document.createElement("button"); + seat.type = "button"; + seat.classList.add("seat", seatType); + seat.dataset.seatId = seatId; + seat.dataset.type = seatType; + seat.title = `${seatId} (${seatType.toUpperCase()})`; + + if (occupiedSeats.has(seatId)) { + seat.classList.add("occupied"); + seat.disabled = true; + seat.setAttribute("aria-label", `${seatId} belegt`); + return seat; + } + + seat.setAttribute("aria-label", `${seatId} frei`); + seat.addEventListener("click", () => { + seat.classList.toggle("selected"); + updateBookingSummary(); + }); + + return seat; +} + +function createSeats(hallName, time) { + const seatGrid = document.getElementById("seat-grid"); + if (!seatGrid) { + return; + } + + seatGrid.innerHTML = ""; + + const baseConfig = seatLayouts[hallName]; + if (!baseConfig) { + currentHallLayout = null; + return; + } + + currentHallLayout = buildHallLayout(hallName, baseConfig); + + const occupiedKey = `${hallName}-${time}`; + const occupiedSeats = new Set(Array.isArray(occupiedSeatsData?.[occupiedKey]) ? occupiedSeatsData[occupiedKey] : []); + + for (let rowIndex = 0; rowIndex < currentHallLayout.rows; rowIndex++) { + const rowNumber = rowIndex + 1; + const rowLabel = getRowLabel(rowIndex); + + const perspectiveFactor = (currentHallLayout.rows - rowNumber) / Math.max(currentHallLayout.rows - 1, 1); + const rowIndent = Math.round(18 * perspectiveFactor); + + const row = document.createElement("div"); + row.className = "seat-row cinema-row"; + row.style.setProperty("--row-indent", `${rowIndent}px`); + + const leftLabel = document.createElement("div"); + leftLabel.className = "row-label"; + leftLabel.textContent = rowLabel; + + const rightLabel = document.createElement("div"); + rightLabel.className = "row-label row-label-right"; + rightLabel.textContent = rowLabel; + + const leftBlock = document.createElement("div"); + leftBlock.className = "row-seat-block left-block"; + + const rightBlock = document.createElement("div"); + rightBlock.className = "row-seat-block right-block"; + + for (let col = 1; col <= currentHallLayout.totalCols; col++) { + const seatId = `R${rowNumber}-P${col}`; + const seatType = getSeatType(currentHallLayout, rowNumber, col); + const seat = createSeatElement({ seatId, seatType, occupiedSeats }); + + if (col <= currentHallLayout.left) { + leftBlock.appendChild(seat); + } else { + rightBlock.appendChild(seat); + } + } + + const aisle = document.createElement("div"); + aisle.className = "aisle-gap"; + + row.append(leftLabel, leftBlock, aisle, rightBlock, rightLabel); + seatGrid.appendChild(row); + } +} + +function renderBookingLegend() { + const legend = document.getElementById("dynamic-legend"); + if (!legend || !currentHallLayout) { + return; + } + + const legendItems = [ + { type: "normal", label: "Standard" }, + { type: "selected", label: "Ausgewählt" }, + { type: "occupied", label: "Belegt" } + ]; + + if (currentHallLayout.isImax) { + legendItems.unshift({ type: "imax", label: "IMAX" }); + } + + if (currentHallLayout.vipRows.length > 0) { + legendItems.unshift({ type: "vip", label: "VIP" }); + } + + if (currentHallLayout.dboxMap.size > 0) { + legendItems.unshift({ type: "dbox", label: "D-BOX" }); + } + + legend.innerHTML = legendItems + .map((item) => ` +
+ + ${item.label} +
+ `) + .join(""); +} + +function updateBookingSummary() { + const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected")); + const summaryPanel = document.getElementById("booking-summary"); + const summaryItems = document.getElementById("summary-items"); + const totalEl = document.getElementById("total-price"); + + let total = 0; + + if (summaryItems) { + summaryItems.innerHTML = selectedSeats + .map((seat) => { + const type = seat.dataset.type || "normal"; + const seatPrice = Number(prices?.[type] ?? prices?.normal ?? 11); + total += seatPrice; + + return ` +
+ ${seat.dataset.seatId} + ${seatPrice.toFixed(2).replace(".", ",")} EUR +
+ `; + }) + .join(""); + } else { + selectedSeats.forEach((seat) => { + const type = seat.dataset.type || "normal"; + const seatPrice = Number(prices?.[type] ?? prices?.normal ?? 11); + total += seatPrice; + }); + } + + if (totalEl) { + totalEl.innerText = `${total.toFixed(2).replace(".", ",")} EUR`; + } + + summaryPanel?.classList.toggle("hidden", selectedSeats.length === 0); +} + +function findMoviePoster(movieTitle) { + const cards = Array.from(document.querySelectorAll(".movie-card, .detailed-card")); + const normalizedTarget = String(movieTitle || "").trim().toLowerCase(); + + for (const card of cards) { + const title = card.querySelector("h2, h3")?.innerText?.trim().toLowerCase(); + if (title === normalizedTarget) { + const imageSrc = card.querySelector("img")?.src; + if (imageSrc) { + return imageSrc; + } + } + } + + return ""; +} + +function confirmSelectedSeats() { + const selectedSeats = Array.from(document.querySelectorAll("#seat-grid .seat.selected")); + + if (!currentBookingContext || selectedSeats.length === 0) { + alert("Bitte waehle mindestens einen Platz aus."); + return; + } + + const moviePoster = findMoviePoster(currentBookingContext.movie); + const addedSeats = []; + + selectedSeats.forEach((seat) => { + const seatId = seat.dataset.seatId; + const seatType = seat.dataset.type || "normal"; + + const alreadyInCart = cart.some((item) => + item.category === "movie" && + item.title === currentBookingContext.movie && + item.hall === currentBookingContext.hall && + item.time === currentBookingContext.time && + item.seatId === seatId + ); + + if (alreadyInCart) { + return; + } + + cart.push({ + id: Date.now() + Math.random(), + category: "movie", + title: currentBookingContext.movie, + hall: currentBookingContext.hall, + time: currentBookingContext.time, + seatId, + type: seatType.toUpperCase(), + price: Number(prices?.[seatType] ?? prices?.normal ?? 11), + img: moviePoster + }); + + addedSeats.push(seatId); + }); + + if (!addedSeats.length) { + alert("Diese Plaetze sind bereits im Warenkorb."); + return; + } + + saveCart?.(); + renderCart?.(); + renderCheckout?.(); + + document.getElementById("booking-modal")?.classList.add("hidden"); + + const snackOverlay = document.getElementById("snack-prompt-overlay"); + snackOverlay?.classList.remove("hidden"); + document.body.style.overflow = "hidden"; +} + +document.addEventListener("DOMContentLoaded", () => { + document.getElementById("btn-confirm-seats")?.addEventListener("click", confirmSelectedSeats); +}); diff --git a/src/cart.js b/src/cart.js new file mode 100644 index 0000000..17457a2 --- /dev/null +++ b/src/cart.js @@ -0,0 +1,199 @@ +function formatEuro(value) { + return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`; +} + +function escapeHtml(value) { + return String(value || "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); +} + +function buildCartKey(item) { + const infoText = item.category === "movie" + ? `Sitz: ${item.seatId} (${item.hall})` + : item.time; + return `${item.title}-${item.hall}-${infoText}`; +} + +function isDrinkItem(item) { + if (item.category !== "snack") { + return false; + } + + const title = String(item.title || "").toLowerCase(); + const size = String(item.hall || "").toLowerCase(); + const drinkKeywords = [ + "cola", + "sprite", + "fanta", + "mezzo", + "fuze", + "wasser", + "getraenk", + "drink" + ]; + + return drinkKeywords.some((word) => title.includes(word)) || size.includes("l"); +} + +function buildItemInfo(item) { + if (item.category === "movie") { + return ` +
Sitzplatz: ${escapeHtml(item.seatId || "-")}
+
Saal: ${escapeHtml(item.hall || "-")}
+
Uhrzeit: ${escapeHtml(item.time || "-")} Uhr
+ `; + } + + if (isDrinkItem(item)) { + return ` +
Variante: ${escapeHtml(item.time || "-")}
+
Groesse: ${escapeHtml(item.hall || "-")}
+ `; + } + + return ` +
Kategorie: Snack
+
Variante: ${escapeHtml(item.time || "-")}
+
Groesse: ${escapeHtml(item.hall || "-")}
+ `; +} + +function groupCartItems() { + const groups = new Map(); + + cart.forEach((item) => { + const key = buildCartKey(item); + + if (!groups.has(key)) { + groups.set(key, { + key, + quantity: 0, + total: 0, + item + }); + } + + const group = groups.get(key); + group.quantity += 1; + group.total += Number(item.price || 0); + }); + + return Array.from(groups.values()); +} + +function saveCart() { + localStorage.setItem("eagleCart", JSON.stringify(cart)); + updateCartBadge(); +} + +function updateCartBadge() { + const cartBadge = document.getElementById("cart-badge"); + + if (!cartBadge) { + return; + } + + cartBadge.innerText = cart.length; + cartBadge.classList.toggle("hidden", cart.length === 0); +} + +function renderCart() { + const cartList = document.getElementById("cart-items-list"); + const totalEl = document.getElementById("cart-total-right"); + const vatEl = document.getElementById("cart-vat-right"); + + if (!cartList || !totalEl || !vatEl) { + return; + } + + if (!Array.isArray(cart) || cart.length === 0) { + cartList.innerHTML = '

Dein Warenkorb ist leer.

'; + totalEl.innerText = formatEuro(0); + vatEl.innerText = `inkl. 19% MwSt: ${formatEuro(0)}`; + return; + } + + const groupedItems = groupCartItems(); + + const header = /*html*/` +
+
MENGE
+
VORSCHAU
+
NAME
+
INFO
+
PREIS
+
AKTION
+
+ `; + + const rows = groupedItems + .map((group) => { + const imageHtml = group.item.img + ? /*html*/`${escapeHtml(group.item.title)}` + : /*html*/`
Kein Bild
`; + const quantityHtml = group.item.category === "movie" + ? /*html*/`
${group.quantity}x
` + : /*html*/` +
+ + ${group.quantity} + +
+ `; + + return /*html*/` +
+
+ ${quantityHtml} +
+
${imageHtml}
+
${escapeHtml(group.item.title)}
+
${buildItemInfo(group.item)}
+
${formatEuro(group.total)}
+
+ +
+
+ `; + }) + .join(""); + + cartList.innerHTML = header + rows; + + const total = cart.reduce((sum, item) => sum + Number(item.price || 0), 0); + const vat = total - total / 1.19; + + totalEl.innerText = formatEuro(total); + vatEl.innerText = `inkl. 19% MwSt: ${formatEuro(vat)}`; + + saveCart(); +} + +window.removeItem = function removeItem(id) { + cart = cart.filter((item) => item.id !== id); + saveCart(); + renderCart(); +}; + +window.changeQty = function changeQty(title, delta) { + if (delta > 0) { + const item = cart.find((entry) => entry.title === title); + if (item) { + cart.push({ ...item, id: Date.now() + Math.random() }); + } + } else { + const index = cart + .map((entry) => entry.title) + .lastIndexOf(title); + if (index !== -1) { + cart.splice(index, 1); + } + } + + saveCart(); + renderCart(); +}; diff --git a/src/checkout.js b/src/checkout.js new file mode 100644 index 0000000..6da24e4 --- /dev/null +++ b/src/checkout.js @@ -0,0 +1,232 @@ +function formatCheckoutEuro(value) { + return `${Number(value || 0).toFixed(2).replace(".", ",")} EUR`; +} + +let selectedPaymentMethod = ""; +let checkoutEventsBound = false; + +function setCheckoutStep(step) { + const step1 = document.getElementById("checkout-step-1"); + const step2 = document.getElementById("checkout-step-2"); + const step3 = document.getElementById("checkout-step-3"); + + step1?.classList.toggle("hidden", step !== 1); + step2?.classList.toggle("hidden", step !== 2); + step3?.classList.toggle("hidden", step !== 3); + + const line1 = document.getElementById("line-1"); + const line2 = document.getElementById("line-2"); + const indicator1 = document.getElementById("step-1-indicator"); + const indicator2 = document.getElementById("step-2-indicator"); + const indicator3 = document.getElementById("step-3-indicator"); + + indicator1?.classList.add("active"); + indicator2?.classList.toggle("active", step >= 2); + indicator3?.classList.toggle("active", step >= 3); + line1?.classList.toggle("active", step >= 2); + line2?.classList.toggle("active", step >= 3); +} + +function renderCheckout() { + const summaryList = document.getElementById("checkout-summary-list"); + const totalDisplay = document.getElementById("checkout-total-display"); + const vatDisplay = document.getElementById("checkout-vat-display"); + const nextButton = document.getElementById("btn-next-step-2"); + + if (!summaryList) { + return; + } + + summaryList.innerHTML = ""; + + const safeCart = Array.isArray(cart) ? cart : []; + const total = safeCart.reduce((sum, item) => sum + Number(item.price || 0), 0); + const vat = total - total / 1.19; + + safeCart.forEach((item) => { + const row = document.createElement("div"); + row.style.cssText = "display:flex; justify-content:space-between; gap:12px; margin-bottom:10px; font-size:0.95rem;"; + + const infoText = item.category === "movie" + ? `Sitz ${item.seatId || "-"} | ${item.hall || "-"} | ${item.time || "-"} Uhr` + : `${item.time || "Standard"} | ${item.hall || "-"}`; + + row.innerHTML = `${item.title} (${infoText})${formatCheckoutEuro(item.price)}`; + summaryList.appendChild(row); + }); + + if (totalDisplay) { + totalDisplay.innerText = `Gesamtbetrag: ${formatCheckoutEuro(total)}`; + } + + if (vatDisplay) { + vatDisplay.innerText = `inkl. 19% MwSt: ${formatCheckoutEuro(vat)}`; + } + + selectedPaymentMethod = ""; + document.querySelectorAll(".payment-method").forEach((method) => { + method.classList.remove("selected"); + }); + + nextButton?.classList.add("hidden"); + setCheckoutStep(1); +} + +function generateTicket() { + const ticketContainer = document.getElementById("ticket-container"); + if (!ticketContainer) { + return; + } + + const moviesInCart = (Array.isArray(cart) ? cart : []).filter((item) => item.category === "movie"); + if (!moviesInCart.length) { + ticketContainer.innerHTML = "

Danke fuer deinen Einkauf!

"; + return; + } + + const mainMovie = moviesInCart[0]; + const matchingMovieSeats = moviesInCart + .filter((item) => item.title === mainMovie.title && item.time === mainMovie.time) + .map((item) => item.seatId) + .join(", "); + + const qrData = encodeURIComponent(`EAGLE-IMAX|${mainMovie.title}|${mainMovie.hall}|${matchingMovieSeats}`); + const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${qrData}&bgcolor=ffffff`; + + ticketContainer.innerHTML = /*html*/` +
+
+ ${mainMovie.title} +
+
+
EAGLE'S IMAX PREMIUM
+

${mainMovie.title}

+
+

SAAL ${mainMovie.hall}

+

ZEIT ${mainMovie.time} Uhr

+

SITZE ${matchingMovieSeats || "-"}

+
+ +
+
+ `; +} + +function saveOrderForCurrentUser(orderItems, orderTotal) { + if (typeof currentUser === "undefined" || !currentUser) { + return; + } + + if (typeof users === "undefined" || !Array.isArray(users)) { + return; + } + + const order = { + date: new Date().toLocaleString("de-DE"), + items: orderItems, + total: orderTotal, + paymentMethod: selectedPaymentMethod || "-" + }; + + const userIndex = users.findIndex((entry) => entry.email === currentUser.email); + if (userIndex === -1) { + return; + } + + if (!Array.isArray(users[userIndex].orders)) { + users[userIndex].orders = []; + } + + users[userIndex].orders.push(order); + localStorage.setItem("eagleUsers", JSON.stringify(users)); +} + +function reserveSeatsAfterPayment(orderItems) { + const movieItems = orderItems.filter((item) => item.category === "movie"); + + movieItems.forEach((item) => { + const key = `${item.hall}-${item.time}`; + if (!occupiedSeatsData[key]) { + occupiedSeatsData[key] = []; + } + + occupiedSeatsData[key].push(item.seatId); + }); + + localStorage.setItem("eagleOccupied", JSON.stringify(occupiedSeatsData)); +} + +function completeCheckout() { + const orderItems = Array.isArray(cart) ? [...cart] : []; + const orderTotal = orderItems.reduce((sum, item) => sum + Number(item.price || 0), 0); + + saveOrderForCurrentUser(orderItems, orderTotal); + reserveSeatsAfterPayment(orderItems); + + cart = []; + saveCart?.(); + renderCart?.(); +} + +function bindCheckoutEvents() { + if (checkoutEventsBound) { + return; + } + + checkoutEventsBound = true; + + const nextButton = document.getElementById("btn-next-step-2"); + const backButton = document.getElementById("btn-back-to-step1"); + const payNowButton = document.getElementById("btn-pay-now"); + + document.querySelectorAll(".payment-method").forEach((method) => { + method.addEventListener("click", () => { + document.querySelectorAll(".payment-method").forEach((entry) => { + entry.classList.remove("selected"); + }); + + method.classList.add("selected"); + selectedPaymentMethod = method.dataset.method || ""; + nextButton?.classList.remove("hidden"); + }); + }); + + nextButton?.addEventListener("click", () => { + if (!selectedPaymentMethod) { + alert("Bitte waehle zuerst eine Zahlungsmethode aus."); + return; + } + + setCheckoutStep(2); + }); + + backButton?.addEventListener("click", () => { + setCheckoutStep(1); + }); + + payNowButton?.addEventListener("click", () => { + if (!Array.isArray(cart) || !cart.length) { + alert("Dein Warenkorb ist leer."); + return; + } + + payNowButton.disabled = true; + payNowButton.innerText = "Verarbeite..."; + payNowButton.style.opacity = "0.7"; + + setTimeout(() => { + setCheckoutStep(3); + generateTicket(); + completeCheckout(); + + payNowButton.disabled = false; + payNowButton.innerText = "Jetzt Bezahlen"; + payNowButton.style.opacity = "1"; + }, 1200); + }); +} + +document.addEventListener("DOMContentLoaded", bindCheckoutEvents); diff --git a/src/interfaces.ts b/src/interfaces.ts new file mode 100644 index 0000000..feba230 --- /dev/null +++ b/src/interfaces.ts @@ -0,0 +1,8 @@ +export interface User { + firstName: string; + lastName: string; + email: string; + hashedPassword: string; + orders: any[]; // TODO: figure out proper array type of orders. Probably smartest do create an Order interface which this would be an array of + paymentMethods: any[]; // TODO: figure out proper array type of paymentMethods. create paymentMethod interface and make this an array of it +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..6cb5d7e --- /dev/null +++ b/src/main.js @@ -0,0 +1,1092 @@ +// Shared app state for legacy script files (account.js, booking.js, cart.js, checkout.js) +var prices = { normal: 11.0, imax: 15.0, vip: 12.0, dbox: 16.0 }; +var seatLayouts = { + "Kino 1": { rows: 6, left: 3, right: 7, vipRows: [5], dbox: [] }, + "Kino 2": { rows: 7, left: 5, right: 5, vipRows: [6], dbox: [] }, + "Deluxe 1": { rows: 10, left: 7, right: 8, vipRows: [9], dbox: [{ r: 4, c: 5, w: 4 }] }, + IMAX: { rows: 15, left: 10, right: 10, vipRows: [], dbox: [], isImax: true } +}; +var cart = JSON.parse(localStorage.getItem("eagleCart")) || []; +var occupiedSeatsData = JSON.parse(localStorage.getItem("eagleOccupied")) || {}; + +document.addEventListener("DOMContentLoaded", () => { + const views = { + hero: document.querySelector(".hero"), + moviesGrid: document.getElementById("movies-grid-section"), + list: document.getElementById("movie-list-view"), + halls: document.getElementById("halls-view"), + dbox: document.getElementById("dbox-view"), + collectors: document.getElementById("collectors-view"), + about: document.getElementById("about-view"), + snacks: document.getElementById("snacks-view"), + cart: document.getElementById("cart-view"), + checkout: document.getElementById("checkout-view"), + account: document.getElementById("account-view") + }; + + const ui = { + logo: document.getElementById("logo-home"), + linkFilme: document.getElementById("link-filme"), + linkSnacks: document.getElementById("link-snacks"), + linkAbout: document.getElementById("link-about"), + linkCart: document.getElementById("link-cart"), + linkAccount: document.getElementById("link-account"), + themeToggle: document.getElementById("theme-toggle"), + heroBookingBtn: document.getElementById("hero-booking-btn"), + heroSlider: document.getElementById("hero-slider"), + heroDots: document.getElementById("hero-dots"), + heroTitle: document.getElementById("hero-title"), + heroText: document.getElementById("hero-text"), + nowRunningRow: document.getElementById("now-running-row"), + movieProgramList: document.getElementById("movie-program-list"), + checkoutBtn: document.getElementById("btn-checkout-final"), + backHomeBtn: document.getElementById("btn-back-home"), + snacksView: document.getElementById("snacks-view"), + snackOverlay: document.getElementById("snack-prompt-overlay"), + btnYesSnacks: document.getElementById("btn-yes-snacks"), + btnNoCart: document.getElementById("btn-no-cart"), + bookingModal: document.getElementById("booking-modal"), + closeBookingModalBtn: document.querySelector(".close-btn") + }; + + const checkoutSteps = { + one: document.getElementById("checkout-step-1"), + two: document.getElementById("checkout-step-2"), + three: document.getElementById("checkout-step-3") + }; + + const movieCatalog = [ + { + title: "Zoomania 2", + genre: "Animation", + duration: 148, + fsk: "6", + description: "In Walt Disney Animation Studios’ \"Zoomania 2\" geraten die tierischen Detektive Judy Hopps und Nick Wilde auf die rätselhafte Spur eines geheimnisvollen Reptils, das in Zoomania auftaucht und die Metropole völlig auf den Kopf stellt: Gary De’Snake! ", + poster: "img/zoomania-2.jpg", + backdrop: "img/zoomania-2.jpg" + }, + { + title: "Shelter", + genre: "Action, Abenteuer", + duration: 147, + fsk: "16", + description: "Michael Mason, ein untergetauchter Elite-Agent, lebt auf einer abgelegenen Insel in Schottland. Als er in einem schweren Sturm ein Mädchen vor dem Ertrinken rettet, setzt er damit eine Kette von Ereignissen in Gang, die sein Versteck enttarnen und ihn zurück in die Welt zwingen. Dort muss er nicht nur um das Überleben der Teenagerin kämpfen, sondern sich auch den Dämonen seiner Vergangenheit stellen…", + poster: "img/shelter.jpg", + backdrop: "img/shelter.jpg" + }, + { + title: "Mutiny", + genre: "Action, Abenteuer", + duration: "tba", + fsk: "?", + description: "Als sein milliardenschwerer Boss vor seinen Augen einem Mordkomplott zum Opfer fällt, wird Cole Reed (Jason Statham) für das Verbrechen verantwortlich gemacht. Im Bestreben dessen Tod zu rächen und die Täter zu überführen, gelangt Reed an Bord eines Frachters und stößt dabei auf eine internationale Verschwörung. Im Alleingang startet Cole eine gnadenlose Racheaktion auf hoher See…", + poster: "img/mutiny.jpg", + backdrop: "img/mutiny.jpg" + }, + { + title: "Der Austronaut - Project Hail Mary", + genre: "Sci-Fi", + duration: 156, + fsk: "12", + description: "Der Naturwissenschaftslehrer Ryland Grace wacht eines Tages auf einem Raumschiff auf - Lichtjahre von zu Hause entfernt und ohne Erinnerung daran, wer er ist oder wie er dorthin gekommen ist.", + poster: "img/derAustronaut.jpg", + backdrop: "img/derAustronaut.jpg" + }, + { + title: "Der Super Mario Galaxy Film", + genre: "Animation", + duration: 98, + fsk: "6", + description: "''Der Super Mario Galaxy Film'' ist der neue Animationsfilm, basierend auf der Welt von „Super Mario Bros.“!", + poster: "img/mariogalaxy.jpg", + backdrop: "img/mariogalaxy.jpg" + }, + { + title: "Hoppers", + genre: "Animation", + duration: 105, + fsk: "6", + description: "In Disney Pixars ''Hoppers'' hoppt Tierfreundin Mabel mithilfe neuester Technologie in einen Roboterbiber und macht die Tierwelt (un)sicher! ", + poster: "img/hoppers.jpg", + backdrop: "img/hoppers.jpg" + }, + { + title: "Solo Mio", + genre: "Lovestory, Komödie", + duration: 96, + fsk: "12", + description: "Nachdem er in Rom am Altar stehen gelassen wurde, beschließt ein Mann, allein in die Flitterwochen zu fahren.", + poster: "img/solomio.png", + backdrop: "img/solomio.png" + }, + { + title: "The Mandalorian and Grogu", + genre: "Action, Abenteuer", + duration: 'tba', + fsk: "?", + description: "Während die Neue Republik daran arbeitet, alles zu schützen, wofür die Rebellion gekämpft hat, sichern sie sich die Unterstützung des legendären mandalorianischen Kopfgeldjägers Din Djarin und seines jungen Lehrlings Grogu. ", + poster: "img/mandalorian.jpeg", + backdrop: "img/mandalorian.jpeg" + }, + { + title: "Glennkill - Ein Schafskrimi", + genre: "Krimi, Komödie", + duration: 'tba', + fsk: "?", + description: "Schäfer George liest seinen geliebten Schafen jeden Abend Krimis vor und nimmt an, dass sie kein Wort davon verstehen. Doch als ein mysteriöser Vorfall das friedliche Leben auf der Farm durchbricht, wird den Schafen bewusst, dass sie selbst nun die Ermittlungen übernehmen müssen. Also folgen sie der Spur der Beweise und machen menschliche Verdächtige ausfindig.", + poster: "img/glennkill.jpg", + backdrop: "img/glennkill.jpg" + }, + { + title: "Masters of the Universe", + genre: "Action, Science-Fiction", + duration: 'tba', + fsk: "?", + description: "Nach 15 Jahren der Trennung führt das Schwert der Macht Prinz Adam zurück nach Eternia und er entdeckt, dass seine Heimat unter der Herrschaft von Skeletor in Trümmern liegt.", + poster: "img/masteruniverse.jpg", + backdrop: "img/masteruniverse.jpg" + }, + { + title: "Minions and Monsters", + genre: "Animation, Familie", + duration: 'tba', + fsk: "?", + description: "MINIONS & MONSTER erzählt die abgefahrene, aberwitzige und natürlich absolut wahre Geschichte von den Minions und wie sie Hollywood erobern, Filmstars werden, alles verlieren, Monster auf die Welt loslassen und sich dann heldenhaft daranmachen, den Planeten vor genau dem Chaos zu retten, das sie selbst angerichtet haben. ", + poster: "img/minionsmonsters.jpg", + backdrop: "img/minionsmonsters.jpg" + }, + { + title: "Spider Man - Brand New Day", + genre: "Action", + duration: 'tba', + fsk: "?", + description: "Spider-Man: Brand New Day erzählt die Geschichte von Peter Parker, der sich mit den Herausforderungen eines neuen Lebens auseinandersetzt.", + poster: "img/spidermannewday.jpg", + backdrop: "img/spidermannewday.jpg" + }, + { + title: "Scream VII", + genre: "Horror", + duration: 'tba', + fsk: "18", + description: "Als in der ruhigen Stadt, in der Sidney Prescott sich ein neues Leben aufgebaut hat, ein neuer Ghostface-Killer auftaucht, werden ihre schlimmsten Befürchtungen wahr, denn ihre Tochter ist sein nächstes Ziel.", + poster: "img/screamvii.jpg", + backdrop: "img/screamvii.jpg" + }, + { + title: "Blade Runner 2049", + genre: "Science-Fiction, Action", + duration: "163", + fsk: "16", + description: "30 Jahre nach den Ereignissen des ersten Films fördert ein neuer Blade Runner, der LAPD Polizeibeamte K (Ryan Gosling), ein lange unter Verschluss gehaltenes Geheimnis zu Tage, welches das Potential hat, die noch vorhandenen gesellschaftlichen Strukturen in Chaos zu stürzen. Die Entdeckungen von K führen ihn auf die Suche nach Rick Deckard (Harrison Ford), einem seit 30 Jahren verschwundenen, ehemaligen LAPD Blade Runner.", + poster: "img/bladerunner2049.jpg", + backdrop: "img/bladerunner2049.jpg" + }, + { + title: "THE FALL GUY", + genre: "Action, Thriller", + duration: 126, + fsk: "16", + description: "Ein angeschlagener Stuntman, der seine besten Zeiten hinter sich hat, findet sich in einem Film mit dem Star wieder, für den er vor langer Zeit gedoubelt hat und der ihn ersetzt hat. Der Haken an der Sache ist jedoch, dass der Star verschwunden ist.", + poster: "img/fallguy.jpg", + backdrop: "img/fallguy.jpg" + }, + { + title: "THE MEG", + genre: "Action, Science-Fiction", + duration: 113, + fsk: "12", + description: "Jonas Taylor ist Tiefseetaucher im geheimen Auftrag der US Navy. Als er mit seiner Crew auf Erkundungstour im Marianengraben unterwegs ist, treffen sie auf einen urzeitlichen, überdimensionierten Hai, einen sogenannten Megalodon. Jonas überlebt die Begegnung als einziger und widmet sich von nun an dem Studium der Paläobiologie. Ein Freund aus der Vergangenheit, Masao Tanaka, bittet Jonas darum mit seiner Hilfe ein U-Boot im Marianengraben zu bergen. Jonas willigt ein, obwohl er noch immer um seine verstorbenen Teammitglieder trauert. Als sich Jonas und Masao dort befinden, sichten sie erneut den Megalodon.", + poster: "img/meg.jpg", + backdrop: "img/meg.jpg" + }, + { + title: "THE MEG 2: Die Tiefe", + genre: "Action, Science-Fiction", + duration: 116, + fsk: "12", + description: "Was ist besser als ein Riesenhai? Ganz einfach: viele Riesenhaie! In diesem spannenden Abenteuer tauchen die Zuschauer gemeinsam mit den weltbekannten Action-Ikonen Jason Statham und Wu Jing in unerforschte Gewässer ein. Als Leiter eines Forschungsteams machen sich die beiden Helden auf einen waghalsigen Erkundungstauchgang in die tiefsten Tiefen des Ozeans. Doch ihre Reise wird jäh unterbrochen, als ein skrupelloser Minenkonzern ihre Mission durchkreuzt und sie sich plötzlich in einem Kampf ums Überleben wiederfinden.", + poster: "img/meg2.jpg", + backdrop: "img/meg2.jpg" + }, + { + title: "Homefront", + genre: "Action, Thriller", + duration: 100, + fsk: "16", + description: "Ex-Drogencop Phil Broker will mit seiner Tochter Maddy in Louisiana ein neues Leben beginnen. Aber dann gerät Maddy auf dem Schulhof in eine Prügelei mit einem Jungen. Dessen Onkel ist ausgerechnet der Crystal-Meth-Dealer Gator Bodine. Als sich Broker nicht einschüchtern lässt und Bodine Hinweise auf seine wahre Identität entdeckt, zögert er nicht, die Feinde aus Brokers Vergangenheit auf seine Spur zu bringen.", + poster: "img/homefront.jpg", + backdrop: "img/homefront.jpg" + }, + { + title: "Cash Truck", + genre: "Action", + duration: 118, + fsk: "16", + description: "" + }, + { + title: "Die Gangster Gang", + genre: "Animation, Komödie", + duration: 100, + fsk: "6", + description: "Mastermind Mr. Wolf, Safeknacker Mr. Snake, Mr. Shark, der Meister der Verwandlung, Mr. Piranha, der Mann fürs Grobe, und die geniale Hackerin Ms. Tarantula sind die „Gangster Gang“, die meistgesuchten Verbrecher von allen. Als die fünf Bösewichte nach einem spektakulären Raub gefasst werden, geloben sie inständig Besserung, um dem Gefängnis zu entgehen, und merken bald, dass Gutes tun gar nicht so schlecht ist. Doch dann bedroht ein neuer Schurke die Stadt ...", + poster: "img/gangstergang.jpg", + backdrop: "img/gangstergang.jpg" + }, + { + title: "Die Gangster Gang 2", + genre: "Animation, Komödie", + duration: 104, + fsk: "6", + description: "Unsere Lieblings-Gangster sind zurück: Im brandneuen, actiongeladenen Abenteuer der gefeierten Antihelden von DreamWorks Animation steht die chaotische, nun geläuterte Gangster Gang endlich auf der guten Seite – wirklich, sie versuchen es! ", + poster: "img/gangstergang2.png", + backdrop: "img/gangstergang2.png" + }, + { + title: "GOAT - Bock auf große Sprünge", + genre: "Animation", + duration: 100, + fsk: "6", + description: "Will, eine kleine Ziege mit großen Träumen, bekommt die einmalige Chance, bei den Profis mitzumachen und Rarball zu spielen - ein hochintensiver, gemischter Vollkontaktsport, der von den schnellsten und wildesten Tieren der Welt dominiert wird. Wills neue Teamkollegen sind nicht begeistert, eine kleine Ziege in ihrem Team zu haben, aber Will ist entschlossen, den Sport zu revolutionieren und ein für alle Mal zu beweisen, dass \"Smalls can ball!\"", + poster: "img/goat.jpg", + backdrop: "img/goat.jpg" + }, + { + title: "TOY STORY", + genre: "Animation", + duration: 81, + fsk: "6", + description: "Als Andys Lieblingspuppe hat Woody im Kinderzimmer das Sagen. Kaum ist der Junge nicht da, erwacht die Cowboy-Figur zum Leben, und mit ihm auch all das andere Spielzeug um ihn herum. Aufgeregt debattiert man über Andys bevorstehenden Geburtstag. Es wird befürchtet, daß ihr Besitzer ein neues Geschenk bevorzugen wird. Und tatsächlich: Der Neuankömmling Buzz Lightyear, ein stolzer Space Ranger, avanciert zu Andys Favoriten. Diese Herabstufung will Woody nicht hinnehmen.", + poster: "img/toystory1.jpg", + backdrop: "img/toystory1.jpg" + }, + { + title: "TOY STORY 2", + genre: "Animation", + duration: 92, + fsk: "6", + description: "Als Woody von einem fiesen Sammler entführt wird macht sich die Puppen-Clique auf, ihren Freund zu befreien - aber schon auf die andere Straßenseite zu gelangen, gestaltet sich schwierig, ganz zu schweigen von den lauernden Gefahren im Spielzeugladen gegenüber: Doppelgänger stellen sich Buzz Lightyear in den Weg, durchgeknallte Barbie-Sirenen drohen die edlen Ritter vom rechten Weg abzubringen, und obendrein entkommt Zurg, der böse Imperator, aus seiner Plastikbox", + poster: "img/toystory2.jpg", + backdrop: "img/toystory2.jpg" + }, + { + title: "TOY STORY 3", + genre: "Animation", + duration: 103, + fsk: "6", + description: "Der Moment des Abschieds ist gekommen: Andy ist den Kinderschuhen entwachsen und macht sich bereit, aufs College zu gehen. Für sein stets getreues Spielzeug hat er keine Verwendung mehr. Andys Mutter spendet die Spielsachen der Kindertagesstätte Sunnyside. Doch dieses angebliche Paradies entpuppt sich nach zuerst freundlicher Aufnahme durch die alteingesessenen Spielzeuge bald zum Gefängnis für die Freunde. Ein ausgeklügelter Ausbruchsplan wird ausgearbeitet - die Zeit drängt, denn hier geht nicht alles mit rechten Dingen zu.", + poster: "img/toystory3.jpg", + backdrop: "img/toystory3.jpg" + }, + { + title: "TOY STORY 4 - Alles hört auf kein Kommando", + genre: "Animation", + duration: 99, + fsk: "6", + description: "Woody wusste immer um seinen Platz im (Spielzeug-)Universum, seine Priorität war es, sich um „sein“ Kind zu kümmern, sei es sein alter Kindheits-Freund Andy oder die süße Bonnie. Aber als Bonnie ein äußerst widerspenstiges neues Spielzeug in ihre Sammlung aufnimmt, hat Woodys ruhiger gewordenes Kinderzimmerleben ein Ende. Denn Forky hat eine schwere Identitätskrise und ist davon überzeugt, kein Spielzeug zu sein. Zusammen mit alten und neuen Freunden erleben Forky und Woody den Roadtrip ihres Lebens und lernen dabei, dass die Welt für ein Spielzeug viel größer ist als jemals gedacht.", + poster: "img/toystory4.jpg", + backdrop: "img/toystory4.jpg" + + }, + { + title: "TOY STORY 5", + genre: "Animation", + duration: 'tba', + fsk: "6", + description: "Die Spielzeuge sind zurück und dieses Mal werden die Aufgaben von Buzz Lightyear, Woody, Jessie und dem Rest der Bande herausgefordert, als sie mit Lilypad (Stimme von Greta Lee) konfrontiert werden, einem brandneuen Tablet-Gerät, das mit seinen eigenen störenden Ideen darüber kommt, was das Beste für ihr Kind Bonnie ist. Wird die Spielzeit jemals wieder dieselbe sein?", + poster: "img/toystory5.png", + backdrop: "img/toystory5.png" + }, + { + title: "Die Monster AG - Monsters Inc.", + genre: "Animation, Familie", + duration: 92, + fsk: "6", + description: "In der Monster-AG-Fabrik gehen die Bösewichte eifrig ihrer Arbeit nach: Über Schranktüren schleichen sie sich in Kinderzimmer ein und sammeln die Angstschreie ihrer Bewohner, die den Strom für Monstropolis liefern. Ungekrönter Star unter den einfallsreichen \"Schreckeinjagern\" ist Sully. Dem passiert eines Tages ein folgenschweres Missgeschick: Das kleine Mädchen Boo, dem er wie gewohnt einen kräftigen Schock versetzen will, verkrallt sich in sein Fell. Als er dann mit dem Kind in die Fabrik zurückkehrt, bricht das totale Chaos aus...", + poster: "img/monsterag.png", + backdrop: "img/monsterag.png" + }, + { + title: "Die Monster Uni - Monsters University", + genre: "Animation, Familie", + duration: 104, + fsk: "6", + description: "Auch Monster müssen lernen, wie man andere wirkungsvoll erschreckt. Genau hierfür gibt es die Monster-Universität, einen Ort an dem aus harmlosen kleinen Monstern die ganz großen Schrecken gemacht werden. Exakt davon träumt Mike schon die ganze Zeit, deshalb schreibt er sich direkt für die Scheckwissenschaften ein. Nun ist er ein Student und lernt viele neue Monster kennen, die wie er den Studiengang schaffen wollen. Doch das ist nicht so einfach wie anfangs erst gedacht, denn neben guten Noten geht es auch um das Ansehen an der Uni. So bricht zwischen Mike und seinem neuen Bekannten Sulley ein wahrer Kampf um die besseren Schrecker aus.", + poster: "img/monsteruni.jpg", + backdrop: "img/monsteruni.jpg" + } + ]; + + const hallRotation = ["IMAX", "Deluxe 1", "Kino 1", "Kino 2"]; + const timePatterns = [ + ["13:00", "15:20", "17:40", "20:00", "22:20"], + ["13:00", "14:50", "17:10", "19:30", "21:50"], + ["13:00", "15:10", "17:30", "19:50", "22:10"], + ["13:00", "16:00", "18:20", "20:40"] + ]; + + let movieProgram = []; + let heroItems = []; + let heroIndex = 0; + let heroTimer = null; + + const weekdayShort = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]; + + const hideAllViews = () => { + Object.values(views).forEach((view) => view?.classList.add("hidden")); + document.getElementById("about-tech-modal")?.classList.add("hidden"); + document.body.style.overflow = "auto"; + }; + + const showHome = () => { + hideAllViews(); + views.hero?.classList.remove("hidden"); + views.moviesGrid?.classList.remove("hidden"); + document.getElementById("about-tech-modal")?.classList.add("hidden"); + document.body.style.overflow = "auto"; + window.scrollTo({ top: 0, behavior: "smooth" }); + }; + + const showMovieList = (programIndexToFocus = null) => { + hideAllViews(); + views.list?.classList.remove("hidden"); + + if (programIndexToFocus === null) { + window.scrollTo({ top: 0, behavior: "smooth" }); + return; + } + + const target = views.list?.querySelector(`[data-program-index="${programIndexToFocus}"]`); + if (target) { + target.scrollIntoView({ behavior: "smooth", block: "start" }); + target.classList.add("flash-focus"); + setTimeout(() => target.classList.remove("flash-focus"), 1200); + } + }; + + const showStaticView = (viewElement) => { + if (!viewElement) { + return; + } + + hideAllViews(); + viewElement.classList.remove("hidden"); + window.scrollTo({ top: 0, behavior: "smooth" }); + }; + + const showCheckoutStart = () => { + if (!cart.length) { + alert("Dein Warenkorb ist leer."); + return; + } + + hideAllViews(); + views.checkout?.classList.remove("hidden"); + checkoutSteps.one?.classList.remove("hidden"); + checkoutSteps.two?.classList.add("hidden"); + checkoutSteps.three?.classList.add("hidden"); + renderCheckout?.(); + window.scrollTo(0, 0); + }; + + const closeBookingModal = () => { + ui.bookingModal?.classList.add("hidden"); + }; + + const escapeHtml = (value) => String(value || "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + + const formatDateShort = (dateObj) => { + const day = String(dateObj.getDate()).padStart(2, "0"); + const month = String(dateObj.getMonth() + 1).padStart(2, "0"); + return `${day}.${month}.`; + }; + + const buildDayMeta = (offset) => { + const date = new Date(); + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() + offset); + + const weekday = weekdayShort[date.getDay()]; + const formattedDate = formatDateShort(date); + + if (offset === 0) { + return { + offset, + date, + short: "Heute", + long: `Heute, ${formattedDate}` + }; + } + + if (offset === 1) { + return { + offset, + date, + short: "Morgen", + long: `Morgen, ${formattedDate}` + }; + } + + return { + offset, + date, + short: weekday, + long: `${weekday}, ${formattedDate}` + }; + }; + + const buildScheduleForMovie = (movieIndex) => { + return Array.from({ length: 7 }, (_, dayOffset) => { + const dayMeta = buildDayMeta(dayOffset); + const pattern = timePatterns[(movieIndex + dayOffset) % timePatterns.length]; + const desiredCount = 4 + ((movieIndex + dayOffset) % 2); + const showCount = Math.min(pattern.length, desiredCount); + + const showings = pattern.slice(0, showCount).map((time, slotIndex) => { + const hall = hallRotation[(movieIndex + dayOffset + slotIndex) % hallRotation.length]; + return { time, hall }; + }); + + return { + ...dayMeta, + showings + }; + }); + }; + + const buildMovieProgram = () => { + movieProgram = movieCatalog.map((movie, movieIndex) => ({ + ...movie, + schedule: buildScheduleForMovie(movieIndex) + })); + heroItems = movieProgram.slice(0, 5); + }; + + const setHeroSlide = (index) => { + if (!heroItems.length || !ui.heroSlider) { + return; + } + + heroIndex = (index + heroItems.length) % heroItems.length; + + ui.heroSlider.querySelectorAll(".hero-slide").forEach((slide, slideIndex) => { + slide.classList.toggle("active", slideIndex === heroIndex); + }); + + ui.heroDots?.querySelectorAll(".hero-dot").forEach((dot, dotIndex) => { + dot.classList.toggle("active", dotIndex === heroIndex); + }); + + const activeMovie = heroItems[heroIndex]; + if (ui.heroTitle) { + ui.heroTitle.textContent = activeMovie.title; + } + if (ui.heroText) { + ui.heroText.textContent = `${activeMovie.genre} • ${activeMovie.duration} Min. • Heute erste Vorstellung um 13:00 Uhr.`; + } + }; + + const renderHero = () => { + if (!ui.heroSlider || !heroItems.length) { + return; + } + + ui.heroSlider.innerHTML = heroItems.map((movie, index) => ` +
+ `).join(""); + + if (ui.heroDots) { + ui.heroDots.innerHTML = heroItems.map((_, index) => ` + + `).join(""); + + ui.heroDots.addEventListener("click", (event) => { + const dot = event.target.closest(".hero-dot"); + if (!dot) { + return; + } + + const nextIndex = Number(dot.dataset.heroIndex || 0); + setHeroSlide(nextIndex); + + if (heroTimer) { + clearInterval(heroTimer); + heroTimer = setInterval(() => setHeroSlide(heroIndex + 1), 6500); + } + }); + } + + setHeroSlide(0); + + if (heroTimer) { + clearInterval(heroTimer); + } + + heroTimer = setInterval(() => { + setHeroSlide(heroIndex + 1); + }, 6500); + }; + + const renderNowRunningRow = () => { + if (!ui.nowRunningRow) { + return; + } + + ui.nowRunningRow.innerHTML = movieProgram.map((movie, index) => /*html*/` +
+ ${escapeHtml(movie.title)} +
+

${escapeHtml(movie.title)}

+

${escapeHtml(movie.genre)}

+ +
+
+ `).join(""); + }; + + const renderScheduleRows = (programIndex, dayIndex) => { + const movie = movieProgram[programIndex]; + if (!movie) { + return; + } + + const day = movie.schedule[dayIndex]; + const body = document.getElementById(`schedule-body-${programIndex}`); + if (!body || !day) { + return; + } + + body.innerHTML = day.showings.map((showing) => /*html*/` + + `).join(""); + }; + + const renderMovieProgramList = () => { + if (!ui.movieProgramList) { + return; + } + + ui.movieProgramList.innerHTML = movieProgram.map((movie, programIndex) => { + const dayTabs = movie.schedule.map((day, dayIndex) => /*html*/` + + `).join(""); + + return /*html*/` +
+
+ ${escapeHtml(movie.title)} + ${escapeHtml(movie.fsk)} +
+
+
+

${escapeHtml(movie.title)}

+ ${movie.duration} Min. | ${escapeHtml(movie.genre)} | FSK: ${escapeHtml(movie.fsk)} +
+

${escapeHtml(movie.description)}

+ +
${dayTabs}
+ +
+
+ TagKinosaalUhrzeit +
+
+
+
+
+ `; + }).join(""); + + movieProgram.forEach((_, programIndex) => { + renderScheduleRows(programIndex, 0); + }); + }; + + const initRevealAnimations = () => { + const revealElements = Array.from(document.querySelectorAll(".reveal-on-scroll")); + if (!revealElements.length) { + return; + } + + if (!("IntersectionObserver" in window)) { + revealElements.forEach((element) => element.classList.add("is-visible")); + return; + } + + const observer = new IntersectionObserver((entries, obs) => { + entries.forEach((entry) => { + if (!entry.isIntersecting) { + return; + } + + entry.target.classList.add("is-visible"); + obs.unobserve(entry.target); + }); + }, { threshold: 0.2 }); + + revealElements.forEach((element) => observer.observe(element)); + }; + + const renderMovieExperience = () => { + buildMovieProgram(); + renderHero(); + renderNowRunningRow(); + renderMovieProgramList(); + initRevealAnimations(); + }; + + const bindNavigation = () => { + ui.logo?.addEventListener("click", showHome); + + ui.linkFilme?.addEventListener("click", (event) => { + event.preventDefault(); + showMovieList(); + }); + + ui.linkSnacks?.addEventListener("click", (event) => { + event.preventDefault(); + showStaticView(views.snacks); + }); + + ui.linkAbout?.addEventListener("click", (event) => { + event.preventDefault(); + showStaticView(views.about); + }); + + ui.linkCart?.addEventListener("click", (event) => { + event.preventDefault(); + hideAllViews(); + views.cart?.classList.remove("hidden"); + renderCart?.(); + }); + + ui.linkAccount?.addEventListener("click", (event) => { + event.preventDefault(); + hideAllViews(); + views.account?.classList.remove("hidden"); + + const isUserLoggedIn = typeof currentUser !== "undefined" && currentUser; + if (isUserLoggedIn && typeof openAccountDashboard === "function") { + openAccountDashboard(); + } + }); + + ui.heroBookingBtn?.addEventListener("click", () => { + showMovieList(); + }); + + ui.checkoutBtn?.addEventListener("click", showCheckoutStart); + ui.backHomeBtn?.addEventListener("click", showHome); + }; + + const bindProgramActions = () => { + views.moviesGrid?.addEventListener("click", (event) => { + const trigger = event.target.closest(".open-program-btn"); + if (!trigger) { + return; + } + + const programIndex = Number(trigger.dataset.programIndex || 0); + showMovieList(programIndex); + }); + + ui.movieProgramList?.addEventListener("click", (event) => { + const dayButton = event.target.closest(".program-day-tab"); + if (!dayButton) { + return; + } + + const programIndex = Number(dayButton.dataset.programIndex || 0); + const dayIndex = Number(dayButton.dataset.dayIndex || 0); + + const tabRow = dayButton.closest(".program-day-tabs"); + tabRow?.querySelectorAll(".program-day-tab").forEach((tab) => tab.classList.remove("active")); + dayButton.classList.add("active"); + + renderScheduleRows(programIndex, dayIndex); + }); + }; + + const bindHomeInfoNavigation = () => { + const openButtons = Array.from(document.querySelectorAll("[data-home-view-open]")); + const backButtons = Array.from(document.querySelectorAll("[data-go-home]")); + const aboutOpenButtons = Array.from(document.querySelectorAll("[data-about-modal-open]")); + const aboutCloseButtons = Array.from(document.querySelectorAll("[data-about-modal-close]")); + const aboutModal = document.getElementById("about-tech-modal"); + + if (!openButtons.length) { + return; + } + + const targetMap = { + "halls-view": views.halls, + "dbox-view": views.dbox, + "collectors-view": views.collectors + }; + + openButtons.forEach((button) => { + button.addEventListener("click", () => { + const targetId = button.getAttribute("data-home-view-open"); + const target = targetId ? targetMap[targetId] : null; + if (target) { + showStaticView(target); + } + }); + }); + + backButtons.forEach((button) => { + button.addEventListener("click", () => { + showHome(); + }); + }); + + aboutOpenButtons.forEach((button) => { + button.addEventListener("click", () => { + const targetId = button.getAttribute("data-about-modal-open"); + if (targetId === "about-tech-modal" && aboutModal) { + aboutModal.classList.remove("hidden"); + document.body.style.overflow = "hidden"; + } + }); + }); + + aboutCloseButtons.forEach((button) => { + button.addEventListener("click", () => { + aboutModal?.classList.add("hidden"); + document.body.style.overflow = "auto"; + }); + }); + + aboutModal?.addEventListener("click", (event) => { + if (event.target === aboutModal) { + aboutModal.classList.add("hidden"); + document.body.style.overflow = "auto"; + } + }); + + document.addEventListener("keydown", (event) => { + if (event.key === "Escape" && aboutModal && !aboutModal.classList.contains("hidden")) { + aboutModal.classList.add("hidden"); + document.body.style.overflow = "auto"; + } + }); + }; + + const initThemeToggle = () => { + if (!ui.themeToggle) { + return; + } + + const THEME_KEY = "eagleTheme"; + + const applyTheme = (theme) => { + const isLight = theme === "light"; + document.body.classList.toggle("theme-light", isLight); + document.body.classList.toggle("theme-dark", !isLight); + ui.themeToggle.classList.toggle("is-light", isLight); + localStorage.setItem(THEME_KEY, isLight ? "light" : "dark"); + }; + + const storedTheme = localStorage.getItem(THEME_KEY); + applyTheme(storedTheme === "light" ? "light" : "dark"); + + ui.themeToggle.addEventListener("click", () => { + const nextTheme = document.body.classList.contains("theme-light") ? "dark" : "light"; + applyTheme(nextTheme); + }); + }; + + const bindAccountActions = () => { + const registerModal = document.getElementById("register-modal"); + const forgotModal = document.getElementById("forgot-modal"); + const forgotEmailInput = document.getElementById("forgot-email"); + const resetMessage = document.getElementById("reset-message"); + const loginError = document.getElementById("login-error"); + const loginEmailInput = document.getElementById("login-email"); + const loginPasswordInput = document.getElementById("login-password"); + + const openModal = (modal) => modal?.classList.remove("hidden"); + const closeModal = (modal) => modal?.classList.add("hidden"); + const triggerLogin = () => { + loginError?.classList.add("hidden"); + if (typeof loginUser === "function") { + loginUser(); + } + }; + + document.getElementById("btn-open-register")?.addEventListener("click", () => { + openModal(registerModal); + }); + + document.getElementById("btn-close-register")?.addEventListener("click", () => { + closeModal(registerModal); + }); + + document.getElementById("btn-register-save")?.addEventListener("click", () => { + if (typeof registerUser === "function") { + registerUser(); + } + }); + + document.getElementById("btn-login-account")?.addEventListener("click", triggerLogin); + + [loginEmailInput, loginPasswordInput].forEach((input) => { + input?.addEventListener("keydown", (event) => { + if (event.key !== "Enter") { + return; + } + + event.preventDefault(); + triggerLogin(); + }); + }); + + document.getElementById("btn-forgot-password")?.addEventListener("click", () => { + if (forgotEmailInput) { + forgotEmailInput.value = ""; + } + resetMessage?.classList.add("hidden"); + openModal(forgotModal); + }); + + document.getElementById("btn-close-forgot")?.addEventListener("click", () => { + closeModal(forgotModal); + }); + + document.getElementById("btn-send-reset")?.addEventListener("click", () => { + const email = forgotEmailInput?.value.trim() || ""; + if (!email || !email.includes("@")) { + alert("Bitte gib eine gueltige E-Mail-Adresse ein."); + return; + } + + if (resetMessage) { + resetMessage.textContent = "Wenn ein Konto existiert, wurde ein Reset-Code simuliert versendet."; + resetMessage.classList.remove("hidden"); + } + }); + + registerModal?.addEventListener("click", (event) => { + if (event.target === registerModal) { + closeModal(registerModal); + } + }); + + forgotModal?.addEventListener("click", (event) => { + if (event.target === forgotModal) { + closeModal(forgotModal); + } + }); + + document.addEventListener("keydown", (event) => { + if (event.key === "Escape") { + closeModal(registerModal); + closeModal(forgotModal); + } + }); + }; + + const bindGlobalDocumentClicks = () => { + document.addEventListener("click", (event) => { + if (event.target.classList.contains("opt-btn")) { + const optionGroup = event.target.parentElement; + optionGroup?.querySelectorAll(".opt-btn").forEach((button) => button.classList.remove("active")); + event.target.classList.add("active"); + } + + const deleteBtn = event.target.closest(".btn-delete-item"); + if (deleteBtn?.dataset.key) { + const row = deleteBtn.closest(".cart-item-row"); + if (row) { + row.classList.add("slide-out-left"); + row.querySelectorAll("button").forEach((button) => { + button.disabled = true; + }); + + setTimeout(() => { + removeFromCartByKey(deleteBtn.dataset.key); + }, 380); + } else { + removeFromCartByKey(deleteBtn.dataset.key); + } + return; + } + + const chip = event.target.closest(".time-chip"); + if (chip) { + const movieFromData = chip.getAttribute("data-movie"); + const movieCard = chip.closest(".movie-card, .detailed-card, .program-card"); + const movie = movieFromData || movieCard?.querySelector("h2, h3")?.innerText || "Film"; + const hall = chip.getAttribute("data-hall"); + const time = chip.getAttribute("data-time"); + + if (hall && time && typeof openBooking === "function") { + openBooking(movie, hall, time); + } + } + + const qtyBtn = event.target.closest(".btn-qty"); + if (!qtyBtn) { + return; + } + + const action = qtyBtn.dataset.action; + const key = qtyBtn.dataset.key; + if (!action || !key) { + return; + } + + const relatedItem = cart.find((item) => { + const infoText = item.category === "movie" + ? `Sitz: ${item.seatId} (${item.hall})` + : item.time; + return `${item.title}-${item.hall}-${infoText}` === key; + }); + + if (!relatedItem || relatedItem.category === "movie") { + return; + } + + if (action === "plus") { + cart.push({ ...relatedItem, id: Date.now() + Math.random() }); + } else { + const keyList = cart.map((item) => { + const infoText = item.category === "movie" + ? `Sitz: ${item.seatId} (${item.hall})` + : item.time; + return `${item.title}-${item.hall}-${infoText}`; + }); + const lastMatch = keyList.lastIndexOf(key); + + if (lastMatch !== -1) { + cart.splice(lastMatch, 1); + } + } + + saveCart?.(); + renderCart?.(); + }); + }; + + const bindSnacksActions = () => { + ui.snacksView?.addEventListener("click", (event) => { + const sizeChip = event.target.closest(".size-chip"); + if (!sizeChip) { + return; + } + + const snackCard = sizeChip.closest(".snack-card"); + if (!snackCard) { + return; + } + + const snackTitle = snackCard.querySelector("h3, h2")?.innerText || "Snack"; + const snackImg = snackCard.querySelector("img")?.src || ""; + const priceSpan = sizeChip.querySelector("span"); + const rawPriceText = (priceSpan ? priceSpan.innerText : sizeChip.innerText) + .replace("EUR", "") + .replace("€", "") + .replace(",", ".") + .trim(); + const priceVal = parseFloat(rawPriceText) || 0; + const sizeVal = sizeChip.innerText.replace(priceSpan?.innerText || "", "").trim() || "Standard"; + const activeOption = snackCard.querySelector(".opt-btn.active"); + const variantVal = activeOption ? activeOption.innerText : "Normal"; + + cart.push({ + id: Date.now() + Math.random(), + category: "snack", + title: snackTitle, + hall: sizeVal, + time: variantVal, + type: "SNACK", + price: priceVal, + img: snackImg + }); + + saveCart?.(); + + const originalHtml = sizeChip.innerHTML; + sizeChip.innerHTML = "Hinzugefügt!"; + setTimeout(() => { + sizeChip.innerHTML = originalHtml; + }, 800); + }); + + document.querySelectorAll(".tab-btn").forEach((button) => { + button.addEventListener("click", () => { + document.querySelectorAll(".tab-btn").forEach((tab) => tab.classList.remove("active")); + button.classList.add("active"); + + document.querySelectorAll(".snack-category").forEach((category) => category.classList.add("hidden")); + document.getElementById(button.dataset.target)?.classList.remove("hidden"); + }); + }); + }; + + const bindOverlayActions = () => { + ui.btnYesSnacks?.addEventListener("click", () => { + ui.snackOverlay?.classList.add("hidden"); + hideAllViews(); + views.snacks?.classList.remove("hidden"); + document.body.style.overflow = "auto"; + }); + + ui.btnNoCart?.addEventListener("click", () => { + ui.snackOverlay?.classList.add("hidden"); + hideAllViews(); + views.cart?.classList.remove("hidden"); + renderCart?.(); + document.body.style.overflow = "auto"; + }); + }; + + const bindBookingModalClose = () => { + ui.closeBookingModalBtn?.addEventListener("click", closeBookingModal); + + ui.bookingModal?.addEventListener("click", (event) => { + if (event.target === ui.bookingModal) { + closeBookingModal(); + } + }); + }; + + window.removeFromCartByKey = function removeFromCartByKey(key) { + cart = cart.filter((item) => { + const infoText = item.category === "movie" + ? `Sitz: ${item.seatId} (${item.hall})` + : item.time; + return `${item.title}-${item.hall}-${infoText}` !== key; + }); + + saveCart?.(); + renderCart?.(); + }; + + renderMovieExperience(); + initThemeToggle(); + bindNavigation(); + bindProgramActions(); + bindHomeInfoNavigation(); + bindAccountActions(); + bindGlobalDocumentClicks(); + bindSnacksActions(); + bindOverlayActions(); + bindBookingModalClose(); + + updateCartBadge?.(); + renderCheckout?.(); +}); diff --git a/style.css b/style.css index 2fe1182..c355eec 100644 --- a/style.css +++ b/style.css @@ -2902,15 +2902,15 @@ body { } .inline-halls .inline-media { - background-image: linear-gradient(120deg, rgba(0, 113, 227, 0.3), rgba(7, 10, 16, 0.55)), url('img/placeholder-hall.jpg'); + background-image: linear-gradient(120deg, rgba(0, 113, 227, 0.3), rgba(7, 10, 16, 0.55)), url('img/shelter.jpg'); } .inline-dbox .inline-media { - background-image: linear-gradient(120deg, rgba(255, 176, 0, 0.2), rgba(8, 12, 18, 0.62)), url('img/placeholder-dbox.jpg'); + background-image: linear-gradient(120deg, rgba(255, 176, 0, 0.2), rgba(8, 12, 18, 0.62)), url('img/dbox.jpg'); } .inline-collectors .inline-media { - background-image: linear-gradient(120deg, rgba(185, 124, 255, 0.15), rgba(8, 12, 18, 0.62)), url('img/placeholder-collector.jpg'); + background-image: linear-gradient(120deg, rgba(185, 124, 255, 0.15), rgba(8, 12, 18, 0.62)), url('img/popcorn.jpg'); } .inline-content { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e3d7c42 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,45 @@ +{ + // Visit https://aka.ms/tsconfig to read more about this file + "compilerOptions": { + // File Layout + "rootDir": "./src", + "outDir": "./dist", + + // Environment Settings + // See also https://aka.ms/tsconfig/module + "module": "ES2020", + "target": "ES2021", + "types": [], + // For nodejs: + // "lib": ["esnext"], + // "types": ["node"], + // and npm install -D @types/node + + // Other Outputs + "sourceMap": true, + "declaration": true, + "declarationMap": true, + + // Stricter Typechecking Options + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + + // Style Options + // "noImplicitReturns": true, + // "noImplicitOverride": true, + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "noFallthroughCasesInSwitch": true, + // "noPropertyAccessFromIndexSignature": true, + + // Recommended Options + "strict": true, + "jsx": "react-jsx", + "verbatimModuleSyntax": true, + "isolatedModules": true, + "noUncheckedSideEffectImports": true, + "moduleDetection": "force", + "skipLibCheck": true, + }, + "include": ["src/*"] +}