├── .gitignore
├── .hintrc
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── client
├── css
│ └── index.css
├── img
│ └── logo.png
└── script
│ ├── dom.js
│ ├── film-list.js
│ └── index.js
├── package-lock.json
├── package.json
└── server
├── context.js
├── controllers
├── films.js
└── home.js
├── data
└── films.js
├── handlebars.js
├── index.js
├── routes.js
└── views
├── home.hbs
├── layouts
└── main.hbs
└── partials
├── film-card.hbs
├── film-detail.css
├── film-detail.hbs
├── film-list.css
├── film-list.hbs
├── structured-card.css
├── structured-card.hbs
├── ui-card.css
└── ui-card.hbs
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules/
3 |
4 | *.tsbuildinfo
5 |
6 | .DS_Store
--------------------------------------------------------------------------------
/.hintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "development"
4 | ],
5 | "hints": {
6 | "compat-api/css": [
7 | "default",
8 | {
9 | "ignore": [
10 | "contain"
11 | ]
12 | }
13 | ]
14 | }
15 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "node_modules": true
4 | },
5 | "cSpell.words": [
6 | "htmx",
7 | "shadowrootmode"
8 | ]
9 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Rob Eisenberg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Server-first Web Components with DSD, HTMX, and Islands
2 |
3 | A demo leveraging common server rendering approaches to enable rendering web components on the server, rather than on the client. This approach enables encapsulating HTML and CSS for each view, declaratively applying common behaviors to views via HTMX, and leveraging browser standards to add custom JavaScript islands as needed to any part of the UI.
4 |
5 | To learn more about Web Components, please consider purchasing [my Web Component Engineering course](https://bluespire.com/p/web-component-engineering). 13 modules, 170+ videos, and an interactive learning app guide you through DOM APIs, Web Components, modular CSS, accessibility, forms, design systems, tools, and more. Purchasing the course helps support my writing, web standards work, and open source.
6 |
7 | For group discounts, please reach out to sales@bluespire.com.
8 |
9 | ## Machine Setup
10 |
11 | 1. [Download and install Node.js LTS v20.16.0](https://nodejs.org/en/download/package-manager) or higher.
12 |
13 | ## Repo Setup
14 |
15 | 1. On the command line, execute `npm i` to install dependencies.
16 |
17 | ## Running the App
18 |
19 | 1. On the command line, execute `npm run server` to run the web server.
20 | 2. Visit http://localhost:3000/ in a browser to view the app.
21 |
22 | ## Dependencies
23 |
24 | ### Server
25 |
26 | * [Node.js](https://nodejs.org/)
27 | * [Express](https://expressjs.com/)
28 | * [Handlebars](https://handlebarsjs.com/) and [Express Handlebars](https://www.npmjs.com/package/express-handlebars)
29 |
30 | > [!IMPORTANT]
31 | > While this demo uses Node.js, Express, and Handlebars, nearly every major web server/framework today supports the concepts of views, partials, helpers, and request/execution context, that are used to make this approach to web development possible. As a result, pretty much everything shown here should translate in a straightforward way to other platforms like .NET, Ruby, Java, etc.
32 |
33 | ### Client
34 |
35 | * W3C Standard [Web Components](https://bluespire.com/p/web-component-engineering)
36 | * [HTMX](https://htmx.org/)
37 |
38 | ### Data
39 |
40 | The data used in this demo was adapted from [SWAPI](https://swapi.dev/).
--------------------------------------------------------------------------------
/client/css/index.css:
--------------------------------------------------------------------------------
1 | :not(:defined) > template[shadowrootmode] ~ * {
2 | display: none;
3 | }
4 |
5 | :root {
6 | --spacing-base: .75rem;
7 | --spacing-baseMinus2: calc(.5 * var(--spacing-base));
8 | --gap: var(--spacing-base);
9 | --gap-small: var(--spacing-baseMinus2);
10 |
11 | --stroke-style: solid;
12 | --stroke-thicknessBase: .15rem;
13 | --stroke-thicknessMinus1: calc(.5 * var(--stroke-thicknessBase));
14 |
15 | --typography-sizeBase: 1rem;
16 | --typography-lineHeightBase: 1.3rem;
17 | --typography-sizePlus1: 1.2rem;
18 | --typography-lineHeightPlus1: 1.6rem;
19 | --typography-weightPlus1: 600;
20 |
21 | --border-radius: .375rem;
22 |
23 | --shadow-raised: 0 .25rem .5rem var(--color-shadow);
24 |
25 | --color-accent: #008ed8;
26 | --color-onAccent: #f4f4f4;
27 | --color-onLayerBase: #2c2c2c;
28 | --color-shadow: #00000033;
29 | --color-layerBorder: #d8d8d8;
30 | }
31 |
32 | body {
33 | color: var(--color-onLayerBase);
34 | }
35 |
36 | h1 {
37 | padding-inline-start: var(--gap);
38 | }
39 |
40 | .container {
41 | display: flex;
42 | gap: var(--gap);
43 | }
44 |
45 | @media (width <= 768px) {
46 | .container {
47 | flex-direction: column;
48 | }
49 | }
--------------------------------------------------------------------------------
/client/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EisenbergEffect/server-first-web-components/868bf3c9b6515bbc8cf32c08e98d1ae888d77142/client/img/logo.png
--------------------------------------------------------------------------------
/client/script/dom.js:
--------------------------------------------------------------------------------
1 | import htmx from "https://unpkg.com/htmx.org@2.0.1/dist/htmx.esm.js";
2 |
3 | export const DOM = Object.freeze({
4 | clearHistoryCache() {
5 | localStorage.removeItem('htmx-history-cache');
6 | },
7 |
8 | onHistoryChange(callback) {
9 | globalThis.addEventListener("htmx:pushedIntoHistory", callback);
10 | },
11 |
12 | applyBehaviors(node) {
13 | htmx.process(node);
14 | },
15 |
16 | configure() {
17 | htmx.config.refreshOnHistoryMiss = true;
18 |
19 | function attachShadowRoots(root) {
20 | root.querySelectorAll("template[shadowrootmode]").forEach(template => {
21 | const mode = template.getAttribute("shadowrootmode");
22 | const shadowRoot = template.parentNode.attachShadow({ mode });
23 | shadowRoot.appendChild(template.content);
24 | template.remove();
25 | attachShadowRoots(shadowRoot);
26 | });
27 | }
28 |
29 | if (!HTMLTemplateElement.prototype.hasOwnProperty('shadowRootMode')) {
30 | attachShadowRoots(document);
31 | }
32 |
33 | new MutationObserver((records) => {
34 | for (const record of records) {
35 | for (const node of record.addedNodes) {
36 | if (node instanceof HTMLElement) {
37 | attachShadowRoots(node);
38 | }
39 | }
40 | }
41 | }).observe(document, { childList: true, subtree: true });
42 | }
43 | });
--------------------------------------------------------------------------------
/client/script/film-list.js:
--------------------------------------------------------------------------------
1 | import { DOM } from "./dom.js";
2 |
3 | export class FilmList extends HTMLElement {
4 | #links;
5 |
6 | connectedCallback() {
7 | this.#links = Array.from(this.shadowRoot.querySelectorAll("a"));
8 |
9 | DOM.applyBehaviors(this.shadowRoot);
10 | DOM.onHistoryChange(this.#selectActiveLink);
11 |
12 | this.#selectActiveLink();
13 | }
14 |
15 | #selectActiveLink = () => {
16 | for (const link of this.#links) {
17 | if (link.href.endsWith(location.pathname)) {
18 | link.classList.add("active");
19 | } else {
20 | link.classList.remove("active");
21 | }
22 | }
23 |
24 | DOM.clearHistoryCache();
25 | }
26 |
27 | static define() {
28 | customElements.define("film-list", this);
29 | }
30 | }
--------------------------------------------------------------------------------
/client/script/index.js:
--------------------------------------------------------------------------------
1 | import { FilmList } from "./film-list.js";
2 | import { DOM } from "./dom.js";
3 |
4 | DOM.configure();
5 | FilmList.define();
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-first-web-components",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "server-first-web-components",
9 | "version": "1.0.0",
10 | "license": "MIT",
11 | "dependencies": {
12 | "express": "^4.19.2",
13 | "express-handlebars": "^7.1.3"
14 | }
15 | },
16 | "node_modules/@isaacs/cliui": {
17 | "version": "8.0.2",
18 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
19 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
20 | "dependencies": {
21 | "string-width": "^5.1.2",
22 | "string-width-cjs": "npm:string-width@^4.2.0",
23 | "strip-ansi": "^7.0.1",
24 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
25 | "wrap-ansi": "^8.1.0",
26 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
27 | },
28 | "engines": {
29 | "node": ">=12"
30 | }
31 | },
32 | "node_modules/@pkgjs/parseargs": {
33 | "version": "0.11.0",
34 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
35 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
36 | "optional": true,
37 | "engines": {
38 | "node": ">=14"
39 | }
40 | },
41 | "node_modules/accepts": {
42 | "version": "1.3.8",
43 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
44 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
45 | "dependencies": {
46 | "mime-types": "~2.1.34",
47 | "negotiator": "0.6.3"
48 | },
49 | "engines": {
50 | "node": ">= 0.6"
51 | }
52 | },
53 | "node_modules/ansi-regex": {
54 | "version": "6.0.1",
55 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
56 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
57 | "engines": {
58 | "node": ">=12"
59 | },
60 | "funding": {
61 | "url": "https://github.com/chalk/ansi-regex?sponsor=1"
62 | }
63 | },
64 | "node_modules/ansi-styles": {
65 | "version": "6.2.1",
66 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
67 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
68 | "engines": {
69 | "node": ">=12"
70 | },
71 | "funding": {
72 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
73 | }
74 | },
75 | "node_modules/array-flatten": {
76 | "version": "1.1.1",
77 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
78 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
79 | },
80 | "node_modules/balanced-match": {
81 | "version": "1.0.2",
82 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
83 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
84 | },
85 | "node_modules/body-parser": {
86 | "version": "1.20.2",
87 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
88 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
89 | "dependencies": {
90 | "bytes": "3.1.2",
91 | "content-type": "~1.0.5",
92 | "debug": "2.6.9",
93 | "depd": "2.0.0",
94 | "destroy": "1.2.0",
95 | "http-errors": "2.0.0",
96 | "iconv-lite": "0.4.24",
97 | "on-finished": "2.4.1",
98 | "qs": "6.11.0",
99 | "raw-body": "2.5.2",
100 | "type-is": "~1.6.18",
101 | "unpipe": "1.0.0"
102 | },
103 | "engines": {
104 | "node": ">= 0.8",
105 | "npm": "1.2.8000 || >= 1.4.16"
106 | }
107 | },
108 | "node_modules/brace-expansion": {
109 | "version": "2.0.1",
110 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
111 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
112 | "dependencies": {
113 | "balanced-match": "^1.0.0"
114 | }
115 | },
116 | "node_modules/bytes": {
117 | "version": "3.1.2",
118 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
119 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
120 | "engines": {
121 | "node": ">= 0.8"
122 | }
123 | },
124 | "node_modules/call-bind": {
125 | "version": "1.0.7",
126 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
127 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
128 | "dependencies": {
129 | "es-define-property": "^1.0.0",
130 | "es-errors": "^1.3.0",
131 | "function-bind": "^1.1.2",
132 | "get-intrinsic": "^1.2.4",
133 | "set-function-length": "^1.2.1"
134 | },
135 | "engines": {
136 | "node": ">= 0.4"
137 | },
138 | "funding": {
139 | "url": "https://github.com/sponsors/ljharb"
140 | }
141 | },
142 | "node_modules/color-convert": {
143 | "version": "2.0.1",
144 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
145 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
146 | "dependencies": {
147 | "color-name": "~1.1.4"
148 | },
149 | "engines": {
150 | "node": ">=7.0.0"
151 | }
152 | },
153 | "node_modules/color-name": {
154 | "version": "1.1.4",
155 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
156 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
157 | },
158 | "node_modules/content-disposition": {
159 | "version": "0.5.4",
160 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
161 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
162 | "dependencies": {
163 | "safe-buffer": "5.2.1"
164 | },
165 | "engines": {
166 | "node": ">= 0.6"
167 | }
168 | },
169 | "node_modules/content-type": {
170 | "version": "1.0.5",
171 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
172 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
173 | "engines": {
174 | "node": ">= 0.6"
175 | }
176 | },
177 | "node_modules/cookie": {
178 | "version": "0.6.0",
179 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
180 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
181 | "engines": {
182 | "node": ">= 0.6"
183 | }
184 | },
185 | "node_modules/cookie-signature": {
186 | "version": "1.0.6",
187 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
188 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
189 | },
190 | "node_modules/cross-spawn": {
191 | "version": "7.0.3",
192 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
193 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
194 | "dependencies": {
195 | "path-key": "^3.1.0",
196 | "shebang-command": "^2.0.0",
197 | "which": "^2.0.1"
198 | },
199 | "engines": {
200 | "node": ">= 8"
201 | }
202 | },
203 | "node_modules/debug": {
204 | "version": "2.6.9",
205 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
206 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
207 | "dependencies": {
208 | "ms": "2.0.0"
209 | }
210 | },
211 | "node_modules/define-data-property": {
212 | "version": "1.1.4",
213 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
214 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
215 | "dependencies": {
216 | "es-define-property": "^1.0.0",
217 | "es-errors": "^1.3.0",
218 | "gopd": "^1.0.1"
219 | },
220 | "engines": {
221 | "node": ">= 0.4"
222 | },
223 | "funding": {
224 | "url": "https://github.com/sponsors/ljharb"
225 | }
226 | },
227 | "node_modules/depd": {
228 | "version": "2.0.0",
229 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
230 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
231 | "engines": {
232 | "node": ">= 0.8"
233 | }
234 | },
235 | "node_modules/destroy": {
236 | "version": "1.2.0",
237 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
238 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
239 | "engines": {
240 | "node": ">= 0.8",
241 | "npm": "1.2.8000 || >= 1.4.16"
242 | }
243 | },
244 | "node_modules/eastasianwidth": {
245 | "version": "0.2.0",
246 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
247 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
248 | },
249 | "node_modules/ee-first": {
250 | "version": "1.1.1",
251 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
252 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
253 | },
254 | "node_modules/emoji-regex": {
255 | "version": "9.2.2",
256 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
257 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
258 | },
259 | "node_modules/encodeurl": {
260 | "version": "1.0.2",
261 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
262 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
263 | "engines": {
264 | "node": ">= 0.8"
265 | }
266 | },
267 | "node_modules/es-define-property": {
268 | "version": "1.0.0",
269 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
270 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
271 | "dependencies": {
272 | "get-intrinsic": "^1.2.4"
273 | },
274 | "engines": {
275 | "node": ">= 0.4"
276 | }
277 | },
278 | "node_modules/es-errors": {
279 | "version": "1.3.0",
280 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
281 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
282 | "engines": {
283 | "node": ">= 0.4"
284 | }
285 | },
286 | "node_modules/escape-html": {
287 | "version": "1.0.3",
288 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
289 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
290 | },
291 | "node_modules/etag": {
292 | "version": "1.8.1",
293 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
294 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
295 | "engines": {
296 | "node": ">= 0.6"
297 | }
298 | },
299 | "node_modules/express": {
300 | "version": "4.19.2",
301 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
302 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
303 | "dependencies": {
304 | "accepts": "~1.3.8",
305 | "array-flatten": "1.1.1",
306 | "body-parser": "1.20.2",
307 | "content-disposition": "0.5.4",
308 | "content-type": "~1.0.4",
309 | "cookie": "0.6.0",
310 | "cookie-signature": "1.0.6",
311 | "debug": "2.6.9",
312 | "depd": "2.0.0",
313 | "encodeurl": "~1.0.2",
314 | "escape-html": "~1.0.3",
315 | "etag": "~1.8.1",
316 | "finalhandler": "1.2.0",
317 | "fresh": "0.5.2",
318 | "http-errors": "2.0.0",
319 | "merge-descriptors": "1.0.1",
320 | "methods": "~1.1.2",
321 | "on-finished": "2.4.1",
322 | "parseurl": "~1.3.3",
323 | "path-to-regexp": "0.1.7",
324 | "proxy-addr": "~2.0.7",
325 | "qs": "6.11.0",
326 | "range-parser": "~1.2.1",
327 | "safe-buffer": "5.2.1",
328 | "send": "0.18.0",
329 | "serve-static": "1.15.0",
330 | "setprototypeof": "1.2.0",
331 | "statuses": "2.0.1",
332 | "type-is": "~1.6.18",
333 | "utils-merge": "1.0.1",
334 | "vary": "~1.1.2"
335 | },
336 | "engines": {
337 | "node": ">= 0.10.0"
338 | }
339 | },
340 | "node_modules/express-handlebars": {
341 | "version": "7.1.3",
342 | "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-7.1.3.tgz",
343 | "integrity": "sha512-O0W4n14iQ8+iFIDdiMh9HRI2nbVQJ/h1qndlD1TXWxxcfbKjKoqJh+ti2tROkyx4C4VQrt0y3bANBQ5auQAiew==",
344 | "dependencies": {
345 | "glob": "^10.4.2",
346 | "graceful-fs": "^4.2.11",
347 | "handlebars": "^4.7.8"
348 | },
349 | "engines": {
350 | "node": ">=v16"
351 | }
352 | },
353 | "node_modules/finalhandler": {
354 | "version": "1.2.0",
355 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
356 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
357 | "dependencies": {
358 | "debug": "2.6.9",
359 | "encodeurl": "~1.0.2",
360 | "escape-html": "~1.0.3",
361 | "on-finished": "2.4.1",
362 | "parseurl": "~1.3.3",
363 | "statuses": "2.0.1",
364 | "unpipe": "~1.0.0"
365 | },
366 | "engines": {
367 | "node": ">= 0.8"
368 | }
369 | },
370 | "node_modules/foreground-child": {
371 | "version": "3.2.1",
372 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
373 | "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
374 | "dependencies": {
375 | "cross-spawn": "^7.0.0",
376 | "signal-exit": "^4.0.1"
377 | },
378 | "engines": {
379 | "node": ">=14"
380 | },
381 | "funding": {
382 | "url": "https://github.com/sponsors/isaacs"
383 | }
384 | },
385 | "node_modules/forwarded": {
386 | "version": "0.2.0",
387 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
388 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
389 | "engines": {
390 | "node": ">= 0.6"
391 | }
392 | },
393 | "node_modules/fresh": {
394 | "version": "0.5.2",
395 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
396 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
397 | "engines": {
398 | "node": ">= 0.6"
399 | }
400 | },
401 | "node_modules/function-bind": {
402 | "version": "1.1.2",
403 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
404 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
405 | "funding": {
406 | "url": "https://github.com/sponsors/ljharb"
407 | }
408 | },
409 | "node_modules/get-intrinsic": {
410 | "version": "1.2.4",
411 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
412 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
413 | "dependencies": {
414 | "es-errors": "^1.3.0",
415 | "function-bind": "^1.1.2",
416 | "has-proto": "^1.0.1",
417 | "has-symbols": "^1.0.3",
418 | "hasown": "^2.0.0"
419 | },
420 | "engines": {
421 | "node": ">= 0.4"
422 | },
423 | "funding": {
424 | "url": "https://github.com/sponsors/ljharb"
425 | }
426 | },
427 | "node_modules/glob": {
428 | "version": "10.4.5",
429 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
430 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
431 | "dependencies": {
432 | "foreground-child": "^3.1.0",
433 | "jackspeak": "^3.1.2",
434 | "minimatch": "^9.0.4",
435 | "minipass": "^7.1.2",
436 | "package-json-from-dist": "^1.0.0",
437 | "path-scurry": "^1.11.1"
438 | },
439 | "bin": {
440 | "glob": "dist/esm/bin.mjs"
441 | },
442 | "funding": {
443 | "url": "https://github.com/sponsors/isaacs"
444 | }
445 | },
446 | "node_modules/gopd": {
447 | "version": "1.0.1",
448 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
449 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
450 | "dependencies": {
451 | "get-intrinsic": "^1.1.3"
452 | },
453 | "funding": {
454 | "url": "https://github.com/sponsors/ljharb"
455 | }
456 | },
457 | "node_modules/graceful-fs": {
458 | "version": "4.2.11",
459 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
460 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
461 | },
462 | "node_modules/handlebars": {
463 | "version": "4.7.8",
464 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
465 | "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
466 | "dependencies": {
467 | "minimist": "^1.2.5",
468 | "neo-async": "^2.6.2",
469 | "source-map": "^0.6.1",
470 | "wordwrap": "^1.0.0"
471 | },
472 | "bin": {
473 | "handlebars": "bin/handlebars"
474 | },
475 | "engines": {
476 | "node": ">=0.4.7"
477 | },
478 | "optionalDependencies": {
479 | "uglify-js": "^3.1.4"
480 | }
481 | },
482 | "node_modules/has-property-descriptors": {
483 | "version": "1.0.2",
484 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
485 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
486 | "dependencies": {
487 | "es-define-property": "^1.0.0"
488 | },
489 | "funding": {
490 | "url": "https://github.com/sponsors/ljharb"
491 | }
492 | },
493 | "node_modules/has-proto": {
494 | "version": "1.0.3",
495 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
496 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
497 | "engines": {
498 | "node": ">= 0.4"
499 | },
500 | "funding": {
501 | "url": "https://github.com/sponsors/ljharb"
502 | }
503 | },
504 | "node_modules/has-symbols": {
505 | "version": "1.0.3",
506 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
507 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
508 | "engines": {
509 | "node": ">= 0.4"
510 | },
511 | "funding": {
512 | "url": "https://github.com/sponsors/ljharb"
513 | }
514 | },
515 | "node_modules/hasown": {
516 | "version": "2.0.2",
517 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
518 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
519 | "dependencies": {
520 | "function-bind": "^1.1.2"
521 | },
522 | "engines": {
523 | "node": ">= 0.4"
524 | }
525 | },
526 | "node_modules/http-errors": {
527 | "version": "2.0.0",
528 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
529 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
530 | "dependencies": {
531 | "depd": "2.0.0",
532 | "inherits": "2.0.4",
533 | "setprototypeof": "1.2.0",
534 | "statuses": "2.0.1",
535 | "toidentifier": "1.0.1"
536 | },
537 | "engines": {
538 | "node": ">= 0.8"
539 | }
540 | },
541 | "node_modules/iconv-lite": {
542 | "version": "0.4.24",
543 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
544 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
545 | "dependencies": {
546 | "safer-buffer": ">= 2.1.2 < 3"
547 | },
548 | "engines": {
549 | "node": ">=0.10.0"
550 | }
551 | },
552 | "node_modules/inherits": {
553 | "version": "2.0.4",
554 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
555 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
556 | },
557 | "node_modules/ipaddr.js": {
558 | "version": "1.9.1",
559 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
560 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
561 | "engines": {
562 | "node": ">= 0.10"
563 | }
564 | },
565 | "node_modules/is-fullwidth-code-point": {
566 | "version": "3.0.0",
567 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
568 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
569 | "engines": {
570 | "node": ">=8"
571 | }
572 | },
573 | "node_modules/isexe": {
574 | "version": "2.0.0",
575 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
576 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
577 | },
578 | "node_modules/jackspeak": {
579 | "version": "3.4.3",
580 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
581 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
582 | "dependencies": {
583 | "@isaacs/cliui": "^8.0.2"
584 | },
585 | "funding": {
586 | "url": "https://github.com/sponsors/isaacs"
587 | },
588 | "optionalDependencies": {
589 | "@pkgjs/parseargs": "^0.11.0"
590 | }
591 | },
592 | "node_modules/lru-cache": {
593 | "version": "10.4.3",
594 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
595 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
596 | },
597 | "node_modules/media-typer": {
598 | "version": "0.3.0",
599 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
600 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
601 | "engines": {
602 | "node": ">= 0.6"
603 | }
604 | },
605 | "node_modules/merge-descriptors": {
606 | "version": "1.0.1",
607 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
608 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
609 | },
610 | "node_modules/methods": {
611 | "version": "1.1.2",
612 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
613 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
614 | "engines": {
615 | "node": ">= 0.6"
616 | }
617 | },
618 | "node_modules/mime": {
619 | "version": "1.6.0",
620 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
621 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
622 | "bin": {
623 | "mime": "cli.js"
624 | },
625 | "engines": {
626 | "node": ">=4"
627 | }
628 | },
629 | "node_modules/mime-db": {
630 | "version": "1.52.0",
631 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
632 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
633 | "engines": {
634 | "node": ">= 0.6"
635 | }
636 | },
637 | "node_modules/mime-types": {
638 | "version": "2.1.35",
639 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
640 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
641 | "dependencies": {
642 | "mime-db": "1.52.0"
643 | },
644 | "engines": {
645 | "node": ">= 0.6"
646 | }
647 | },
648 | "node_modules/minimatch": {
649 | "version": "9.0.5",
650 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
651 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
652 | "dependencies": {
653 | "brace-expansion": "^2.0.1"
654 | },
655 | "engines": {
656 | "node": ">=16 || 14 >=14.17"
657 | },
658 | "funding": {
659 | "url": "https://github.com/sponsors/isaacs"
660 | }
661 | },
662 | "node_modules/minimist": {
663 | "version": "1.2.8",
664 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
665 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
666 | "funding": {
667 | "url": "https://github.com/sponsors/ljharb"
668 | }
669 | },
670 | "node_modules/minipass": {
671 | "version": "7.1.2",
672 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
673 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
674 | "engines": {
675 | "node": ">=16 || 14 >=14.17"
676 | }
677 | },
678 | "node_modules/ms": {
679 | "version": "2.0.0",
680 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
681 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
682 | },
683 | "node_modules/negotiator": {
684 | "version": "0.6.3",
685 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
686 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
687 | "engines": {
688 | "node": ">= 0.6"
689 | }
690 | },
691 | "node_modules/neo-async": {
692 | "version": "2.6.2",
693 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
694 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
695 | },
696 | "node_modules/object-inspect": {
697 | "version": "1.13.2",
698 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
699 | "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
700 | "engines": {
701 | "node": ">= 0.4"
702 | },
703 | "funding": {
704 | "url": "https://github.com/sponsors/ljharb"
705 | }
706 | },
707 | "node_modules/on-finished": {
708 | "version": "2.4.1",
709 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
710 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
711 | "dependencies": {
712 | "ee-first": "1.1.1"
713 | },
714 | "engines": {
715 | "node": ">= 0.8"
716 | }
717 | },
718 | "node_modules/package-json-from-dist": {
719 | "version": "1.0.0",
720 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
721 | "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
722 | },
723 | "node_modules/parseurl": {
724 | "version": "1.3.3",
725 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
726 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
727 | "engines": {
728 | "node": ">= 0.8"
729 | }
730 | },
731 | "node_modules/path-key": {
732 | "version": "3.1.1",
733 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
734 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
735 | "engines": {
736 | "node": ">=8"
737 | }
738 | },
739 | "node_modules/path-scurry": {
740 | "version": "1.11.1",
741 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
742 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
743 | "dependencies": {
744 | "lru-cache": "^10.2.0",
745 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
746 | },
747 | "engines": {
748 | "node": ">=16 || 14 >=14.18"
749 | },
750 | "funding": {
751 | "url": "https://github.com/sponsors/isaacs"
752 | }
753 | },
754 | "node_modules/path-to-regexp": {
755 | "version": "0.1.7",
756 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
757 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
758 | },
759 | "node_modules/proxy-addr": {
760 | "version": "2.0.7",
761 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
762 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
763 | "dependencies": {
764 | "forwarded": "0.2.0",
765 | "ipaddr.js": "1.9.1"
766 | },
767 | "engines": {
768 | "node": ">= 0.10"
769 | }
770 | },
771 | "node_modules/qs": {
772 | "version": "6.11.0",
773 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
774 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
775 | "dependencies": {
776 | "side-channel": "^1.0.4"
777 | },
778 | "engines": {
779 | "node": ">=0.6"
780 | },
781 | "funding": {
782 | "url": "https://github.com/sponsors/ljharb"
783 | }
784 | },
785 | "node_modules/range-parser": {
786 | "version": "1.2.1",
787 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
788 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
789 | "engines": {
790 | "node": ">= 0.6"
791 | }
792 | },
793 | "node_modules/raw-body": {
794 | "version": "2.5.2",
795 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
796 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
797 | "dependencies": {
798 | "bytes": "3.1.2",
799 | "http-errors": "2.0.0",
800 | "iconv-lite": "0.4.24",
801 | "unpipe": "1.0.0"
802 | },
803 | "engines": {
804 | "node": ">= 0.8"
805 | }
806 | },
807 | "node_modules/safe-buffer": {
808 | "version": "5.2.1",
809 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
810 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
811 | "funding": [
812 | {
813 | "type": "github",
814 | "url": "https://github.com/sponsors/feross"
815 | },
816 | {
817 | "type": "patreon",
818 | "url": "https://www.patreon.com/feross"
819 | },
820 | {
821 | "type": "consulting",
822 | "url": "https://feross.org/support"
823 | }
824 | ]
825 | },
826 | "node_modules/safer-buffer": {
827 | "version": "2.1.2",
828 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
829 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
830 | },
831 | "node_modules/send": {
832 | "version": "0.18.0",
833 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
834 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
835 | "dependencies": {
836 | "debug": "2.6.9",
837 | "depd": "2.0.0",
838 | "destroy": "1.2.0",
839 | "encodeurl": "~1.0.2",
840 | "escape-html": "~1.0.3",
841 | "etag": "~1.8.1",
842 | "fresh": "0.5.2",
843 | "http-errors": "2.0.0",
844 | "mime": "1.6.0",
845 | "ms": "2.1.3",
846 | "on-finished": "2.4.1",
847 | "range-parser": "~1.2.1",
848 | "statuses": "2.0.1"
849 | },
850 | "engines": {
851 | "node": ">= 0.8.0"
852 | }
853 | },
854 | "node_modules/send/node_modules/ms": {
855 | "version": "2.1.3",
856 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
857 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
858 | },
859 | "node_modules/serve-static": {
860 | "version": "1.15.0",
861 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
862 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
863 | "dependencies": {
864 | "encodeurl": "~1.0.2",
865 | "escape-html": "~1.0.3",
866 | "parseurl": "~1.3.3",
867 | "send": "0.18.0"
868 | },
869 | "engines": {
870 | "node": ">= 0.8.0"
871 | }
872 | },
873 | "node_modules/set-function-length": {
874 | "version": "1.2.2",
875 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
876 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
877 | "dependencies": {
878 | "define-data-property": "^1.1.4",
879 | "es-errors": "^1.3.0",
880 | "function-bind": "^1.1.2",
881 | "get-intrinsic": "^1.2.4",
882 | "gopd": "^1.0.1",
883 | "has-property-descriptors": "^1.0.2"
884 | },
885 | "engines": {
886 | "node": ">= 0.4"
887 | }
888 | },
889 | "node_modules/setprototypeof": {
890 | "version": "1.2.0",
891 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
892 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
893 | },
894 | "node_modules/shebang-command": {
895 | "version": "2.0.0",
896 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
897 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
898 | "dependencies": {
899 | "shebang-regex": "^3.0.0"
900 | },
901 | "engines": {
902 | "node": ">=8"
903 | }
904 | },
905 | "node_modules/shebang-regex": {
906 | "version": "3.0.0",
907 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
908 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
909 | "engines": {
910 | "node": ">=8"
911 | }
912 | },
913 | "node_modules/side-channel": {
914 | "version": "1.0.6",
915 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
916 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
917 | "dependencies": {
918 | "call-bind": "^1.0.7",
919 | "es-errors": "^1.3.0",
920 | "get-intrinsic": "^1.2.4",
921 | "object-inspect": "^1.13.1"
922 | },
923 | "engines": {
924 | "node": ">= 0.4"
925 | },
926 | "funding": {
927 | "url": "https://github.com/sponsors/ljharb"
928 | }
929 | },
930 | "node_modules/signal-exit": {
931 | "version": "4.1.0",
932 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
933 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
934 | "engines": {
935 | "node": ">=14"
936 | },
937 | "funding": {
938 | "url": "https://github.com/sponsors/isaacs"
939 | }
940 | },
941 | "node_modules/source-map": {
942 | "version": "0.6.1",
943 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
944 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
945 | "engines": {
946 | "node": ">=0.10.0"
947 | }
948 | },
949 | "node_modules/statuses": {
950 | "version": "2.0.1",
951 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
952 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
953 | "engines": {
954 | "node": ">= 0.8"
955 | }
956 | },
957 | "node_modules/string-width": {
958 | "version": "5.1.2",
959 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
960 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
961 | "dependencies": {
962 | "eastasianwidth": "^0.2.0",
963 | "emoji-regex": "^9.2.2",
964 | "strip-ansi": "^7.0.1"
965 | },
966 | "engines": {
967 | "node": ">=12"
968 | },
969 | "funding": {
970 | "url": "https://github.com/sponsors/sindresorhus"
971 | }
972 | },
973 | "node_modules/string-width-cjs": {
974 | "name": "string-width",
975 | "version": "4.2.3",
976 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
977 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
978 | "dependencies": {
979 | "emoji-regex": "^8.0.0",
980 | "is-fullwidth-code-point": "^3.0.0",
981 | "strip-ansi": "^6.0.1"
982 | },
983 | "engines": {
984 | "node": ">=8"
985 | }
986 | },
987 | "node_modules/string-width-cjs/node_modules/ansi-regex": {
988 | "version": "5.0.1",
989 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
990 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
991 | "engines": {
992 | "node": ">=8"
993 | }
994 | },
995 | "node_modules/string-width-cjs/node_modules/emoji-regex": {
996 | "version": "8.0.0",
997 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
998 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
999 | },
1000 | "node_modules/string-width-cjs/node_modules/strip-ansi": {
1001 | "version": "6.0.1",
1002 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1003 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1004 | "dependencies": {
1005 | "ansi-regex": "^5.0.1"
1006 | },
1007 | "engines": {
1008 | "node": ">=8"
1009 | }
1010 | },
1011 | "node_modules/strip-ansi": {
1012 | "version": "7.1.0",
1013 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
1014 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
1015 | "dependencies": {
1016 | "ansi-regex": "^6.0.1"
1017 | },
1018 | "engines": {
1019 | "node": ">=12"
1020 | },
1021 | "funding": {
1022 | "url": "https://github.com/chalk/strip-ansi?sponsor=1"
1023 | }
1024 | },
1025 | "node_modules/strip-ansi-cjs": {
1026 | "name": "strip-ansi",
1027 | "version": "6.0.1",
1028 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1029 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1030 | "dependencies": {
1031 | "ansi-regex": "^5.0.1"
1032 | },
1033 | "engines": {
1034 | "node": ">=8"
1035 | }
1036 | },
1037 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
1038 | "version": "5.0.1",
1039 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1040 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1041 | "engines": {
1042 | "node": ">=8"
1043 | }
1044 | },
1045 | "node_modules/toidentifier": {
1046 | "version": "1.0.1",
1047 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1048 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1049 | "engines": {
1050 | "node": ">=0.6"
1051 | }
1052 | },
1053 | "node_modules/type-is": {
1054 | "version": "1.6.18",
1055 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1056 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1057 | "dependencies": {
1058 | "media-typer": "0.3.0",
1059 | "mime-types": "~2.1.24"
1060 | },
1061 | "engines": {
1062 | "node": ">= 0.6"
1063 | }
1064 | },
1065 | "node_modules/uglify-js": {
1066 | "version": "3.19.1",
1067 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.1.tgz",
1068 | "integrity": "sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==",
1069 | "optional": true,
1070 | "bin": {
1071 | "uglifyjs": "bin/uglifyjs"
1072 | },
1073 | "engines": {
1074 | "node": ">=0.8.0"
1075 | }
1076 | },
1077 | "node_modules/unpipe": {
1078 | "version": "1.0.0",
1079 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1080 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1081 | "engines": {
1082 | "node": ">= 0.8"
1083 | }
1084 | },
1085 | "node_modules/utils-merge": {
1086 | "version": "1.0.1",
1087 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1088 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
1089 | "engines": {
1090 | "node": ">= 0.4.0"
1091 | }
1092 | },
1093 | "node_modules/vary": {
1094 | "version": "1.1.2",
1095 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1096 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1097 | "engines": {
1098 | "node": ">= 0.8"
1099 | }
1100 | },
1101 | "node_modules/which": {
1102 | "version": "2.0.2",
1103 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1104 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1105 | "dependencies": {
1106 | "isexe": "^2.0.0"
1107 | },
1108 | "bin": {
1109 | "node-which": "bin/node-which"
1110 | },
1111 | "engines": {
1112 | "node": ">= 8"
1113 | }
1114 | },
1115 | "node_modules/wordwrap": {
1116 | "version": "1.0.0",
1117 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1118 | "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
1119 | },
1120 | "node_modules/wrap-ansi": {
1121 | "version": "8.1.0",
1122 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
1123 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
1124 | "dependencies": {
1125 | "ansi-styles": "^6.1.0",
1126 | "string-width": "^5.0.1",
1127 | "strip-ansi": "^7.0.1"
1128 | },
1129 | "engines": {
1130 | "node": ">=12"
1131 | },
1132 | "funding": {
1133 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1134 | }
1135 | },
1136 | "node_modules/wrap-ansi-cjs": {
1137 | "name": "wrap-ansi",
1138 | "version": "7.0.0",
1139 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1140 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1141 | "dependencies": {
1142 | "ansi-styles": "^4.0.0",
1143 | "string-width": "^4.1.0",
1144 | "strip-ansi": "^6.0.0"
1145 | },
1146 | "engines": {
1147 | "node": ">=10"
1148 | },
1149 | "funding": {
1150 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1151 | }
1152 | },
1153 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
1154 | "version": "5.0.1",
1155 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1156 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1157 | "engines": {
1158 | "node": ">=8"
1159 | }
1160 | },
1161 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
1162 | "version": "4.3.0",
1163 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1164 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1165 | "dependencies": {
1166 | "color-convert": "^2.0.1"
1167 | },
1168 | "engines": {
1169 | "node": ">=8"
1170 | },
1171 | "funding": {
1172 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1173 | }
1174 | },
1175 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
1176 | "version": "8.0.0",
1177 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1178 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
1179 | },
1180 | "node_modules/wrap-ansi-cjs/node_modules/string-width": {
1181 | "version": "4.2.3",
1182 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1183 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1184 | "dependencies": {
1185 | "emoji-regex": "^8.0.0",
1186 | "is-fullwidth-code-point": "^3.0.0",
1187 | "strip-ansi": "^6.0.1"
1188 | },
1189 | "engines": {
1190 | "node": ">=8"
1191 | }
1192 | },
1193 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
1194 | "version": "6.0.1",
1195 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1196 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1197 | "dependencies": {
1198 | "ansi-regex": "^5.0.1"
1199 | },
1200 | "engines": {
1201 | "node": ">=8"
1202 | }
1203 | }
1204 | },
1205 | "dependencies": {
1206 | "@isaacs/cliui": {
1207 | "version": "8.0.2",
1208 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
1209 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
1210 | "requires": {
1211 | "string-width": "^5.1.2",
1212 | "string-width-cjs": "npm:string-width@^4.2.0",
1213 | "strip-ansi": "^7.0.1",
1214 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
1215 | "wrap-ansi": "^8.1.0",
1216 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
1217 | }
1218 | },
1219 | "@pkgjs/parseargs": {
1220 | "version": "0.11.0",
1221 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
1222 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
1223 | "optional": true
1224 | },
1225 | "accepts": {
1226 | "version": "1.3.8",
1227 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
1228 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
1229 | "requires": {
1230 | "mime-types": "~2.1.34",
1231 | "negotiator": "0.6.3"
1232 | }
1233 | },
1234 | "ansi-regex": {
1235 | "version": "6.0.1",
1236 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
1237 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="
1238 | },
1239 | "ansi-styles": {
1240 | "version": "6.2.1",
1241 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
1242 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
1243 | },
1244 | "array-flatten": {
1245 | "version": "1.1.1",
1246 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
1247 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
1248 | },
1249 | "balanced-match": {
1250 | "version": "1.0.2",
1251 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1252 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
1253 | },
1254 | "body-parser": {
1255 | "version": "1.20.2",
1256 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
1257 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
1258 | "requires": {
1259 | "bytes": "3.1.2",
1260 | "content-type": "~1.0.5",
1261 | "debug": "2.6.9",
1262 | "depd": "2.0.0",
1263 | "destroy": "1.2.0",
1264 | "http-errors": "2.0.0",
1265 | "iconv-lite": "0.4.24",
1266 | "on-finished": "2.4.1",
1267 | "qs": "6.11.0",
1268 | "raw-body": "2.5.2",
1269 | "type-is": "~1.6.18",
1270 | "unpipe": "1.0.0"
1271 | }
1272 | },
1273 | "brace-expansion": {
1274 | "version": "2.0.1",
1275 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
1276 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
1277 | "requires": {
1278 | "balanced-match": "^1.0.0"
1279 | }
1280 | },
1281 | "bytes": {
1282 | "version": "3.1.2",
1283 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1284 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
1285 | },
1286 | "call-bind": {
1287 | "version": "1.0.7",
1288 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
1289 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
1290 | "requires": {
1291 | "es-define-property": "^1.0.0",
1292 | "es-errors": "^1.3.0",
1293 | "function-bind": "^1.1.2",
1294 | "get-intrinsic": "^1.2.4",
1295 | "set-function-length": "^1.2.1"
1296 | }
1297 | },
1298 | "color-convert": {
1299 | "version": "2.0.1",
1300 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1301 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1302 | "requires": {
1303 | "color-name": "~1.1.4"
1304 | }
1305 | },
1306 | "color-name": {
1307 | "version": "1.1.4",
1308 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1309 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
1310 | },
1311 | "content-disposition": {
1312 | "version": "0.5.4",
1313 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
1314 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
1315 | "requires": {
1316 | "safe-buffer": "5.2.1"
1317 | }
1318 | },
1319 | "content-type": {
1320 | "version": "1.0.5",
1321 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
1322 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="
1323 | },
1324 | "cookie": {
1325 | "version": "0.6.0",
1326 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
1327 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
1328 | },
1329 | "cookie-signature": {
1330 | "version": "1.0.6",
1331 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
1332 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
1333 | },
1334 | "cross-spawn": {
1335 | "version": "7.0.3",
1336 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
1337 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
1338 | "requires": {
1339 | "path-key": "^3.1.0",
1340 | "shebang-command": "^2.0.0",
1341 | "which": "^2.0.1"
1342 | }
1343 | },
1344 | "debug": {
1345 | "version": "2.6.9",
1346 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1347 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1348 | "requires": {
1349 | "ms": "2.0.0"
1350 | }
1351 | },
1352 | "define-data-property": {
1353 | "version": "1.1.4",
1354 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
1355 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
1356 | "requires": {
1357 | "es-define-property": "^1.0.0",
1358 | "es-errors": "^1.3.0",
1359 | "gopd": "^1.0.1"
1360 | }
1361 | },
1362 | "depd": {
1363 | "version": "2.0.0",
1364 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1365 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
1366 | },
1367 | "destroy": {
1368 | "version": "1.2.0",
1369 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
1370 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
1371 | },
1372 | "eastasianwidth": {
1373 | "version": "0.2.0",
1374 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
1375 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
1376 | },
1377 | "ee-first": {
1378 | "version": "1.1.1",
1379 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1380 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
1381 | },
1382 | "emoji-regex": {
1383 | "version": "9.2.2",
1384 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
1385 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
1386 | },
1387 | "encodeurl": {
1388 | "version": "1.0.2",
1389 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
1390 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
1391 | },
1392 | "es-define-property": {
1393 | "version": "1.0.0",
1394 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
1395 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
1396 | "requires": {
1397 | "get-intrinsic": "^1.2.4"
1398 | }
1399 | },
1400 | "es-errors": {
1401 | "version": "1.3.0",
1402 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
1403 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
1404 | },
1405 | "escape-html": {
1406 | "version": "1.0.3",
1407 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1408 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
1409 | },
1410 | "etag": {
1411 | "version": "1.8.1",
1412 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
1413 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
1414 | },
1415 | "express": {
1416 | "version": "4.19.2",
1417 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
1418 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
1419 | "requires": {
1420 | "accepts": "~1.3.8",
1421 | "array-flatten": "1.1.1",
1422 | "body-parser": "1.20.2",
1423 | "content-disposition": "0.5.4",
1424 | "content-type": "~1.0.4",
1425 | "cookie": "0.6.0",
1426 | "cookie-signature": "1.0.6",
1427 | "debug": "2.6.9",
1428 | "depd": "2.0.0",
1429 | "encodeurl": "~1.0.2",
1430 | "escape-html": "~1.0.3",
1431 | "etag": "~1.8.1",
1432 | "finalhandler": "1.2.0",
1433 | "fresh": "0.5.2",
1434 | "http-errors": "2.0.0",
1435 | "merge-descriptors": "1.0.1",
1436 | "methods": "~1.1.2",
1437 | "on-finished": "2.4.1",
1438 | "parseurl": "~1.3.3",
1439 | "path-to-regexp": "0.1.7",
1440 | "proxy-addr": "~2.0.7",
1441 | "qs": "6.11.0",
1442 | "range-parser": "~1.2.1",
1443 | "safe-buffer": "5.2.1",
1444 | "send": "0.18.0",
1445 | "serve-static": "1.15.0",
1446 | "setprototypeof": "1.2.0",
1447 | "statuses": "2.0.1",
1448 | "type-is": "~1.6.18",
1449 | "utils-merge": "1.0.1",
1450 | "vary": "~1.1.2"
1451 | }
1452 | },
1453 | "express-handlebars": {
1454 | "version": "7.1.3",
1455 | "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-7.1.3.tgz",
1456 | "integrity": "sha512-O0W4n14iQ8+iFIDdiMh9HRI2nbVQJ/h1qndlD1TXWxxcfbKjKoqJh+ti2tROkyx4C4VQrt0y3bANBQ5auQAiew==",
1457 | "requires": {
1458 | "glob": "^10.4.2",
1459 | "graceful-fs": "^4.2.11",
1460 | "handlebars": "^4.7.8"
1461 | }
1462 | },
1463 | "finalhandler": {
1464 | "version": "1.2.0",
1465 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1466 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1467 | "requires": {
1468 | "debug": "2.6.9",
1469 | "encodeurl": "~1.0.2",
1470 | "escape-html": "~1.0.3",
1471 | "on-finished": "2.4.1",
1472 | "parseurl": "~1.3.3",
1473 | "statuses": "2.0.1",
1474 | "unpipe": "~1.0.0"
1475 | }
1476 | },
1477 | "foreground-child": {
1478 | "version": "3.2.1",
1479 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
1480 | "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
1481 | "requires": {
1482 | "cross-spawn": "^7.0.0",
1483 | "signal-exit": "^4.0.1"
1484 | }
1485 | },
1486 | "forwarded": {
1487 | "version": "0.2.0",
1488 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1489 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
1490 | },
1491 | "fresh": {
1492 | "version": "0.5.2",
1493 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1494 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
1495 | },
1496 | "function-bind": {
1497 | "version": "1.1.2",
1498 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1499 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
1500 | },
1501 | "get-intrinsic": {
1502 | "version": "1.2.4",
1503 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
1504 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
1505 | "requires": {
1506 | "es-errors": "^1.3.0",
1507 | "function-bind": "^1.1.2",
1508 | "has-proto": "^1.0.1",
1509 | "has-symbols": "^1.0.3",
1510 | "hasown": "^2.0.0"
1511 | }
1512 | },
1513 | "glob": {
1514 | "version": "10.4.5",
1515 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
1516 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
1517 | "requires": {
1518 | "foreground-child": "^3.1.0",
1519 | "jackspeak": "^3.1.2",
1520 | "minimatch": "^9.0.4",
1521 | "minipass": "^7.1.2",
1522 | "package-json-from-dist": "^1.0.0",
1523 | "path-scurry": "^1.11.1"
1524 | }
1525 | },
1526 | "gopd": {
1527 | "version": "1.0.1",
1528 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
1529 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
1530 | "requires": {
1531 | "get-intrinsic": "^1.1.3"
1532 | }
1533 | },
1534 | "graceful-fs": {
1535 | "version": "4.2.11",
1536 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1537 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
1538 | },
1539 | "handlebars": {
1540 | "version": "4.7.8",
1541 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
1542 | "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
1543 | "requires": {
1544 | "minimist": "^1.2.5",
1545 | "neo-async": "^2.6.2",
1546 | "source-map": "^0.6.1",
1547 | "uglify-js": "^3.1.4",
1548 | "wordwrap": "^1.0.0"
1549 | }
1550 | },
1551 | "has-property-descriptors": {
1552 | "version": "1.0.2",
1553 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
1554 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
1555 | "requires": {
1556 | "es-define-property": "^1.0.0"
1557 | }
1558 | },
1559 | "has-proto": {
1560 | "version": "1.0.3",
1561 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
1562 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q=="
1563 | },
1564 | "has-symbols": {
1565 | "version": "1.0.3",
1566 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1567 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
1568 | },
1569 | "hasown": {
1570 | "version": "2.0.2",
1571 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1572 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1573 | "requires": {
1574 | "function-bind": "^1.1.2"
1575 | }
1576 | },
1577 | "http-errors": {
1578 | "version": "2.0.0",
1579 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1580 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1581 | "requires": {
1582 | "depd": "2.0.0",
1583 | "inherits": "2.0.4",
1584 | "setprototypeof": "1.2.0",
1585 | "statuses": "2.0.1",
1586 | "toidentifier": "1.0.1"
1587 | }
1588 | },
1589 | "iconv-lite": {
1590 | "version": "0.4.24",
1591 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1592 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1593 | "requires": {
1594 | "safer-buffer": ">= 2.1.2 < 3"
1595 | }
1596 | },
1597 | "inherits": {
1598 | "version": "2.0.4",
1599 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1600 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1601 | },
1602 | "ipaddr.js": {
1603 | "version": "1.9.1",
1604 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1605 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
1606 | },
1607 | "is-fullwidth-code-point": {
1608 | "version": "3.0.0",
1609 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1610 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
1611 | },
1612 | "isexe": {
1613 | "version": "2.0.0",
1614 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1615 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
1616 | },
1617 | "jackspeak": {
1618 | "version": "3.4.3",
1619 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
1620 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
1621 | "requires": {
1622 | "@isaacs/cliui": "^8.0.2",
1623 | "@pkgjs/parseargs": "^0.11.0"
1624 | }
1625 | },
1626 | "lru-cache": {
1627 | "version": "10.4.3",
1628 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1629 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
1630 | },
1631 | "media-typer": {
1632 | "version": "0.3.0",
1633 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1634 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
1635 | },
1636 | "merge-descriptors": {
1637 | "version": "1.0.1",
1638 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1639 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
1640 | },
1641 | "methods": {
1642 | "version": "1.1.2",
1643 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1644 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
1645 | },
1646 | "mime": {
1647 | "version": "1.6.0",
1648 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1649 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
1650 | },
1651 | "mime-db": {
1652 | "version": "1.52.0",
1653 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1654 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
1655 | },
1656 | "mime-types": {
1657 | "version": "2.1.35",
1658 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1659 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1660 | "requires": {
1661 | "mime-db": "1.52.0"
1662 | }
1663 | },
1664 | "minimatch": {
1665 | "version": "9.0.5",
1666 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
1667 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
1668 | "requires": {
1669 | "brace-expansion": "^2.0.1"
1670 | }
1671 | },
1672 | "minimist": {
1673 | "version": "1.2.8",
1674 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1675 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
1676 | },
1677 | "minipass": {
1678 | "version": "7.1.2",
1679 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1680 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
1681 | },
1682 | "ms": {
1683 | "version": "2.0.0",
1684 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1685 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1686 | },
1687 | "negotiator": {
1688 | "version": "0.6.3",
1689 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1690 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
1691 | },
1692 | "neo-async": {
1693 | "version": "2.6.2",
1694 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
1695 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
1696 | },
1697 | "object-inspect": {
1698 | "version": "1.13.2",
1699 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
1700 | "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g=="
1701 | },
1702 | "on-finished": {
1703 | "version": "2.4.1",
1704 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1705 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1706 | "requires": {
1707 | "ee-first": "1.1.1"
1708 | }
1709 | },
1710 | "package-json-from-dist": {
1711 | "version": "1.0.0",
1712 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
1713 | "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
1714 | },
1715 | "parseurl": {
1716 | "version": "1.3.3",
1717 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1718 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1719 | },
1720 | "path-key": {
1721 | "version": "3.1.1",
1722 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1723 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
1724 | },
1725 | "path-scurry": {
1726 | "version": "1.11.1",
1727 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
1728 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
1729 | "requires": {
1730 | "lru-cache": "^10.2.0",
1731 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1732 | }
1733 | },
1734 | "path-to-regexp": {
1735 | "version": "0.1.7",
1736 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1737 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1738 | },
1739 | "proxy-addr": {
1740 | "version": "2.0.7",
1741 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1742 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1743 | "requires": {
1744 | "forwarded": "0.2.0",
1745 | "ipaddr.js": "1.9.1"
1746 | }
1747 | },
1748 | "qs": {
1749 | "version": "6.11.0",
1750 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1751 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1752 | "requires": {
1753 | "side-channel": "^1.0.4"
1754 | }
1755 | },
1756 | "range-parser": {
1757 | "version": "1.2.1",
1758 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1759 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
1760 | },
1761 | "raw-body": {
1762 | "version": "2.5.2",
1763 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
1764 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
1765 | "requires": {
1766 | "bytes": "3.1.2",
1767 | "http-errors": "2.0.0",
1768 | "iconv-lite": "0.4.24",
1769 | "unpipe": "1.0.0"
1770 | }
1771 | },
1772 | "safe-buffer": {
1773 | "version": "5.2.1",
1774 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1775 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
1776 | },
1777 | "safer-buffer": {
1778 | "version": "2.1.2",
1779 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1780 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1781 | },
1782 | "send": {
1783 | "version": "0.18.0",
1784 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1785 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1786 | "requires": {
1787 | "debug": "2.6.9",
1788 | "depd": "2.0.0",
1789 | "destroy": "1.2.0",
1790 | "encodeurl": "~1.0.2",
1791 | "escape-html": "~1.0.3",
1792 | "etag": "~1.8.1",
1793 | "fresh": "0.5.2",
1794 | "http-errors": "2.0.0",
1795 | "mime": "1.6.0",
1796 | "ms": "2.1.3",
1797 | "on-finished": "2.4.1",
1798 | "range-parser": "~1.2.1",
1799 | "statuses": "2.0.1"
1800 | },
1801 | "dependencies": {
1802 | "ms": {
1803 | "version": "2.1.3",
1804 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1805 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1806 | }
1807 | }
1808 | },
1809 | "serve-static": {
1810 | "version": "1.15.0",
1811 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1812 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1813 | "requires": {
1814 | "encodeurl": "~1.0.2",
1815 | "escape-html": "~1.0.3",
1816 | "parseurl": "~1.3.3",
1817 | "send": "0.18.0"
1818 | }
1819 | },
1820 | "set-function-length": {
1821 | "version": "1.2.2",
1822 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
1823 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
1824 | "requires": {
1825 | "define-data-property": "^1.1.4",
1826 | "es-errors": "^1.3.0",
1827 | "function-bind": "^1.1.2",
1828 | "get-intrinsic": "^1.2.4",
1829 | "gopd": "^1.0.1",
1830 | "has-property-descriptors": "^1.0.2"
1831 | }
1832 | },
1833 | "setprototypeof": {
1834 | "version": "1.2.0",
1835 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1836 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1837 | },
1838 | "shebang-command": {
1839 | "version": "2.0.0",
1840 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1841 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1842 | "requires": {
1843 | "shebang-regex": "^3.0.0"
1844 | }
1845 | },
1846 | "shebang-regex": {
1847 | "version": "3.0.0",
1848 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1849 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
1850 | },
1851 | "side-channel": {
1852 | "version": "1.0.6",
1853 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
1854 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
1855 | "requires": {
1856 | "call-bind": "^1.0.7",
1857 | "es-errors": "^1.3.0",
1858 | "get-intrinsic": "^1.2.4",
1859 | "object-inspect": "^1.13.1"
1860 | }
1861 | },
1862 | "signal-exit": {
1863 | "version": "4.1.0",
1864 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1865 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
1866 | },
1867 | "source-map": {
1868 | "version": "0.6.1",
1869 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1870 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
1871 | },
1872 | "statuses": {
1873 | "version": "2.0.1",
1874 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1875 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
1876 | },
1877 | "string-width": {
1878 | "version": "5.1.2",
1879 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
1880 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
1881 | "requires": {
1882 | "eastasianwidth": "^0.2.0",
1883 | "emoji-regex": "^9.2.2",
1884 | "strip-ansi": "^7.0.1"
1885 | }
1886 | },
1887 | "string-width-cjs": {
1888 | "version": "npm:string-width@4.2.3",
1889 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1890 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1891 | "requires": {
1892 | "emoji-regex": "^8.0.0",
1893 | "is-fullwidth-code-point": "^3.0.0",
1894 | "strip-ansi": "^6.0.1"
1895 | },
1896 | "dependencies": {
1897 | "ansi-regex": {
1898 | "version": "5.0.1",
1899 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1900 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
1901 | },
1902 | "emoji-regex": {
1903 | "version": "8.0.0",
1904 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1905 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
1906 | },
1907 | "strip-ansi": {
1908 | "version": "6.0.1",
1909 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1910 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1911 | "requires": {
1912 | "ansi-regex": "^5.0.1"
1913 | }
1914 | }
1915 | }
1916 | },
1917 | "strip-ansi": {
1918 | "version": "7.1.0",
1919 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
1920 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
1921 | "requires": {
1922 | "ansi-regex": "^6.0.1"
1923 | }
1924 | },
1925 | "strip-ansi-cjs": {
1926 | "version": "npm:strip-ansi@6.0.1",
1927 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1928 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1929 | "requires": {
1930 | "ansi-regex": "^5.0.1"
1931 | },
1932 | "dependencies": {
1933 | "ansi-regex": {
1934 | "version": "5.0.1",
1935 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1936 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
1937 | }
1938 | }
1939 | },
1940 | "toidentifier": {
1941 | "version": "1.0.1",
1942 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1943 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
1944 | },
1945 | "type-is": {
1946 | "version": "1.6.18",
1947 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1948 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1949 | "requires": {
1950 | "media-typer": "0.3.0",
1951 | "mime-types": "~2.1.24"
1952 | }
1953 | },
1954 | "uglify-js": {
1955 | "version": "3.19.1",
1956 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.1.tgz",
1957 | "integrity": "sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==",
1958 | "optional": true
1959 | },
1960 | "unpipe": {
1961 | "version": "1.0.0",
1962 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1963 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
1964 | },
1965 | "utils-merge": {
1966 | "version": "1.0.1",
1967 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1968 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
1969 | },
1970 | "vary": {
1971 | "version": "1.1.2",
1972 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1973 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
1974 | },
1975 | "which": {
1976 | "version": "2.0.2",
1977 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1978 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1979 | "requires": {
1980 | "isexe": "^2.0.0"
1981 | }
1982 | },
1983 | "wordwrap": {
1984 | "version": "1.0.0",
1985 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1986 | "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
1987 | },
1988 | "wrap-ansi": {
1989 | "version": "8.1.0",
1990 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
1991 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
1992 | "requires": {
1993 | "ansi-styles": "^6.1.0",
1994 | "string-width": "^5.0.1",
1995 | "strip-ansi": "^7.0.1"
1996 | }
1997 | },
1998 | "wrap-ansi-cjs": {
1999 | "version": "npm:wrap-ansi@7.0.0",
2000 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2001 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2002 | "requires": {
2003 | "ansi-styles": "^4.0.0",
2004 | "string-width": "^4.1.0",
2005 | "strip-ansi": "^6.0.0"
2006 | },
2007 | "dependencies": {
2008 | "ansi-regex": {
2009 | "version": "5.0.1",
2010 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2011 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
2012 | },
2013 | "ansi-styles": {
2014 | "version": "4.3.0",
2015 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2016 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2017 | "requires": {
2018 | "color-convert": "^2.0.1"
2019 | }
2020 | },
2021 | "emoji-regex": {
2022 | "version": "8.0.0",
2023 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2024 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
2025 | },
2026 | "string-width": {
2027 | "version": "4.2.3",
2028 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2029 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2030 | "requires": {
2031 | "emoji-regex": "^8.0.0",
2032 | "is-fullwidth-code-point": "^3.0.0",
2033 | "strip-ansi": "^6.0.1"
2034 | }
2035 | },
2036 | "strip-ansi": {
2037 | "version": "6.0.1",
2038 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2039 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2040 | "requires": {
2041 | "ansi-regex": "^5.0.1"
2042 | }
2043 | }
2044 | }
2045 | }
2046 | }
2047 | }
2048 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-first-web-components",
3 | "private": true,
4 | "version": "1.0.0",
5 | "description": "A demo app showing server-first web components with HTMX.",
6 | "main": "server/index.js",
7 | "type": "module",
8 | "scripts": {
9 | "server": "node ./server/index.js"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/EisenbergEffect/server-first-web-components.git"
14 | },
15 | "author": "EisenbergEffect",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/EisenbergEffect/server-first-web-components/issues"
19 | },
20 | "homepage": "https://github.com/EisenbergEffect/server-first-web-components#readme",
21 | "dependencies": {
22 | "express": "^4.19.2",
23 | "express-handlebars": "^7.1.3"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/server/context.js:
--------------------------------------------------------------------------------
1 | import { AsyncLocalStorage } from "async_hooks";
2 |
3 | const als = new AsyncLocalStorage();
4 |
5 | export const getCurrentContext = () => als.getStore();
6 | export const runInNewContext = (callback) => als.run(new Map(), callback);
7 | export const contextMiddleware = (req, res, next) => runInNewContext(next);
--------------------------------------------------------------------------------
/server/controllers/films.js:
--------------------------------------------------------------------------------
1 | import allFilms from "../data/films.js";
2 |
3 | const isAJAX = (req) => !!req.get("HX-Request");
4 |
5 | export default {
6 | "/films/:id": (req, res) => {
7 | const filmId = req.params.id;
8 | const film = allFilms.find(x => x.id == filmId);
9 |
10 | if (isAJAX(req)) {
11 | const viewModel = { film, layout: false };
12 | res.render("partials/film-detail", viewModel);
13 | } else {
14 | const viewModel = { films: allFilms, selectedFilm: film };
15 | res.render("home", viewModel);
16 | }
17 | },
18 | };
--------------------------------------------------------------------------------
/server/controllers/home.js:
--------------------------------------------------------------------------------
1 | import films from "../data/films.js";
2 |
3 | export default {
4 | "/": (req, res) => {
5 | const viewModel = { films, selectedFilm: films[0] };
6 | res.render("home", viewModel);
7 | }
8 | };
--------------------------------------------------------------------------------
/server/data/films.js:
--------------------------------------------------------------------------------
1 | // Data from https://swapi.dev/
2 |
3 | export default [
4 | {
5 | "id": 1,
6 | "episode_id": 4,
7 | "title": "A New Hope",
8 | "opening_crawl": "It is a period of civil war.\r\nRebel spaceships, striking\r\nfrom a hidden base, have won\r\ntheir first victory against\r\nthe evil Galactic Empire.\r\n\r\nDuring the battle, Rebel\r\nspies managed to steal secret\r\nplans to the Empire's\r\nultimate weapon, the DEATH\r\nSTAR, an armored space\r\nstation with enough power\r\nto destroy an entire planet.\r\n\r\nPursued by the Empire's\r\nsinister agents, Princess\r\nLeia races home aboard her\r\nstarship, custodian of the\r\nstolen plans that can save her\r\npeople and restore\r\nfreedom to the galaxy....",
9 | "director": "George Lucas",
10 | "producer": "Gary Kurtz, Rick McCallum",
11 | "release_date": "5/25/1977",
12 | },
13 | {
14 | "id": 2,
15 | "title": "The Empire Strikes Back",
16 | "episode_id": 5,
17 | "opening_crawl": "It is a dark time for the\r\nRebellion. Although the Death\r\nStar has been destroyed,\r\nImperial troops have driven the\r\nRebel forces from their hidden\r\nbase and pursued them across\r\nthe galaxy.\r\n\r\nEvading the dreaded Imperial\r\nStarfleet, a group of freedom\r\nfighters led by Luke Skywalker\r\nhas established a new secret\r\nbase on the remote ice world\r\nof Hoth.\r\n\r\nThe evil lord Darth Vader,\r\nobsessed with finding young\r\nSkywalker, has dispatched\r\nthousands of remote probes into\r\nthe far reaches of space....",
18 | "director": "Irvin Kershner",
19 | "producer": "Gary Kurtz, Rick McCallum",
20 | "release_date": "5/17/1980",
21 | },
22 | {
23 | "id": 3,
24 | "title": "Return of the Jedi",
25 | "episode_id": 6,
26 | "opening_crawl": "Luke Skywalker has returned to\r\nhis home planet of Tatooine in\r\nan attempt to rescue his\r\nfriend Han Solo from the\r\nclutches of the vile gangster\r\nJabba the Hutt.\r\n\r\nLittle does Luke know that the\r\nGALACTIC EMPIRE has secretly\r\nbegun construction on a new\r\narmored space station even\r\nmore powerful than the first\r\ndreaded Death Star.\r\n\r\nWhen completed, this ultimate\r\nweapon will spell certain doom\r\nfor the small band of rebels\r\nstruggling to restore freedom\r\nto the galaxy...",
27 | "director": "Richard Marquand",
28 | "producer": "Howard G. Kazanjian, George Lucas, Rick McCallum",
29 | "release_date": "5/25/1983",
30 | },
31 | {
32 | "id": 4,
33 | "title": "The Phantom Menace",
34 | "episode_id": 1,
35 | "opening_crawl": "Turmoil has engulfed the\r\nGalactic Republic. The taxation\r\nof trade routes to outlying star\r\nsystems is in dispute.\r\n\r\nHoping to resolve the matter\r\nwith a blockade of deadly\r\nbattleships, the greedy Trade\r\nFederation has stopped all\r\nshipping to the small planet\r\nof Naboo.\r\n\r\nWhile the Congress of the\r\nRepublic endlessly debates\r\nthis alarming chain of events,\r\nthe Supreme Chancellor has\r\nsecretly dispatched two Jedi\r\nKnights, the guardians of\r\npeace and justice in the\r\ngalaxy, to settle the conflict....",
36 | "director": "George Lucas",
37 | "producer": "Rick McCallum",
38 | "release_date": "5/19/1999",
39 | },
40 | {
41 | "id": 5,
42 | "title": "Attack of the Clones",
43 | "episode_id": 2,
44 | "opening_crawl": "There is unrest in the Galactic\r\nSenate. Several thousand solar\r\nsystems have declared their\r\nintentions to leave the Republic.\r\n\r\nThis separatist movement,\r\nunder the leadership of the\r\nmysterious Count Dooku, has\r\nmade it difficult for the limited\r\nnumber of Jedi Knights to maintain \r\npeace and order in the galaxy.\r\n\r\nSenator Amidala, the former\r\nQueen of Naboo, is returning\r\nto the Galactic Senate to vote\r\non the critical issue of creating\r\nan ARMY OF THE REPUBLIC\r\nto assist the overwhelmed\r\nJedi....",
45 | "director": "George Lucas",
46 | "producer": "Rick McCallum",
47 | "release_date": "5/16/2002",
48 | },
49 | {
50 | "id": 6,
51 | "title": "Revenge of the Sith",
52 | "episode_id": 3,
53 | "opening_crawl": "War! The Republic is crumbling\r\nunder attacks by the ruthless\r\nSith Lord, Count Dooku.\r\nThere are heroes on both sides.\r\nEvil is everywhere.\r\n\r\nIn a stunning move, the\r\nfiendish droid leader, General\r\nGrievous, has swept into the\r\nRepublic capital and kidnapped\r\nChancellor Palpatine, leader of\r\nthe Galactic Senate.\r\n\r\nAs the Separatist Droid Army\r\nattempts to flee the besieged\r\ncapital with their valuable\r\nhostage, two Jedi Knights lead a\r\ndesperate mission to rescue the\r\ncaptive Chancellor....",
54 | "director": "George Lucas",
55 | "producer": "Rick McCallum",
56 | "release_date": "5/19/2005",
57 | }
58 | ];
--------------------------------------------------------------------------------
/server/handlebars.js:
--------------------------------------------------------------------------------
1 | import { dirname, resolve } from "path";
2 | import { fileURLToPath } from "url";
3 | import { readFileSync } from "fs";
4 | import { engine } from "express-handlebars";
5 | import { getCurrentContext } from "./context.js";
6 |
7 | const __dirname = dirname(fileURLToPath(import.meta.url));
8 | const pathToStyleContent = new Map();
9 | const environment = process.env.NODE_ENV ?? "development";
10 |
11 | function loadStyleContent(src) {
12 | const path = resolve(__dirname, "./views/partials", src);
13 |
14 | if (environment === "development") {
15 | return readFileSync(path, "utf-8");
16 | }
17 |
18 | let styles = pathToStyleContent.get(path);
19 |
20 | if (!styles) {
21 | styles = readFileSync(path, "utf-8");
22 | pathToStyleContent.set(path, styles);
23 | }
24 |
25 | return styles;
26 | }
27 |
28 | const hbConfig = {
29 | extname: ".hbs",
30 | helpers: {
31 | "shared-styles": function(src, options) {
32 | const context = getCurrentContext();
33 | const stylesAlreadySent = context.get(src);
34 | let html = "";
35 |
36 | if (!stylesAlreadySent) {
37 | const styles = loadStyleContent(src);
38 | context.set(src, true)
39 | html = ``;
40 | }
41 |
42 | return html + `
{{film.opening_crawl}}
11 | 12 |