@metabase/custom-viz 0.0.1-alpha.5 → 0.0.1-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -6,37 +6,40 @@ import { createInterface as o } from "node:readline";
6
6
  import { Command as s } from "commander";
7
7
  import { fileURLToPath as c } from "node:url";
8
8
  //#region package.json
9
- var l = "0.0.1-alpha.5", u = "node_modules/\n.DS_Store\n# dist must be committed\n", d = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.79978 6.86661C1.65041 7.01583 1.53192 7.19302 1.45107 7.38806C1.37023 7.58309 1.32861 7.79215 1.32861 8.00328C1.32861 8.21441 1.37023 8.42347 1.45107 8.61851C1.53192 8.81354 1.65041 8.99073 1.79978 9.13995L6.85978 14.1999C7.00899 14.3493 7.18618 14.4678 7.38122 14.5487C7.57626 14.6295 7.78531 14.6711 7.99644 14.6711C8.20757 14.6711 8.41663 14.6295 8.61167 14.5487C8.80671 14.4678 8.9839 14.3493 9.13311 14.1999L14.1931 9.13995C14.3425 8.99073 14.461 8.81354 14.5418 8.61851C14.6227 8.42347 14.6643 8.21441 14.6643 8.00328C14.6643 7.79215 14.6227 7.58309 14.5418 7.38806C14.461 7.19302 14.3425 7.01583 14.1931 6.86661L9.13311 1.80661C8.9839 1.65725 8.80671 1.53875 8.61167 1.45791C8.41663 1.37706 8.20757 1.33545 7.99644 1.33545C7.78531 1.33545 7.57626 1.37706 7.38122 1.45791C7.18618 1.53875 7.00899 1.65725 6.85978 1.80661L1.79978 6.86661Z\" stroke=\"white\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n", f = "import type {\n CreateCustomVisualization,\n CustomStaticVisualizationProps,\n CustomVisualizationProps,\n} from \"@metabase/custom-viz\";\n\ntype Settings = {\n threshold?: number;\n};\n\nconst createVisualization: CreateCustomVisualization<Settings> = ({\n getAssetUrl,\n}) => {\n return {\n id: \"__CUSTOM_VIZ_NAME__\",\n getName: () => \"__CUSTOM_VIZ_NAME__\",\n minSize: { width: 1, height: 1 },\n defaultSize: { width: 2, height: 2 },\n isSensible({ cols, rows }) {\n return cols.length === 1 && rows.length === 1 && typeof rows[0][0] === \"number\";\n },\n checkRenderable(series, settings) {\n if (series.length !== 1) {\n throw new Error(\"Only 1 series is supported\");\n }\n\n const [\n {\n data: { cols, rows },\n },\n ] = series;\n\n if (cols.length !== 1) {\n throw new Error(\"Query results should only have 1 column\");\n }\n\n if (rows.length !== 1) {\n throw new Error(\"Query results should only have 1 row\");\n }\n\n if (typeof rows[0][0] !== \"number\") {\n throw new Error(\"Result is not a number\");\n }\n\n if (typeof settings.threshold !== \"number\") {\n throw new Error(\"Threshold setting is not set\");\n }\n },\n settings: {\n threshold: {\n id: \"1\",\n title: \"Threshold\",\n widget: \"number\",\n getDefault() {\n return 0;\n },\n getProps() {\n return {\n options: {\n isInteger: false,\n isNonNegative: false,\n },\n placeholder: \"Set threshold\",\n };\n },\n },\n },\n VisualizationComponent: makeVisualizationComponent(getAssetUrl),\n StaticVisualizationComponent: makeStaticVisualizationComponent(getAssetUrl),\n };\n};\n\nconst makeVisualizationComponent = (getAssetUrl: (path: string) => string) => (props: CustomVisualizationProps<Settings>) => {\n const { height, series, settings, width } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji = value >= threshold ? \"👍\" : \"👎\";\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nconst makeStaticVisualizationComponent = (getAssetUrl: (path: string) => string) => (\n props: CustomStaticVisualizationProps<Settings>,\n) => {\n const width = 540;\n const height = 360;\n const { series, settings } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji =\n value >= threshold ? (\n <img src={getAssetUrl(\"thumbs-up.png\")} />\n ) : (\n <img src={getAssetUrl(\"thumbs-down.png\")} />\n );\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nexport default createVisualization;\n", p = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"icon\": \"icon.svg\",\n \"assets\": [\"icon.svg\", \"thumbs-up.png\", \"thumbs-down.png\"],\n \"metabase\": {\n \"version\": \">=59\"\n }\n}\n", m = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"vite build\",\n \"dev\": \"vite build --watch\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@metabase/custom-viz\": \"__CUSTOM_VIZ_VERSION__\",\n \"@types/react\": \"^19.2.14\",\n \"react\": \"^19.1.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.0\"\n }\n}\n", h = "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"jsx\": \"react-jsx\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"outDir\": \"dist\",\n \"declaration\": true\n },\n \"include\": [\"src\"]\n}\n", g = "import { resolve } from \"path\";\nimport { createServer } from \"http\";\nimport { watch, cpSync } from \"fs\";\nimport { defineConfig } from \"vite\";\n\n/**\n * Vite plugin that replaces `react` and `react/jsx-runtime` imports with\n * virtual modules that read from Metabase's `window.__METABASE_VIZ_API__`.\n *\n * This is necessary because the ES module output format cannot use\n * `output.globals`, and bare `import 'react'` would fail in the browser.\n */\nfunction metabaseVizExternals() {\n const VIRTUAL_REACT = \"\\0virtual:react\";\n const VIRTUAL_JSX_RUNTIME = \"\\0virtual:react/jsx-runtime\";\n return {\n name: \"metabase-viz-externals\",\n enforce: \"pre\" as const,\n\n resolveId(source) {\n if (source === \"react\") {\n return VIRTUAL_REACT;\n }\n if (source === \"react/jsx-runtime\") {\n return VIRTUAL_JSX_RUNTIME;\n }\n return null;\n },\n\n load(id) {\n if (id === VIRTUAL_REACT) {\n return [\n \"const React = window.__METABASE_VIZ_API__.React;\",\n \"export default React;\",\n \"export const { useState, useEffect, useRef, useCallback, useMemo, useReducer, useContext, createElement, Fragment } = React;\",\n ].join(\"\\n\");\n }\n if (id === VIRTUAL_JSX_RUNTIME) {\n return [\n \"const jsxRuntime = window.__METABASE_VIZ_API__.jsxRuntime;\",\n \"export const { jsx, jsxs, Fragment } = jsxRuntime;\",\n ].join(\"\\n\");\n }\n return null;\n },\n };\n}\n\nconst DEV_PORT = 5174;\n\n/**\n * Vite plugin that starts a dev server serving both static files from dist/\n * and an SSE endpoint at /__sse for hot-reload notifications.\n * Metabase's frontend connects to /__sse on the same origin as dev_bundle_url.\n */\nfunction metabaseDevServer() {\n const clients = new Set<import(\"http\").ServerResponse>();\n let server: ReturnType<typeof createServer> | null = null;\n\n return {\n name: \"metabase-dev-server\",\n\n buildStart() {\n if (server) {\n return;\n }\n\n const distDir = resolve(__dirname, \"dist\");\n\n server = createServer((req, res) => {\n const url = req.url ?? \"/\";\n\n // SSE endpoint for hot-reload\n if (url === \"/__sse\") {\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n clients.add(res);\n req.on(\"close\", () => clients.delete(res));\n return;\n }\n\n // CORS headers for all static responses\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\n // Serve static files from dist/\n const { readFile, stat } = require(\"fs\");\n const { join, extname } = require(\"path\");\n\n const filePath = url === \"/\" ? join(distDir, \"index.html\") : join(distDir, url);\n\n // Prevent directory traversal\n if (!filePath.startsWith(distDir)) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n stat(filePath, (err: NodeJS.ErrnoException | null) => {\n if (err) {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const mimeTypes: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n };\n const contentType = mimeTypes[extname(filePath)] ?? \"application/octet-stream\";\n\n readFile(filePath, (readErr: NodeJS.ErrnoException | null, data: Buffer) => {\n if (readErr) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(data);\n });\n });\n });\n\n server.listen(DEV_PORT, () => {\n console.log(\n `[custom-viz] Dev server listening on http://localhost:${DEV_PORT}`,\n );\n });\n\n // Watch public/assets/ for changes — copy to dist/assets/ and notify\n const assetsDir = resolve(__dirname, \"public/assets\");\n watch(assetsDir, { recursive: true }, (_event, filename) => {\n if (!filename) {\n return;\n }\n cpSync(resolve(assetsDir, filename), resolve(__dirname, \"dist/assets\", filename));\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);\n });\n },\n\n closeBundle() {\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(\n `[custom-viz] Build complete, notified ${clients.size} client(s)`,\n );\n },\n };\n}\n\nconst isWatch = process.argv.includes(\"--watch\");\n\nexport default defineConfig({\n plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseDevServer()] : [])],\n publicDir: \"public\",\n build: {\n outDir: \"dist\",\n lib: {\n entry: resolve(__dirname, \"src/index.tsx\"),\n formats: [\"iife\"],\n fileName: () => \"index.js\",\n name: \"__customVizPlugin__\",\n },\n },\n});\n", _ = "__CUSTOM_VIZ_NAME__", v = "__CUSTOM_VIZ_VERSION__";
10
- function y(e, t) {
11
- return e.split(_).join(t);
9
+ var l = "0.0.1-alpha.7", u = "node_modules/\n.DS_Store\n# dist must be committed\n", d = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1.79978 6.86661C1.65041 7.01583 1.53192 7.19302 1.45107 7.38806C1.37023 7.58309 1.32861 7.79215 1.32861 8.00328C1.32861 8.21441 1.37023 8.42347 1.45107 8.61851C1.53192 8.81354 1.65041 8.99073 1.79978 9.13995L6.85978 14.1999C7.00899 14.3493 7.18618 14.4678 7.38122 14.5487C7.57626 14.6295 7.78531 14.6711 7.99644 14.6711C8.20757 14.6711 8.41663 14.6295 8.61167 14.5487C8.80671 14.4678 8.9839 14.3493 9.13311 14.1999L14.1931 9.13995C14.3425 8.99073 14.461 8.81354 14.5418 8.61851C14.6227 8.42347 14.6643 8.21441 14.6643 8.00328C14.6643 7.79215 14.6227 7.58309 14.5418 7.38806C14.461 7.19302 14.3425 7.01583 14.1931 6.86661L9.13311 1.80661C8.9839 1.65725 8.80671 1.53875 8.61167 1.45791C8.41663 1.37706 8.20757 1.33545 7.99644 1.33545C7.78531 1.33545 7.57626 1.37706 7.38122 1.45791C7.18618 1.53875 7.00899 1.65725 6.85978 1.80661L1.79978 6.86661Z\" stroke=\"white\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n", f = "import type {\n CreateCustomVisualization,\n CustomStaticVisualizationProps,\n CustomVisualizationProps,\n} from \"@metabase/custom-viz\";\n\ntype Settings = {\n threshold?: number;\n};\n\nconst createVisualization: CreateCustomVisualization<Settings> = ({\n getAssetUrl,\n}) => {\n return {\n id: \"__CUSTOM_VIZ_NAME__\",\n getName: () => \"__CUSTOM_VIZ_NAME__\",\n minSize: { width: 1, height: 1 },\n defaultSize: { width: 2, height: 2 },\n isSensible({ cols, rows }) {\n return cols.length === 1 && rows.length === 1 && typeof rows[0][0] === \"number\";\n },\n checkRenderable(series, settings) {\n if (series.length !== 1) {\n throw new Error(\"Only 1 series is supported\");\n }\n\n const [\n {\n data: { cols, rows },\n },\n ] = series;\n\n if (cols.length !== 1) {\n throw new Error(\"Query results should only have 1 column\");\n }\n\n if (rows.length !== 1) {\n throw new Error(\"Query results should only have 1 row\");\n }\n\n if (typeof rows[0][0] !== \"number\") {\n throw new Error(\"Result is not a number\");\n }\n\n if (typeof settings.threshold !== \"number\") {\n throw new Error(\"Threshold setting is not set\");\n }\n },\n settings: {\n threshold: {\n id: \"1\",\n title: \"Threshold\",\n widget: \"number\",\n getDefault() {\n return 0;\n },\n getProps() {\n return {\n options: {\n isInteger: false,\n isNonNegative: false,\n },\n placeholder: \"Set threshold\",\n };\n },\n },\n },\n VisualizationComponent: makeVisualizationComponent(getAssetUrl),\n StaticVisualizationComponent: makeStaticVisualizationComponent(getAssetUrl),\n };\n};\n\nconst makeVisualizationComponent = (getAssetUrl: (path: string) => string) => (props: CustomVisualizationProps<Settings>) => {\n const { height, series, settings, width } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji = value >= threshold ? \"👍\" : \"👎\";\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nconst makeStaticVisualizationComponent = (getAssetUrl: (path: string) => string) => (\n props: CustomStaticVisualizationProps<Settings>,\n) => {\n const width = 540;\n const height = 360;\n const { series, settings } = props;\n const { threshold } = settings;\n const value = series[0].data.rows[0][0];\n\n if (typeof value !== \"number\" || typeof threshold !== \"number\") {\n throw new Error(\"Value and threshold need to be numbers\");\n }\n\n const emoji =\n value >= threshold ? (\n <img src={getAssetUrl(\"thumbs-up.png\")} />\n ) : (\n <img src={getAssetUrl(\"thumbs-down.png\")} />\n );\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width,\n height,\n fontSize: \"10rem\",\n }}\n >\n {emoji}\n </div>\n );\n};\n\nexport default createVisualization;\n", p = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"icon\": \"icon.svg\",\n \"assets\": [\"icon.svg\", \"thumbs-up.png\", \"thumbs-down.png\"],\n \"metabase\": {\n \"version\": \">=59\"\n }\n}\n", m = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"lockfileVersion\": 3,\n \"requires\": true,\n \"packages\": {\n \"\": {\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"devDependencies\": {\n \"@metabase/custom-viz\": \"__CUSTOM_VIZ_VERSION__\",\n \"@types/react\": \"^19.2.14\",\n \"react\": \"^19.1.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.0\"\n }\n },\n \"node_modules/@emnapi/core\": {\n \"version\": \"1.9.1\",\n \"resolved\": \"https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz\",\n \"integrity\": \"sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"peer\": true,\n \"dependencies\": {\n \"@emnapi/wasi-threads\": \"1.2.0\",\n \"tslib\": \"^2.4.0\"\n }\n },\n \"node_modules/@emnapi/runtime\": {\n \"version\": \"1.9.1\",\n \"resolved\": \"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz\",\n \"integrity\": \"sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"peer\": true,\n \"dependencies\": {\n \"tslib\": \"^2.4.0\"\n }\n },\n \"node_modules/@emnapi/wasi-threads\": {\n \"version\": \"1.2.0\",\n \"resolved\": \"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz\",\n \"integrity\": \"sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"peer\": true,\n \"dependencies\": {\n \"tslib\": \"^2.4.0\"\n }\n },\n \"node_modules/@metabase/custom-viz\": {\n \"version\": \"__CUSTOM_VIZ_VERSION__\",\n \"resolved\": \"https://registry.npmjs.org/@metabase/custom-viz/-/custom-viz-__CUSTOM_VIZ_VERSION__.tgz\",\n \"dev\": true,\n \"dependencies\": {\n \"commander\": \"^13.1.0\"\n },\n \"bin\": {\n \"metabase-custom-viz\": \"dist/cli.js\"\n }\n },\n \"node_modules/@napi-rs/wasm-runtime\": {\n \"version\": \"1.1.2\",\n \"resolved\": \"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz\",\n \"integrity\": \"sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"dependencies\": {\n \"@tybys/wasm-util\": \"^0.10.1\"\n },\n \"funding\": {\n \"type\": \"github\",\n \"url\": \"https://github.com/sponsors/Brooooooklyn\"\n },\n \"peerDependencies\": {\n \"@emnapi/core\": \"^1.7.1\",\n \"@emnapi/runtime\": \"^1.7.1\"\n }\n },\n \"node_modules/@oxc-project/types\": {\n \"version\": \"0.122.0\",\n \"resolved\": \"https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz\",\n \"integrity\": \"sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"funding\": {\n \"url\": \"https://github.com/sponsors/Boshen\"\n }\n },\n \"node_modules/@rolldown/binding-android-arm64\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"android\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-darwin-arm64\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"darwin\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-darwin-x64\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"darwin\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-freebsd-x64\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"freebsd\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-arm-gnueabihf\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==\",\n \"cpu\": [\n \"arm\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-arm64-gnu\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-arm64-musl\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-ppc64-gnu\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==\",\n \"cpu\": [\n \"ppc64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-s390x-gnu\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==\",\n \"cpu\": [\n \"s390x\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-x64-gnu\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-linux-x64-musl\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-openharmony-arm64\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"openharmony\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-wasm32-wasi\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==\",\n \"cpu\": [\n \"wasm32\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"dependencies\": {\n \"@napi-rs/wasm-runtime\": \"^1.1.1\"\n },\n \"engines\": {\n \"node\": \">=14.0.0\"\n }\n },\n \"node_modules/@rolldown/binding-win32-arm64-msvc\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"win32\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/binding-win32-x64-msvc\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"win32\"\n ],\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n }\n },\n \"node_modules/@rolldown/pluginutils\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==\",\n \"dev\": true,\n \"license\": \"MIT\"\n },\n \"node_modules/@tybys/wasm-util\": {\n \"version\": \"0.10.1\",\n \"resolved\": \"https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz\",\n \"integrity\": \"sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"dependencies\": {\n \"tslib\": \"^2.4.0\"\n }\n },\n \"node_modules/@types/react\": {\n \"version\": \"19.2.14\",\n \"resolved\": \"https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz\",\n \"integrity\": \"sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"dependencies\": {\n \"csstype\": \"^3.2.2\"\n }\n },\n \"node_modules/commander\": {\n \"version\": \"13.1.0\",\n \"resolved\": \"https://registry.npmjs.org/commander/-/commander-13.1.0.tgz\",\n \"integrity\": \"sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=18\"\n }\n },\n \"node_modules/csstype\": {\n \"version\": \"3.2.3\",\n \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz\",\n \"integrity\": \"sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==\",\n \"dev\": true,\n \"license\": \"MIT\"\n },\n \"node_modules/detect-libc\": {\n \"version\": \"2.1.2\",\n \"resolved\": \"https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz\",\n \"integrity\": \"sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==\",\n \"dev\": true,\n \"license\": \"Apache-2.0\",\n \"engines\": {\n \"node\": \">=8\"\n }\n },\n \"node_modules/fdir\": {\n \"version\": \"6.5.0\",\n \"resolved\": \"https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz\",\n \"integrity\": \"sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=12.0.0\"\n },\n \"peerDependencies\": {\n \"picomatch\": \"^3 || ^4\"\n },\n \"peerDependenciesMeta\": {\n \"picomatch\": {\n \"optional\": true\n }\n }\n },\n \"node_modules/fsevents\": {\n \"version\": \"2.3.3\",\n \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz\",\n \"integrity\": \"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==\",\n \"dev\": true,\n \"hasInstallScript\": true,\n \"license\": \"MIT\",\n \"optional\": true,\n \"os\": [\n \"darwin\"\n ],\n \"engines\": {\n \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n }\n },\n \"node_modules/lightningcss\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz\",\n \"integrity\": \"sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==\",\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"dependencies\": {\n \"detect-libc\": \"^2.0.3\"\n },\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n },\n \"optionalDependencies\": {\n \"lightningcss-android-arm64\": \"1.32.0\",\n \"lightningcss-darwin-arm64\": \"1.32.0\",\n \"lightningcss-darwin-x64\": \"1.32.0\",\n \"lightningcss-freebsd-x64\": \"1.32.0\",\n \"lightningcss-linux-arm-gnueabihf\": \"1.32.0\",\n \"lightningcss-linux-arm64-gnu\": \"1.32.0\",\n \"lightningcss-linux-arm64-musl\": \"1.32.0\",\n \"lightningcss-linux-x64-gnu\": \"1.32.0\",\n \"lightningcss-linux-x64-musl\": \"1.32.0\",\n \"lightningcss-win32-arm64-msvc\": \"1.32.0\",\n \"lightningcss-win32-x64-msvc\": \"1.32.0\"\n }\n },\n \"node_modules/lightningcss-android-arm64\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz\",\n \"integrity\": \"sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"android\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-darwin-arm64\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz\",\n \"integrity\": \"sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"darwin\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-darwin-x64\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz\",\n \"integrity\": \"sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"darwin\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-freebsd-x64\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz\",\n \"integrity\": \"sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"freebsd\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-linux-arm-gnueabihf\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz\",\n \"integrity\": \"sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==\",\n \"cpu\": [\n \"arm\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-linux-arm64-gnu\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz\",\n \"integrity\": \"sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-linux-arm64-musl\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz\",\n \"integrity\": \"sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-linux-x64-gnu\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz\",\n \"integrity\": \"sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-linux-x64-musl\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz\",\n \"integrity\": \"sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"linux\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-win32-arm64-msvc\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz\",\n \"integrity\": \"sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==\",\n \"cpu\": [\n \"arm64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"win32\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/lightningcss-win32-x64-msvc\": {\n \"version\": \"1.32.0\",\n \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz\",\n \"integrity\": \"sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==\",\n \"cpu\": [\n \"x64\"\n ],\n \"dev\": true,\n \"license\": \"MPL-2.0\",\n \"optional\": true,\n \"os\": [\n \"win32\"\n ],\n \"engines\": {\n \"node\": \">= 12.0.0\"\n },\n \"funding\": {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/parcel\"\n }\n },\n \"node_modules/nanoid\": {\n \"version\": \"3.3.11\",\n \"resolved\": \"https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz\",\n \"integrity\": \"sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==\",\n \"dev\": true,\n \"funding\": [\n {\n \"type\": \"github\",\n \"url\": \"https://github.com/sponsors/ai\"\n }\n ],\n \"license\": \"MIT\",\n \"bin\": {\n \"nanoid\": \"bin/nanoid.cjs\"\n },\n \"engines\": {\n \"node\": \"^10 || ^12 || ^13.7 || ^14 || >=15.0.1\"\n }\n },\n \"node_modules/picocolors\": {\n \"version\": \"1.1.1\",\n \"resolved\": \"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz\",\n \"integrity\": \"sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==\",\n \"dev\": true,\n \"license\": \"ISC\"\n },\n \"node_modules/picomatch\": {\n \"version\": \"4.0.4\",\n \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz\",\n \"integrity\": \"sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=12\"\n },\n \"funding\": {\n \"url\": \"https://github.com/sponsors/jonschlinkert\"\n }\n },\n \"node_modules/postcss\": {\n \"version\": \"8.5.8\",\n \"resolved\": \"https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz\",\n \"integrity\": \"sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==\",\n \"dev\": true,\n \"funding\": [\n {\n \"type\": \"opencollective\",\n \"url\": \"https://opencollective.com/postcss/\"\n },\n {\n \"type\": \"tidelift\",\n \"url\": \"https://tidelift.com/funding/github/npm/postcss\"\n },\n {\n \"type\": \"github\",\n \"url\": \"https://github.com/sponsors/ai\"\n }\n ],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"nanoid\": \"^3.3.11\",\n \"picocolors\": \"^1.1.1\",\n \"source-map-js\": \"^1.2.1\"\n },\n \"engines\": {\n \"node\": \"^10 || ^12 || >=14\"\n }\n },\n \"node_modules/react\": {\n \"version\": \"19.2.4\",\n \"resolved\": \"https://registry.npmjs.org/react/-/react-19.2.4.tgz\",\n \"integrity\": \"sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=0.10.0\"\n }\n },\n \"node_modules/rolldown\": {\n \"version\": \"1.0.0-rc.12\",\n \"resolved\": \"https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz\",\n \"integrity\": \"sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@oxc-project/types\": \"=0.122.0\",\n \"@rolldown/pluginutils\": \"1.0.0-rc.12\"\n },\n \"bin\": {\n \"rolldown\": \"bin/cli.mjs\"\n },\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n },\n \"optionalDependencies\": {\n \"@rolldown/binding-android-arm64\": \"1.0.0-rc.12\",\n \"@rolldown/binding-darwin-arm64\": \"1.0.0-rc.12\",\n \"@rolldown/binding-darwin-x64\": \"1.0.0-rc.12\",\n \"@rolldown/binding-freebsd-x64\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-arm-gnueabihf\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-arm64-gnu\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-arm64-musl\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-ppc64-gnu\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-s390x-gnu\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-x64-gnu\": \"1.0.0-rc.12\",\n \"@rolldown/binding-linux-x64-musl\": \"1.0.0-rc.12\",\n \"@rolldown/binding-openharmony-arm64\": \"1.0.0-rc.12\",\n \"@rolldown/binding-wasm32-wasi\": \"1.0.0-rc.12\",\n \"@rolldown/binding-win32-arm64-msvc\": \"1.0.0-rc.12\",\n \"@rolldown/binding-win32-x64-msvc\": \"1.0.0-rc.12\"\n }\n },\n \"node_modules/source-map-js\": {\n \"version\": \"1.2.1\",\n \"resolved\": \"https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz\",\n \"integrity\": \"sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==\",\n \"dev\": true,\n \"license\": \"BSD-3-Clause\",\n \"engines\": {\n \"node\": \">=0.10.0\"\n }\n },\n \"node_modules/tinyglobby\": {\n \"version\": \"0.2.15\",\n \"resolved\": \"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz\",\n \"integrity\": \"sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"dependencies\": {\n \"fdir\": \"^6.5.0\",\n \"picomatch\": \"^4.0.3\"\n },\n \"engines\": {\n \"node\": \">=12.0.0\"\n },\n \"funding\": {\n \"url\": \"https://github.com/sponsors/SuperchupuDev\"\n }\n },\n \"node_modules/tslib\": {\n \"version\": \"2.8.1\",\n \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz\",\n \"integrity\": \"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==\",\n \"dev\": true,\n \"license\": \"0BSD\",\n \"optional\": true\n },\n \"node_modules/typescript\": {\n \"version\": \"5.9.3\",\n \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\n \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\n \"dev\": true,\n \"license\": \"Apache-2.0\",\n \"bin\": {\n \"tsc\": \"bin/tsc\",\n \"tsserver\": \"bin/tsserver\"\n },\n \"engines\": {\n \"node\": \">=14.17\"\n }\n },\n \"node_modules/vite\": {\n \"version\": \"8.0.3\",\n \"resolved\": \"https://registry.npmjs.org/vite/-/vite-8.0.3.tgz\",\n \"integrity\": \"sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==\",\n \"dev\": true,\n \"license\": \"MIT\",\n \"dependencies\": {\n \"lightningcss\": \"^1.32.0\",\n \"picomatch\": \"^4.0.4\",\n \"postcss\": \"^8.5.8\",\n \"rolldown\": \"1.0.0-rc.12\",\n \"tinyglobby\": \"^0.2.15\"\n },\n \"bin\": {\n \"vite\": \"bin/vite.js\"\n },\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n },\n \"funding\": {\n \"url\": \"https://github.com/vitejs/vite?sponsor=1\"\n },\n \"optionalDependencies\": {\n \"fsevents\": \"~2.3.3\"\n },\n \"peerDependencies\": {\n \"@types/node\": \"^20.19.0 || >=22.12.0\",\n \"@vitejs/devtools\": \"^0.1.0\",\n \"esbuild\": \"^0.27.0\",\n \"jiti\": \">=1.21.0\",\n \"less\": \"^4.0.0\",\n \"sass\": \"^1.70.0\",\n \"sass-embedded\": \"^1.70.0\",\n \"stylus\": \">=0.54.8\",\n \"sugarss\": \"^5.0.0\",\n \"terser\": \"^5.16.0\",\n \"tsx\": \"^4.8.1\",\n \"yaml\": \"^2.4.2\"\n },\n \"peerDependenciesMeta\": {\n \"@types/node\": {\n \"optional\": true\n },\n \"@vitejs/devtools\": {\n \"optional\": true\n },\n \"esbuild\": {\n \"optional\": true\n },\n \"jiti\": {\n \"optional\": true\n },\n \"less\": {\n \"optional\": true\n },\n \"sass\": {\n \"optional\": true\n },\n \"sass-embedded\": {\n \"optional\": true\n },\n \"stylus\": {\n \"optional\": true\n },\n \"sugarss\": {\n \"optional\": true\n },\n \"terser\": {\n \"optional\": true\n },\n \"tsx\": {\n \"optional\": true\n },\n \"yaml\": {\n \"optional\": true\n }\n }\n }\n }\n}\n", h = "{\n \"name\": \"__CUSTOM_VIZ_NAME__\",\n \"version\": \"0.0.1\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"vite build\",\n \"dev\": \"vite build --watch\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"devDependencies\": {\n \"@metabase/custom-viz\": \"__CUSTOM_VIZ_VERSION__\",\n \"@types/react\": \"^19.2.14\",\n \"react\": \"^19.1.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.0\"\n }\n}\n", g = "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"jsx\": \"react-jsx\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"outDir\": \"dist\",\n \"declaration\": true\n },\n \"include\": [\"src\"]\n}\n", _ = "import { resolve } from \"path\";\nimport { createServer } from \"http\";\nimport { watch, cpSync, existsSync } from \"fs\";\nimport { defineConfig } from \"vite\";\n\n/**\n * Vite plugin that replaces `react` and `react/jsx-runtime` imports with\n * virtual modules that read from Metabase's `window.__METABASE_VIZ_API__`.\n *\n * This is necessary because the ES module output format cannot use\n * `output.globals`, and bare `import 'react'` would fail in the browser.\n */\nfunction metabaseVizExternals() {\n const VIRTUAL_REACT = \"\\0virtual:react\";\n const VIRTUAL_JSX_RUNTIME = \"\\0virtual:react/jsx-runtime\";\n return {\n name: \"metabase-viz-externals\",\n enforce: \"pre\" as const,\n\n resolveId(source) {\n if (source === \"react\") {\n return VIRTUAL_REACT;\n }\n if (source === \"react/jsx-runtime\") {\n return VIRTUAL_JSX_RUNTIME;\n }\n return null;\n },\n\n load(id) {\n if (id === VIRTUAL_REACT) {\n return [\n \"const React = window.__METABASE_VIZ_API__.React;\",\n \"export default React;\",\n \"export const { useState, useEffect, useRef, useCallback, useMemo, useReducer, useContext, createElement, Fragment } = React;\",\n ].join(\"\\n\");\n }\n if (id === VIRTUAL_JSX_RUNTIME) {\n return [\n \"const jsxRuntime = window.__METABASE_VIZ_API__.jsxRuntime;\",\n \"export const { jsx, jsxs, Fragment } = jsxRuntime;\",\n ].join(\"\\n\");\n }\n return null;\n },\n };\n}\n\nconst DEV_PORT = 5174;\n\n/**\n * Vite plugin that starts a dev server serving both static files from dist/\n * and an SSE endpoint at /__sse for hot-reload notifications.\n * Metabase's frontend connects to /__sse on the same origin as dev_bundle_url.\n */\nfunction metabaseDevServer() {\n const clients = new Set<import(\"http\").ServerResponse>();\n let server: ReturnType<typeof createServer> | null = null;\n\n return {\n name: \"metabase-dev-server\",\n\n buildStart() {\n if (server) {\n return;\n }\n\n const distDir = resolve(__dirname, \"dist\");\n\n server = createServer((req, res) => {\n const url = req.url ?? \"/\";\n\n // SSE endpoint for hot-reload\n if (url === \"/__sse\") {\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n clients.add(res);\n req.on(\"close\", () => clients.delete(res));\n return;\n }\n\n // CORS headers for all static responses\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\n // Serve static files from dist/\n const { readFile, stat } = require(\"fs\");\n const { join, extname } = require(\"path\");\n\n const filePath = url === \"/\" ? join(distDir, \"index.html\") : join(distDir, url);\n\n // Prevent directory traversal\n if (!filePath.startsWith(distDir)) {\n res.writeHead(403);\n res.end(\"Forbidden\");\n return;\n }\n\n stat(filePath, (err: NodeJS.ErrnoException | null) => {\n if (err) {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const mimeTypes: Record<string, string> = {\n \".html\": \"text/html\",\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n };\n const contentType = mimeTypes[extname(filePath)] ?? \"application/octet-stream\";\n\n readFile(filePath, (readErr: NodeJS.ErrnoException | null, data: Buffer) => {\n if (readErr) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(data);\n });\n });\n });\n\n server.listen(DEV_PORT, () => {\n console.log(\n `[custom-viz] Dev server listening on http://localhost:${DEV_PORT}`,\n );\n });\n\n // Watch public/assets/ for changes — copy to dist/assets/ and notify\n const assetsDir = resolve(__dirname, \"public/assets\");\n if (existsSync(assetsDir)) {\n watch(assetsDir, { recursive: true }, (_event, filename) => {\n if (!filename) {\n return;\n }\n cpSync(resolve(assetsDir, filename), resolve(__dirname, \"dist/assets\", filename));\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);\n });\n }\n },\n\n closeBundle() {\n for (const client of clients) {\n client.write(\"data: reload\\n\\n\");\n }\n console.log(\n `[custom-viz] Build complete, notified ${clients.size} client(s)`,\n );\n },\n };\n}\n\nconst isWatch = process.argv.includes(\"--watch\");\n\nexport default defineConfig({\n plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseDevServer()] : [])],\n publicDir: \"public\",\n define: {\n \"process.env.NODE_ENV\": JSON.stringify(\"production\"),\n \"process.env\": JSON.stringify({}),\n },\n build: {\n outDir: \"dist\",\n lib: {\n entry: resolve(__dirname, \"src/index.tsx\"),\n formats: [\"iife\"],\n fileName: () => \"index.js\",\n name: \"__customVizPlugin__\",\n },\n },\n});\n", v = "__CUSTOM_VIZ_NAME__", y = "__CUSTOM_VIZ_VERSION__";
10
+ function b(e, t) {
11
+ return e.split(v).join(t);
12
12
  }
13
- function b(e) {
14
- return y(m, e).split(v).join(l);
13
+ function x(e) {
14
+ return b(h, e).split(y).join(l);
15
15
  }
16
- function x() {
17
- return g;
16
+ function S(e) {
17
+ return b(m, e).split(y).join(l);
18
+ }
19
+ function C() {
20
+ return _;
18
21
  }
19
- function S() {
20
- return h;
22
+ function w() {
23
+ return g;
21
24
  }
22
- function C(e) {
23
- return y(f, e);
25
+ function T(e) {
26
+ return b(f, e);
24
27
  }
25
- function w(e) {
26
- return y(p, e);
28
+ function E(e) {
29
+ return b(p, e);
27
30
  }
28
- function T() {
31
+ function D() {
29
32
  return d;
30
33
  }
31
- var E = a(i(c(import.meta.url)), "templates");
32
- function D(e) {
33
- return t(a(E, e));
34
+ var O = a(i(c(import.meta.url)), "templates");
35
+ function k(e) {
36
+ return t(a(O, e));
34
37
  }
35
- function O() {
38
+ function A() {
36
39
  return u;
37
40
  }
38
- function k(e) {
39
- let t = JSON.parse(e), n = JSON.parse(m.split(_).join("__placeholder__").split(v).join(l));
41
+ function j(e) {
42
+ let t = JSON.parse(e), n = JSON.parse(h.split(v).join("__placeholder__").split(y).join(l));
40
43
  return t.devDependencies = {
41
44
  ...t.devDependencies,
42
45
  ...n.devDependencies
@@ -47,21 +50,22 @@ function k(e) {
47
50
  }
48
51
  //#endregion
49
52
  //#region src/cli.ts
50
- var A = new s();
51
- A.name("metabase-custom-viz").description("CLI for creating custom visualizations for Metabase").version(l), A.command("init").description("Scaffold a new custom visualization").argument("<name>", "Name of the custom visualization").action(async (t) => {
53
+ var M = new s();
54
+ M.name("metabase-custom-viz").description("CLI for creating custom visualizations for Metabase").version(l), M.command("init").description("Scaffold a new custom visualization").argument("<name>", "Name of the custom visualization").action(async (t) => {
52
55
  let i = t.trim().replace(/\s+/g, "-").toLowerCase();
53
56
  (!i || !/^[a-z0-9@][a-z0-9._\-/]*$/.test(i)) && (console.error(`Error: "${t}" is not a valid project name. Use letters, numbers, hyphens, and dots.`), process.exit(1)), e(i) && (console.error(`Error: Directory "${i}" already exists.`), process.exit(1)), console.log(`Scaffolding custom visualization: ${i}\n`), await Promise.all([n(a(i, "src"), { recursive: !0 }), n(a(i, "public", "assets"), { recursive: !0 })]), await Promise.all([
54
- r(a(i, "package.json"), b(i)),
55
- r(a(i, "vite.config.ts"), x()),
56
- r(a(i, "tsconfig.json"), S()),
57
- r(a(i, "src", "index.tsx"), C(i)),
58
- r(a(i, "metabase-plugin.json"), w(i)),
59
- r(a(i, "public", "assets", "icon.svg"), T()),
60
- r(a(i, "public", "assets", "thumbs-up.png"), D("thumbs-up.png")),
61
- r(a(i, "public", "assets", "thumbs-down.png"), D("thumbs-down.png")),
62
- r(a(i, ".gitignore"), O())
63
- ]), console.log("Created files:"), console.log(` ${i}/package.json`), console.log(` ${i}/vite.config.ts`), console.log(` ${i}/tsconfig.json`), console.log(` ${i}/src/index.tsx`), console.log(` ${i}/metabase-plugin.json`), console.log(` ${i}/public/assets/icon.svg`), console.log(` ${i}/public/assets/thumbs-up.png`), console.log(` ${i}/public/assets/thumbs-down.png`), console.log(` ${i}/.gitignore`), console.log(), console.log("Next steps:"), console.log(` cd ${i}`), console.log(" npm install"), console.log(" npm run dev # Watch mode"), console.log(" npm run build # Production build");
64
- }), A.command("upgrade").description("Upgrade an existing custom visualization to the latest template version").action(async () => {
57
+ r(a(i, "package.json"), x(i)),
58
+ r(a(i, "package-lock.json"), S(i)),
59
+ r(a(i, "vite.config.ts"), C()),
60
+ r(a(i, "tsconfig.json"), w()),
61
+ r(a(i, "src", "index.tsx"), T(i)),
62
+ r(a(i, "metabase-plugin.json"), E(i)),
63
+ r(a(i, "public", "assets", "icon.svg"), D()),
64
+ r(a(i, "public", "assets", "thumbs-up.png"), k("thumbs-up.png")),
65
+ r(a(i, "public", "assets", "thumbs-down.png"), k("thumbs-down.png")),
66
+ r(a(i, ".gitignore"), A())
67
+ ]), console.log("Created files:"), console.log(` ${i}/package.json`), console.log(` ${i}/package-lock.json`), console.log(` ${i}/vite.config.ts`), console.log(` ${i}/tsconfig.json`), console.log(` ${i}/src/index.tsx`), console.log(` ${i}/metabase-plugin.json`), console.log(` ${i}/public/assets/icon.svg`), console.log(` ${i}/public/assets/thumbs-up.png`), console.log(` ${i}/public/assets/thumbs-down.png`), console.log(` ${i}/.gitignore`), console.log(), console.log("Next steps:"), console.log(` cd ${i}`), console.log(" npm install"), console.log(" npm run dev # Watch mode"), console.log(" npm run build # Production build");
68
+ }), M.command("upgrade").description("Upgrade an existing custom visualization to the latest template version").action(async () => {
65
69
  let n = process.cwd(), i = a(n, "package.json");
66
70
  e(i) || (console.error("Error: No package.json found. Run this command from the root of a custom visualization project."), process.exit(1));
67
71
  let o;
@@ -71,21 +75,21 @@ A.name("metabase-custom-viz").description("CLI for creating custom visualization
71
75
  console.error("Error: Could not parse package.json."), process.exit(1);
72
76
  }
73
77
  let s = o.devDependencies?.["@metabase/custom-viz"];
74
- if (s || (console.error("Error: @metabase/custom-viz not found in devDependencies. Is this a custom visualization project?"), process.exit(1)), s === "0.0.1-alpha.5") {
78
+ if (s || (console.error("Error: @metabase/custom-viz not found in devDependencies. Is this a custom visualization project?"), process.exit(1)), s === "0.0.1-alpha.7") {
75
79
  console.log(`Already up to date (v${l}). No changes needed.`);
76
80
  return;
77
81
  }
78
- if (console.log(`Upgrading from @metabase/custom-viz ${s} → ${l}\n`), console.log("The following changes will be made:\n"), console.log(" vite.config.ts — Replace with the latest build configuration"), console.log(" tsconfig.json — Replace with the latest TypeScript configuration"), console.log(" .gitignore — Replace with the latest gitignore rules"), console.log(" package.json — Update devDependencies and scripts to latest versions"), console.log(), console.log("Your source code (src/), assets (public/), and metabase-plugin.json will NOT be modified.\n"), !await j("Proceed with upgrade?")) {
82
+ if (console.log(`Upgrading from @metabase/custom-viz ${s} → ${l}\n`), console.log("The following changes will be made:\n"), console.log(" vite.config.ts — Replace with the latest build configuration"), console.log(" tsconfig.json — Replace with the latest TypeScript configuration"), console.log(" .gitignore — Replace with the latest gitignore rules"), console.log(" package.json — Update devDependencies and scripts to latest versions"), console.log(), console.log("Your source code (src/), assets (public/), and metabase-plugin.json will NOT be modified.\n"), !await N("Proceed with upgrade?")) {
79
83
  console.log("Upgrade cancelled.");
80
84
  return;
81
85
  }
82
86
  console.log();
83
87
  let c = [];
84
- await r(a(n, "vite.config.ts"), x()), c.push("vite.config.ts"), await r(a(n, "tsconfig.json"), S()), c.push("tsconfig.json"), await r(a(n, ".gitignore"), O()), c.push(".gitignore"), await r(i, k(t(i, "utf-8"))), c.push("package.json"), console.log("Updated files:");
88
+ await r(a(n, "vite.config.ts"), C()), c.push("vite.config.ts"), await r(a(n, "tsconfig.json"), w()), c.push("tsconfig.json"), await r(a(n, ".gitignore"), A()), c.push(".gitignore"), await r(i, j(t(i, "utf-8"))), c.push("package.json"), console.log("Updated files:");
85
89
  for (let e of c) console.log(` ${e}`);
86
90
  console.log(), console.log("Next steps:"), console.log(" npm install # Install updated dependencies");
87
91
  });
88
- function j(e) {
92
+ function N(e) {
89
93
  let t = o({
90
94
  input: process.stdin,
91
95
  output: process.stdout
@@ -96,5 +100,5 @@ function j(e) {
96
100
  });
97
101
  });
98
102
  }
99
- A.parse();
103
+ M.parse();
100
104
  //#endregion
@@ -0,0 +1,939 @@
1
+ {
2
+ "name": "__CUSTOM_VIZ_NAME__",
3
+ "version": "0.0.1",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "__CUSTOM_VIZ_NAME__",
9
+ "version": "0.0.1",
10
+ "devDependencies": {
11
+ "@metabase/custom-viz": "__CUSTOM_VIZ_VERSION__",
12
+ "@types/react": "^19.2.14",
13
+ "react": "^19.1.0",
14
+ "typescript": "^5.9.3",
15
+ "vite": "^8.0.0"
16
+ }
17
+ },
18
+ "node_modules/@emnapi/core": {
19
+ "version": "1.9.1",
20
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz",
21
+ "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==",
22
+ "dev": true,
23
+ "license": "MIT",
24
+ "optional": true,
25
+ "peer": true,
26
+ "dependencies": {
27
+ "@emnapi/wasi-threads": "1.2.0",
28
+ "tslib": "^2.4.0"
29
+ }
30
+ },
31
+ "node_modules/@emnapi/runtime": {
32
+ "version": "1.9.1",
33
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz",
34
+ "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==",
35
+ "dev": true,
36
+ "license": "MIT",
37
+ "optional": true,
38
+ "peer": true,
39
+ "dependencies": {
40
+ "tslib": "^2.4.0"
41
+ }
42
+ },
43
+ "node_modules/@emnapi/wasi-threads": {
44
+ "version": "1.2.0",
45
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz",
46
+ "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==",
47
+ "dev": true,
48
+ "license": "MIT",
49
+ "optional": true,
50
+ "peer": true,
51
+ "dependencies": {
52
+ "tslib": "^2.4.0"
53
+ }
54
+ },
55
+ "node_modules/@metabase/custom-viz": {
56
+ "version": "__CUSTOM_VIZ_VERSION__",
57
+ "resolved": "https://registry.npmjs.org/@metabase/custom-viz/-/custom-viz-__CUSTOM_VIZ_VERSION__.tgz",
58
+ "dev": true,
59
+ "dependencies": {
60
+ "commander": "^13.1.0"
61
+ },
62
+ "bin": {
63
+ "metabase-custom-viz": "dist/cli.js"
64
+ }
65
+ },
66
+ "node_modules/@napi-rs/wasm-runtime": {
67
+ "version": "1.1.2",
68
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz",
69
+ "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==",
70
+ "dev": true,
71
+ "license": "MIT",
72
+ "optional": true,
73
+ "dependencies": {
74
+ "@tybys/wasm-util": "^0.10.1"
75
+ },
76
+ "funding": {
77
+ "type": "github",
78
+ "url": "https://github.com/sponsors/Brooooooklyn"
79
+ },
80
+ "peerDependencies": {
81
+ "@emnapi/core": "^1.7.1",
82
+ "@emnapi/runtime": "^1.7.1"
83
+ }
84
+ },
85
+ "node_modules/@oxc-project/types": {
86
+ "version": "0.122.0",
87
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz",
88
+ "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==",
89
+ "dev": true,
90
+ "license": "MIT",
91
+ "funding": {
92
+ "url": "https://github.com/sponsors/Boshen"
93
+ }
94
+ },
95
+ "node_modules/@rolldown/binding-android-arm64": {
96
+ "version": "1.0.0-rc.12",
97
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz",
98
+ "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==",
99
+ "cpu": [
100
+ "arm64"
101
+ ],
102
+ "dev": true,
103
+ "license": "MIT",
104
+ "optional": true,
105
+ "os": [
106
+ "android"
107
+ ],
108
+ "engines": {
109
+ "node": "^20.19.0 || >=22.12.0"
110
+ }
111
+ },
112
+ "node_modules/@rolldown/binding-darwin-arm64": {
113
+ "version": "1.0.0-rc.12",
114
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz",
115
+ "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==",
116
+ "cpu": [
117
+ "arm64"
118
+ ],
119
+ "dev": true,
120
+ "license": "MIT",
121
+ "optional": true,
122
+ "os": [
123
+ "darwin"
124
+ ],
125
+ "engines": {
126
+ "node": "^20.19.0 || >=22.12.0"
127
+ }
128
+ },
129
+ "node_modules/@rolldown/binding-darwin-x64": {
130
+ "version": "1.0.0-rc.12",
131
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz",
132
+ "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==",
133
+ "cpu": [
134
+ "x64"
135
+ ],
136
+ "dev": true,
137
+ "license": "MIT",
138
+ "optional": true,
139
+ "os": [
140
+ "darwin"
141
+ ],
142
+ "engines": {
143
+ "node": "^20.19.0 || >=22.12.0"
144
+ }
145
+ },
146
+ "node_modules/@rolldown/binding-freebsd-x64": {
147
+ "version": "1.0.0-rc.12",
148
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz",
149
+ "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==",
150
+ "cpu": [
151
+ "x64"
152
+ ],
153
+ "dev": true,
154
+ "license": "MIT",
155
+ "optional": true,
156
+ "os": [
157
+ "freebsd"
158
+ ],
159
+ "engines": {
160
+ "node": "^20.19.0 || >=22.12.0"
161
+ }
162
+ },
163
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
164
+ "version": "1.0.0-rc.12",
165
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz",
166
+ "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==",
167
+ "cpu": [
168
+ "arm"
169
+ ],
170
+ "dev": true,
171
+ "license": "MIT",
172
+ "optional": true,
173
+ "os": [
174
+ "linux"
175
+ ],
176
+ "engines": {
177
+ "node": "^20.19.0 || >=22.12.0"
178
+ }
179
+ },
180
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
181
+ "version": "1.0.0-rc.12",
182
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz",
183
+ "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==",
184
+ "cpu": [
185
+ "arm64"
186
+ ],
187
+ "dev": true,
188
+ "license": "MIT",
189
+ "optional": true,
190
+ "os": [
191
+ "linux"
192
+ ],
193
+ "engines": {
194
+ "node": "^20.19.0 || >=22.12.0"
195
+ }
196
+ },
197
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
198
+ "version": "1.0.0-rc.12",
199
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz",
200
+ "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==",
201
+ "cpu": [
202
+ "arm64"
203
+ ],
204
+ "dev": true,
205
+ "license": "MIT",
206
+ "optional": true,
207
+ "os": [
208
+ "linux"
209
+ ],
210
+ "engines": {
211
+ "node": "^20.19.0 || >=22.12.0"
212
+ }
213
+ },
214
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
215
+ "version": "1.0.0-rc.12",
216
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz",
217
+ "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==",
218
+ "cpu": [
219
+ "ppc64"
220
+ ],
221
+ "dev": true,
222
+ "license": "MIT",
223
+ "optional": true,
224
+ "os": [
225
+ "linux"
226
+ ],
227
+ "engines": {
228
+ "node": "^20.19.0 || >=22.12.0"
229
+ }
230
+ },
231
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
232
+ "version": "1.0.0-rc.12",
233
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz",
234
+ "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==",
235
+ "cpu": [
236
+ "s390x"
237
+ ],
238
+ "dev": true,
239
+ "license": "MIT",
240
+ "optional": true,
241
+ "os": [
242
+ "linux"
243
+ ],
244
+ "engines": {
245
+ "node": "^20.19.0 || >=22.12.0"
246
+ }
247
+ },
248
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
249
+ "version": "1.0.0-rc.12",
250
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz",
251
+ "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==",
252
+ "cpu": [
253
+ "x64"
254
+ ],
255
+ "dev": true,
256
+ "license": "MIT",
257
+ "optional": true,
258
+ "os": [
259
+ "linux"
260
+ ],
261
+ "engines": {
262
+ "node": "^20.19.0 || >=22.12.0"
263
+ }
264
+ },
265
+ "node_modules/@rolldown/binding-linux-x64-musl": {
266
+ "version": "1.0.0-rc.12",
267
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz",
268
+ "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==",
269
+ "cpu": [
270
+ "x64"
271
+ ],
272
+ "dev": true,
273
+ "license": "MIT",
274
+ "optional": true,
275
+ "os": [
276
+ "linux"
277
+ ],
278
+ "engines": {
279
+ "node": "^20.19.0 || >=22.12.0"
280
+ }
281
+ },
282
+ "node_modules/@rolldown/binding-openharmony-arm64": {
283
+ "version": "1.0.0-rc.12",
284
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz",
285
+ "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==",
286
+ "cpu": [
287
+ "arm64"
288
+ ],
289
+ "dev": true,
290
+ "license": "MIT",
291
+ "optional": true,
292
+ "os": [
293
+ "openharmony"
294
+ ],
295
+ "engines": {
296
+ "node": "^20.19.0 || >=22.12.0"
297
+ }
298
+ },
299
+ "node_modules/@rolldown/binding-wasm32-wasi": {
300
+ "version": "1.0.0-rc.12",
301
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz",
302
+ "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==",
303
+ "cpu": [
304
+ "wasm32"
305
+ ],
306
+ "dev": true,
307
+ "license": "MIT",
308
+ "optional": true,
309
+ "dependencies": {
310
+ "@napi-rs/wasm-runtime": "^1.1.1"
311
+ },
312
+ "engines": {
313
+ "node": ">=14.0.0"
314
+ }
315
+ },
316
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
317
+ "version": "1.0.0-rc.12",
318
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz",
319
+ "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==",
320
+ "cpu": [
321
+ "arm64"
322
+ ],
323
+ "dev": true,
324
+ "license": "MIT",
325
+ "optional": true,
326
+ "os": [
327
+ "win32"
328
+ ],
329
+ "engines": {
330
+ "node": "^20.19.0 || >=22.12.0"
331
+ }
332
+ },
333
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
334
+ "version": "1.0.0-rc.12",
335
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz",
336
+ "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==",
337
+ "cpu": [
338
+ "x64"
339
+ ],
340
+ "dev": true,
341
+ "license": "MIT",
342
+ "optional": true,
343
+ "os": [
344
+ "win32"
345
+ ],
346
+ "engines": {
347
+ "node": "^20.19.0 || >=22.12.0"
348
+ }
349
+ },
350
+ "node_modules/@rolldown/pluginutils": {
351
+ "version": "1.0.0-rc.12",
352
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz",
353
+ "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==",
354
+ "dev": true,
355
+ "license": "MIT"
356
+ },
357
+ "node_modules/@tybys/wasm-util": {
358
+ "version": "0.10.1",
359
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
360
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
361
+ "dev": true,
362
+ "license": "MIT",
363
+ "optional": true,
364
+ "dependencies": {
365
+ "tslib": "^2.4.0"
366
+ }
367
+ },
368
+ "node_modules/@types/react": {
369
+ "version": "19.2.14",
370
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
371
+ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
372
+ "dev": true,
373
+ "license": "MIT",
374
+ "dependencies": {
375
+ "csstype": "^3.2.2"
376
+ }
377
+ },
378
+ "node_modules/commander": {
379
+ "version": "13.1.0",
380
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
381
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
382
+ "dev": true,
383
+ "license": "MIT",
384
+ "engines": {
385
+ "node": ">=18"
386
+ }
387
+ },
388
+ "node_modules/csstype": {
389
+ "version": "3.2.3",
390
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
391
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
392
+ "dev": true,
393
+ "license": "MIT"
394
+ },
395
+ "node_modules/detect-libc": {
396
+ "version": "2.1.2",
397
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
398
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
399
+ "dev": true,
400
+ "license": "Apache-2.0",
401
+ "engines": {
402
+ "node": ">=8"
403
+ }
404
+ },
405
+ "node_modules/fdir": {
406
+ "version": "6.5.0",
407
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
408
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
409
+ "dev": true,
410
+ "license": "MIT",
411
+ "engines": {
412
+ "node": ">=12.0.0"
413
+ },
414
+ "peerDependencies": {
415
+ "picomatch": "^3 || ^4"
416
+ },
417
+ "peerDependenciesMeta": {
418
+ "picomatch": {
419
+ "optional": true
420
+ }
421
+ }
422
+ },
423
+ "node_modules/fsevents": {
424
+ "version": "2.3.3",
425
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
426
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
427
+ "dev": true,
428
+ "hasInstallScript": true,
429
+ "license": "MIT",
430
+ "optional": true,
431
+ "os": [
432
+ "darwin"
433
+ ],
434
+ "engines": {
435
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
436
+ }
437
+ },
438
+ "node_modules/lightningcss": {
439
+ "version": "1.32.0",
440
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
441
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
442
+ "dev": true,
443
+ "license": "MPL-2.0",
444
+ "dependencies": {
445
+ "detect-libc": "^2.0.3"
446
+ },
447
+ "engines": {
448
+ "node": ">= 12.0.0"
449
+ },
450
+ "funding": {
451
+ "type": "opencollective",
452
+ "url": "https://opencollective.com/parcel"
453
+ },
454
+ "optionalDependencies": {
455
+ "lightningcss-android-arm64": "1.32.0",
456
+ "lightningcss-darwin-arm64": "1.32.0",
457
+ "lightningcss-darwin-x64": "1.32.0",
458
+ "lightningcss-freebsd-x64": "1.32.0",
459
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
460
+ "lightningcss-linux-arm64-gnu": "1.32.0",
461
+ "lightningcss-linux-arm64-musl": "1.32.0",
462
+ "lightningcss-linux-x64-gnu": "1.32.0",
463
+ "lightningcss-linux-x64-musl": "1.32.0",
464
+ "lightningcss-win32-arm64-msvc": "1.32.0",
465
+ "lightningcss-win32-x64-msvc": "1.32.0"
466
+ }
467
+ },
468
+ "node_modules/lightningcss-android-arm64": {
469
+ "version": "1.32.0",
470
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
471
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
472
+ "cpu": [
473
+ "arm64"
474
+ ],
475
+ "dev": true,
476
+ "license": "MPL-2.0",
477
+ "optional": true,
478
+ "os": [
479
+ "android"
480
+ ],
481
+ "engines": {
482
+ "node": ">= 12.0.0"
483
+ },
484
+ "funding": {
485
+ "type": "opencollective",
486
+ "url": "https://opencollective.com/parcel"
487
+ }
488
+ },
489
+ "node_modules/lightningcss-darwin-arm64": {
490
+ "version": "1.32.0",
491
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
492
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
493
+ "cpu": [
494
+ "arm64"
495
+ ],
496
+ "dev": true,
497
+ "license": "MPL-2.0",
498
+ "optional": true,
499
+ "os": [
500
+ "darwin"
501
+ ],
502
+ "engines": {
503
+ "node": ">= 12.0.0"
504
+ },
505
+ "funding": {
506
+ "type": "opencollective",
507
+ "url": "https://opencollective.com/parcel"
508
+ }
509
+ },
510
+ "node_modules/lightningcss-darwin-x64": {
511
+ "version": "1.32.0",
512
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
513
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
514
+ "cpu": [
515
+ "x64"
516
+ ],
517
+ "dev": true,
518
+ "license": "MPL-2.0",
519
+ "optional": true,
520
+ "os": [
521
+ "darwin"
522
+ ],
523
+ "engines": {
524
+ "node": ">= 12.0.0"
525
+ },
526
+ "funding": {
527
+ "type": "opencollective",
528
+ "url": "https://opencollective.com/parcel"
529
+ }
530
+ },
531
+ "node_modules/lightningcss-freebsd-x64": {
532
+ "version": "1.32.0",
533
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
534
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
535
+ "cpu": [
536
+ "x64"
537
+ ],
538
+ "dev": true,
539
+ "license": "MPL-2.0",
540
+ "optional": true,
541
+ "os": [
542
+ "freebsd"
543
+ ],
544
+ "engines": {
545
+ "node": ">= 12.0.0"
546
+ },
547
+ "funding": {
548
+ "type": "opencollective",
549
+ "url": "https://opencollective.com/parcel"
550
+ }
551
+ },
552
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
553
+ "version": "1.32.0",
554
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
555
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
556
+ "cpu": [
557
+ "arm"
558
+ ],
559
+ "dev": true,
560
+ "license": "MPL-2.0",
561
+ "optional": true,
562
+ "os": [
563
+ "linux"
564
+ ],
565
+ "engines": {
566
+ "node": ">= 12.0.0"
567
+ },
568
+ "funding": {
569
+ "type": "opencollective",
570
+ "url": "https://opencollective.com/parcel"
571
+ }
572
+ },
573
+ "node_modules/lightningcss-linux-arm64-gnu": {
574
+ "version": "1.32.0",
575
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
576
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
577
+ "cpu": [
578
+ "arm64"
579
+ ],
580
+ "dev": true,
581
+ "license": "MPL-2.0",
582
+ "optional": true,
583
+ "os": [
584
+ "linux"
585
+ ],
586
+ "engines": {
587
+ "node": ">= 12.0.0"
588
+ },
589
+ "funding": {
590
+ "type": "opencollective",
591
+ "url": "https://opencollective.com/parcel"
592
+ }
593
+ },
594
+ "node_modules/lightningcss-linux-arm64-musl": {
595
+ "version": "1.32.0",
596
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
597
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
598
+ "cpu": [
599
+ "arm64"
600
+ ],
601
+ "dev": true,
602
+ "license": "MPL-2.0",
603
+ "optional": true,
604
+ "os": [
605
+ "linux"
606
+ ],
607
+ "engines": {
608
+ "node": ">= 12.0.0"
609
+ },
610
+ "funding": {
611
+ "type": "opencollective",
612
+ "url": "https://opencollective.com/parcel"
613
+ }
614
+ },
615
+ "node_modules/lightningcss-linux-x64-gnu": {
616
+ "version": "1.32.0",
617
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
618
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
619
+ "cpu": [
620
+ "x64"
621
+ ],
622
+ "dev": true,
623
+ "license": "MPL-2.0",
624
+ "optional": true,
625
+ "os": [
626
+ "linux"
627
+ ],
628
+ "engines": {
629
+ "node": ">= 12.0.0"
630
+ },
631
+ "funding": {
632
+ "type": "opencollective",
633
+ "url": "https://opencollective.com/parcel"
634
+ }
635
+ },
636
+ "node_modules/lightningcss-linux-x64-musl": {
637
+ "version": "1.32.0",
638
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
639
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
640
+ "cpu": [
641
+ "x64"
642
+ ],
643
+ "dev": true,
644
+ "license": "MPL-2.0",
645
+ "optional": true,
646
+ "os": [
647
+ "linux"
648
+ ],
649
+ "engines": {
650
+ "node": ">= 12.0.0"
651
+ },
652
+ "funding": {
653
+ "type": "opencollective",
654
+ "url": "https://opencollective.com/parcel"
655
+ }
656
+ },
657
+ "node_modules/lightningcss-win32-arm64-msvc": {
658
+ "version": "1.32.0",
659
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
660
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
661
+ "cpu": [
662
+ "arm64"
663
+ ],
664
+ "dev": true,
665
+ "license": "MPL-2.0",
666
+ "optional": true,
667
+ "os": [
668
+ "win32"
669
+ ],
670
+ "engines": {
671
+ "node": ">= 12.0.0"
672
+ },
673
+ "funding": {
674
+ "type": "opencollective",
675
+ "url": "https://opencollective.com/parcel"
676
+ }
677
+ },
678
+ "node_modules/lightningcss-win32-x64-msvc": {
679
+ "version": "1.32.0",
680
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
681
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
682
+ "cpu": [
683
+ "x64"
684
+ ],
685
+ "dev": true,
686
+ "license": "MPL-2.0",
687
+ "optional": true,
688
+ "os": [
689
+ "win32"
690
+ ],
691
+ "engines": {
692
+ "node": ">= 12.0.0"
693
+ },
694
+ "funding": {
695
+ "type": "opencollective",
696
+ "url": "https://opencollective.com/parcel"
697
+ }
698
+ },
699
+ "node_modules/nanoid": {
700
+ "version": "3.3.11",
701
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
702
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
703
+ "dev": true,
704
+ "funding": [
705
+ {
706
+ "type": "github",
707
+ "url": "https://github.com/sponsors/ai"
708
+ }
709
+ ],
710
+ "license": "MIT",
711
+ "bin": {
712
+ "nanoid": "bin/nanoid.cjs"
713
+ },
714
+ "engines": {
715
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
716
+ }
717
+ },
718
+ "node_modules/picocolors": {
719
+ "version": "1.1.1",
720
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
721
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
722
+ "dev": true,
723
+ "license": "ISC"
724
+ },
725
+ "node_modules/picomatch": {
726
+ "version": "4.0.4",
727
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
728
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
729
+ "dev": true,
730
+ "license": "MIT",
731
+ "engines": {
732
+ "node": ">=12"
733
+ },
734
+ "funding": {
735
+ "url": "https://github.com/sponsors/jonschlinkert"
736
+ }
737
+ },
738
+ "node_modules/postcss": {
739
+ "version": "8.5.8",
740
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
741
+ "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
742
+ "dev": true,
743
+ "funding": [
744
+ {
745
+ "type": "opencollective",
746
+ "url": "https://opencollective.com/postcss/"
747
+ },
748
+ {
749
+ "type": "tidelift",
750
+ "url": "https://tidelift.com/funding/github/npm/postcss"
751
+ },
752
+ {
753
+ "type": "github",
754
+ "url": "https://github.com/sponsors/ai"
755
+ }
756
+ ],
757
+ "license": "MIT",
758
+ "dependencies": {
759
+ "nanoid": "^3.3.11",
760
+ "picocolors": "^1.1.1",
761
+ "source-map-js": "^1.2.1"
762
+ },
763
+ "engines": {
764
+ "node": "^10 || ^12 || >=14"
765
+ }
766
+ },
767
+ "node_modules/react": {
768
+ "version": "19.2.4",
769
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
770
+ "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
771
+ "dev": true,
772
+ "license": "MIT",
773
+ "engines": {
774
+ "node": ">=0.10.0"
775
+ }
776
+ },
777
+ "node_modules/rolldown": {
778
+ "version": "1.0.0-rc.12",
779
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz",
780
+ "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==",
781
+ "dev": true,
782
+ "license": "MIT",
783
+ "dependencies": {
784
+ "@oxc-project/types": "=0.122.0",
785
+ "@rolldown/pluginutils": "1.0.0-rc.12"
786
+ },
787
+ "bin": {
788
+ "rolldown": "bin/cli.mjs"
789
+ },
790
+ "engines": {
791
+ "node": "^20.19.0 || >=22.12.0"
792
+ },
793
+ "optionalDependencies": {
794
+ "@rolldown/binding-android-arm64": "1.0.0-rc.12",
795
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.12",
796
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.12",
797
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.12",
798
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12",
799
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12",
800
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12",
801
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12",
802
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12",
803
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12",
804
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12",
805
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12",
806
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12",
807
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12",
808
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12"
809
+ }
810
+ },
811
+ "node_modules/source-map-js": {
812
+ "version": "1.2.1",
813
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
814
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
815
+ "dev": true,
816
+ "license": "BSD-3-Clause",
817
+ "engines": {
818
+ "node": ">=0.10.0"
819
+ }
820
+ },
821
+ "node_modules/tinyglobby": {
822
+ "version": "0.2.15",
823
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
824
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
825
+ "dev": true,
826
+ "license": "MIT",
827
+ "dependencies": {
828
+ "fdir": "^6.5.0",
829
+ "picomatch": "^4.0.3"
830
+ },
831
+ "engines": {
832
+ "node": ">=12.0.0"
833
+ },
834
+ "funding": {
835
+ "url": "https://github.com/sponsors/SuperchupuDev"
836
+ }
837
+ },
838
+ "node_modules/tslib": {
839
+ "version": "2.8.1",
840
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
841
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
842
+ "dev": true,
843
+ "license": "0BSD",
844
+ "optional": true
845
+ },
846
+ "node_modules/typescript": {
847
+ "version": "5.9.3",
848
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
849
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
850
+ "dev": true,
851
+ "license": "Apache-2.0",
852
+ "bin": {
853
+ "tsc": "bin/tsc",
854
+ "tsserver": "bin/tsserver"
855
+ },
856
+ "engines": {
857
+ "node": ">=14.17"
858
+ }
859
+ },
860
+ "node_modules/vite": {
861
+ "version": "8.0.3",
862
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz",
863
+ "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==",
864
+ "dev": true,
865
+ "license": "MIT",
866
+ "dependencies": {
867
+ "lightningcss": "^1.32.0",
868
+ "picomatch": "^4.0.4",
869
+ "postcss": "^8.5.8",
870
+ "rolldown": "1.0.0-rc.12",
871
+ "tinyglobby": "^0.2.15"
872
+ },
873
+ "bin": {
874
+ "vite": "bin/vite.js"
875
+ },
876
+ "engines": {
877
+ "node": "^20.19.0 || >=22.12.0"
878
+ },
879
+ "funding": {
880
+ "url": "https://github.com/vitejs/vite?sponsor=1"
881
+ },
882
+ "optionalDependencies": {
883
+ "fsevents": "~2.3.3"
884
+ },
885
+ "peerDependencies": {
886
+ "@types/node": "^20.19.0 || >=22.12.0",
887
+ "@vitejs/devtools": "^0.1.0",
888
+ "esbuild": "^0.27.0",
889
+ "jiti": ">=1.21.0",
890
+ "less": "^4.0.0",
891
+ "sass": "^1.70.0",
892
+ "sass-embedded": "^1.70.0",
893
+ "stylus": ">=0.54.8",
894
+ "sugarss": "^5.0.0",
895
+ "terser": "^5.16.0",
896
+ "tsx": "^4.8.1",
897
+ "yaml": "^2.4.2"
898
+ },
899
+ "peerDependenciesMeta": {
900
+ "@types/node": {
901
+ "optional": true
902
+ },
903
+ "@vitejs/devtools": {
904
+ "optional": true
905
+ },
906
+ "esbuild": {
907
+ "optional": true
908
+ },
909
+ "jiti": {
910
+ "optional": true
911
+ },
912
+ "less": {
913
+ "optional": true
914
+ },
915
+ "sass": {
916
+ "optional": true
917
+ },
918
+ "sass-embedded": {
919
+ "optional": true
920
+ },
921
+ "stylus": {
922
+ "optional": true
923
+ },
924
+ "sugarss": {
925
+ "optional": true
926
+ },
927
+ "terser": {
928
+ "optional": true
929
+ },
930
+ "tsx": {
931
+ "optional": true
932
+ },
933
+ "yaml": {
934
+ "optional": true
935
+ }
936
+ }
937
+ }
938
+ }
939
+ }
@@ -1,6 +1,6 @@
1
1
  import { resolve } from "path";
2
2
  import { createServer } from "http";
3
- import { watch, cpSync } from "fs";
3
+ import { watch, cpSync, existsSync } from "fs";
4
4
  import { defineConfig } from "vite";
5
5
 
6
6
  /**
@@ -138,16 +138,18 @@ function metabaseDevServer() {
138
138
 
139
139
  // Watch public/assets/ for changes — copy to dist/assets/ and notify
140
140
  const assetsDir = resolve(__dirname, "public/assets");
141
- watch(assetsDir, { recursive: true }, (_event, filename) => {
142
- if (!filename) {
143
- return;
144
- }
145
- cpSync(resolve(assetsDir, filename), resolve(__dirname, "dist/assets", filename));
146
- for (const client of clients) {
147
- client.write("data: reload\n\n");
148
- }
149
- console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);
150
- });
141
+ if (existsSync(assetsDir)) {
142
+ watch(assetsDir, { recursive: true }, (_event, filename) => {
143
+ if (!filename) {
144
+ return;
145
+ }
146
+ cpSync(resolve(assetsDir, filename), resolve(__dirname, "dist/assets", filename));
147
+ for (const client of clients) {
148
+ client.write("data: reload\n\n");
149
+ }
150
+ console.log(`[custom-viz] Asset changed: ${filename}, notified ${clients.size} client(s)`);
151
+ });
152
+ }
151
153
  },
152
154
 
153
155
  closeBundle() {
@@ -166,6 +168,10 @@ const isWatch = process.argv.includes("--watch");
166
168
  export default defineConfig({
167
169
  plugins: [metabaseVizExternals(), ...(isWatch ? [metabaseDevServer()] : [])],
168
170
  publicDir: "public",
171
+ define: {
172
+ "process.env.NODE_ENV": JSON.stringify("production"),
173
+ "process.env": JSON.stringify({}),
174
+ },
169
175
  build: {
170
176
  outDir: "dist",
171
177
  lib: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metabase/custom-viz",
3
- "version": "0.0.1-alpha.5",
3
+ "version": "0.0.1-alpha.7",
4
4
  "description": "Creating custom visualizations for Metabase",
5
5
  "type": "module",
6
6
  "bin": {