├── .github └── workflows │ ├── ci.yml │ ├── github-pages.yml │ └── release-please.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── .tool-versions ├── CHANGELOG.md ├── LICENSE ├── README.md ├── example ├── .storybook │ ├── main.ts │ └── preview.ts ├── README.md ├── declarations.d.ts ├── package-lock.json ├── package.json ├── src │ ├── Button │ │ ├── Button.tsx │ │ └── stories │ │ │ ├── Button.stories.tsx │ │ │ ├── editableStory.source.js │ │ │ └── editableStory.source.tsx │ ├── index.ts │ ├── intro.mdx │ └── playgroundExample.css ├── tsconfig.build.json ├── tsconfig.json └── vite.config.ts ├── icon.png ├── manager.js ├── package-lock.json ├── package.json ├── scripts ├── createChildProcess.js ├── post-build.js └── rm.js ├── src ├── Editor │ ├── Editor.tsx │ ├── getMonacoOverflowContainer.ts │ ├── monacoLoader.ts │ ├── reactTypesLoader.ts │ └── setupMonaco.ts ├── ErrorBoundary.tsx ├── Preview.tsx ├── constants.ts ├── createStore.ts ├── declarations.d.ts ├── evalModule.ts ├── getStaticDirs.ts ├── index.test.tsx ├── index.tsx └── manager.tsx ├── tsconfig-cjs.json ├── tsconfig.json └── vitest.config.ts /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | 6 | name: CI 7 | 8 | jobs: 9 | ci: 10 | permissions: 11 | contents: read 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: 20 21 | 22 | - run: npm ci 23 | - run: npm run build 24 | - run: npm run test 25 | -------------------------------------------------------------------------------- /.github/workflows/github-pages.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | name: github-pages 7 | 8 | jobs: 9 | deploy: 10 | permissions: 11 | contents: read 12 | id-token: write 13 | pages: write 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: 20 23 | 24 | - run: | 25 | npm ci 26 | rm -rf example/node_modules 27 | rm example/package-lock.json 28 | npm run build-example 29 | 30 | - uses: actions/upload-pages-artifact@v3 31 | with: 32 | path: storybook-site/ 33 | 34 | - uses: actions/deploy-pages@v4 35 | -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | name: release-please 7 | 8 | jobs: 9 | release-please: 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: googleapis/release-please-action@v4 18 | id: release 19 | with: 20 | token: ${{ secrets.GITHUB_TOKEN }} 21 | release-type: node 22 | 23 | - uses: actions/checkout@v4 24 | if: ${{ steps.release.outputs.release_created }} 25 | 26 | - uses: actions/setup-node@v4 27 | with: 28 | node-version: 20 29 | registry-url: 'https://registry.npmjs.org' 30 | if: ${{ steps.release.outputs.release_created }} 31 | 32 | - name: Publish to npm 33 | run: | 34 | npm ci 35 | npm run build 36 | npm run test 37 | npm publish --access public 38 | env: 39 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 40 | if: ${{ steps.release.outputs.release_created }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Files that might appear in the root of a volume 7 | .DocumentRevisions-V100 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | .VolumeIcon.icns 13 | .com.apple.timemachine.donotpresent 14 | 15 | # Directories potentially created on remote AFP share 16 | .AppleDB 17 | .AppleDesktop 18 | Network Trash Folder 19 | Temporary Items 20 | .apdisk 21 | 22 | # Logs 23 | logs 24 | *.log 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | lerna-debug.log* 29 | .pnpm-debug.log* 30 | 31 | # Diagnostic reports (https://nodejs.org/api/report.html) 32 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 33 | 34 | # Runtime data 35 | pids 36 | *.pid 37 | *.seed 38 | *.pid.lock 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | 46 | # Build directories/files 47 | dist/ 48 | storybook-site/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # wireit cache 57 | .wireit 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Stores VSCode versions used for testing VSCode extensions 66 | .vscode-test 67 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.mdx 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | nodejs 22.14.0 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [4.1.2](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v4.1.1...v4.1.2) (2025-05-16) 4 | 5 | 6 | ### Bug Fixes 7 | 8 | * add indexed keys ([238c246](https://github.com/JeremyRH/storybook-addon-code-editor/commit/238c246c34b190f659640b83165b5d3de40fc971)) 9 | * add tags to MinimalStoryObj ([f6eb42b](https://github.com/JeremyRH/storybook-addon-code-editor/commit/f6eb42b71d59322c7a8a8a11291ee51c48eebe82)) 10 | 11 | ## [4.1.1](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v4.1.0...v4.1.1) (2025-04-03) 12 | 13 | 14 | ### Bug Fixes 15 | 16 | * Clean up examples/docs. ([1dccf27](https://github.com/JeremyRH/storybook-addon-code-editor/commit/1dccf277de71b8e00e7b390aad4f382d71e995b7)) 17 | 18 | ## [4.1.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v4.0.1...v4.1.0) (2025-04-02) 19 | 20 | 21 | ### Features 22 | 23 | * Add makeLiveEditStory to replace createLiveEditStory. createLiveEditStory is still available but deprecated. Storybook adds some features during the build by reading the story object. This means addons should not change the way a story is defined. In order to keep the interface simple, makeLiveEditStory does not create the story object. It takes an already defined story object and modifies it. ([613261c](https://github.com/JeremyRH/storybook-addon-code-editor/commit/613261c1d6c5f4369a429c3e77dce6b34a1281b1)) 24 | 25 | 26 | ### Bug Fixes 27 | 28 | * Import type directly. ([cd1d2d2](https://github.com/JeremyRH/storybook-addon-code-editor/commit/cd1d2d254f01ae14888ff7cfca9f5d3e77b169d1)) 29 | * React types needed JSX types. ([7b7c2f7](https://github.com/JeremyRH/storybook-addon-code-editor/commit/7b7c2f7fb96edb22a4e5d3f3bb0bf98e552fb43f)) 30 | 31 | ## [4.0.1](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v4.0.0...v4.0.1) (2025-04-01) 32 | 33 | 34 | ### Bug Fixes 35 | 36 | * passing tags to the story ([57b2d0e](https://github.com/JeremyRH/storybook-addon-code-editor/commit/57b2d0ef4901d3d97e19b4ea57449d06e534bf96)) 37 | 38 | ## [4.0.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.2.0...v4.0.0) (2025-03-30) 39 | 40 | 41 | ### ⚠ BREAKING CHANGES 42 | 43 | * Replace Playground wrapping component with Container. This breaking change allows complete control of the Playground style. 44 | 45 | ### Features 46 | 47 | * Hide code editor panel tab if no story editor id is found (indicating createLiveEditStory was not used). ([3f1799e](https://github.com/JeremyRH/storybook-addon-code-editor/commit/3f1799e6dd479edd545c7ffd4bb603e4d9aedc1b)) 48 | * Replace Playground wrapping component with Container. This breaking change allows complete control of the Playground style. ([a8bcaea](https://github.com/JeremyRH/storybook-addon-code-editor/commit/a8bcaeaf24ff02c2741d378472407bfeb258d4e9)) 49 | * Update all deps to latest. Replace jest with vitest and babel with tsc. ([c055c92](https://github.com/JeremyRH/storybook-addon-code-editor/commit/c055c926848e6dabada0caa0b5a49b41db558e70)) 50 | 51 | 52 | ### Bug Fixes 53 | 54 | * Support React 19. ([c1c2026](https://github.com/JeremyRH/storybook-addon-code-editor/commit/c1c20262baeee7f202e202e1820d797080d05490)) 55 | 56 | ## [3.2.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.1.0...v3.2.0) (2024-12-13) 57 | 58 | 59 | ### Features 60 | 61 | * update dependencies ([5005935](https://github.com/JeremyRH/storybook-addon-code-editor/commit/50059352e1e9b10c3982377c6cb8990fd3bf7d6d)) 62 | 63 | 64 | ### Bug Fixes 65 | 66 | * combine post-build scripts ([8ba7432](https://github.com/JeremyRH/storybook-addon-code-editor/commit/8ba743218a16afba0b27f82743a79aca3e84a2e5)) 67 | * Node 22.12 error with cjs imports ([6c8719c](https://github.com/JeremyRH/storybook-addon-code-editor/commit/6c8719c1ea62d89e9cea78447425c6f3128fcf41)) 68 | * remove top-level getStaticDirs and only rely on package.json exports ([31dc7a4](https://github.com/JeremyRH/storybook-addon-code-editor/commit/31dc7a4e85389fbf88805e001cf70cec095a1e2f)) 69 | 70 | ## [3.1.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.0.3...v3.1.0) (2024-07-01) 71 | 72 | 73 | ### Features 74 | 75 | * add editor options and wrapping component prop ([5d47fd8](https://github.com/JeremyRH/storybook-addon-code-editor/commit/5d47fd8048684b99dde98d38f4c1501bee3a025d)) 76 | 77 | 78 | ### Bug Fixes 79 | 80 | * implement pr feedback ([58dc909](https://github.com/JeremyRH/storybook-addon-code-editor/commit/58dc90928c4f8d3fe97cfdb978e76c1afd8fa3ce)) 81 | 82 | ## [3.0.3](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.0.2...v3.0.3) (2024-06-25) 83 | 84 | 85 | ### Bug Fixes 86 | 87 | * only use window.parent and fall back to window to prevent manager from throwing ([cc48522](https://github.com/JeremyRH/storybook-addon-code-editor/commit/cc485224cf059086be21a9c9ab5d45f95e7b82a3)) 88 | 89 | ## [3.0.2](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.0.1...v3.0.2) (2024-06-24) 90 | 91 | 92 | ### Bug Fixes 93 | 94 | * iframed storybook sites fail due to window.top access ([02f8255](https://github.com/JeremyRH/storybook-addon-code-editor/commit/02f825557e20dc6e77aa13464b8246d4ef7e1c39)) 95 | 96 | ## [3.0.1](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v3.0.0...v3.0.1) (2024-06-12) 97 | 98 | 99 | ### Bug Fixes 100 | 101 | * use os path separator for windows support ([bb2d73a](https://github.com/JeremyRH/storybook-addon-code-editor/commit/bb2d73a1c7849582d0d82e31bb6acd73d30f17c7)) 102 | 103 | ## [3.0.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v2.2.2...v3.0.0) (2024-05-17) 104 | 105 | 106 | ### ⚠ BREAKING CHANGES 107 | 108 | * Update to storybook 8 109 | * Drop support for StoryBook version 6 & 7. 110 | * Drop support for React 16. Use react/jsx-runtime for jsx. 111 | * `createLiveEditStory` changed to accept all story fields. 112 | ```js 113 | // Before: 114 | export const StoryA = createLiveEditStory({ code: StoryASource }); 115 | // Had to mutate the Story 116 | StoryA.args = { foo: 'foo' }; 117 | ``` 118 | ```js 119 | // After: 120 | export const StoryA = createLiveEditStory({ 121 | code: StoryASource, 122 | args: { foo: 'foo' }, 123 | }); 124 | ``` 125 | 126 | * Remove automatic configuration for webpack. 127 | * [MDX updated](https://github.com/storybookjs/storybook/blob/ba69532715f162567cc17aa3a0de8ca918dfdd2c/MIGRATION.md#mdx-related-changes), some breaking changes. 128 | * Update TypeScript which may cause breaking changes in types. 129 | * Add package.json "exports" and "type: module". 130 | 131 | ### Features 132 | 133 | * update to storybook 8 ([6946257](https://github.com/JeremyRH/storybook-addon-code-editor/commit/6946257e989ea361e28f1d0810a95c6c9ffc4074)) 134 | 135 | 136 | ### Bug Fixes 137 | 138 | * build ([2d43afa](https://github.com/JeremyRH/storybook-addon-code-editor/commit/2d43afaf28ad1cad075d2c624b9c4e32d5cfedf7)) 139 | * build ([b60d6fb](https://github.com/JeremyRH/storybook-addon-code-editor/commit/b60d6fb18d942fe68642457cf4f62c45fa59d54f)) 140 | * github pages deploy ([1584042](https://github.com/JeremyRH/storybook-addon-code-editor/commit/15840421a2b1500cf601fbdcc28e2f3c42503cb3)) 141 | 142 | ## [2.2.2](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v2.2.1...v2.2.2) (2024-05-15) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * release-please output ([397d89b](https://github.com/JeremyRH/storybook-addon-code-editor/commit/397d89b760807aef5ee40e09860656e253115c48)) 148 | * test creating release pr ([4127514](https://github.com/JeremyRH/storybook-addon-code-editor/commit/4127514b4bf23c6e4758228a769db2a81500a060)) 149 | 150 | ## [2.2.1](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v2.2.0...v2.2.1) (2024-02-13) 151 | 152 | 153 | ### Bug Fixes 154 | 155 | * make getStaticDirs work with yarn zero installs ([0daab18](https://github.com/JeremyRH/storybook-addon-code-editor/commit/0daab180298a7760e0a74a512985f72a5f1f327d)) 156 | 157 | ## [2.2.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v2.1.0...v2.2.0) (2023-06-14) 158 | 159 | 160 | ### Features 161 | 162 | * update dependencies ([4df6835](https://github.com/JeremyRH/storybook-addon-code-editor/commit/4df6835dc5af30e229f6a06b11d8325ddc1303af)) 163 | 164 | 165 | ### Bug Fixes 166 | 167 | * detect react import default and named ([bed3329](https://github.com/JeremyRH/storybook-addon-code-editor/commit/bed3329c05064dc7839f398749d3fd0f629598a1)) 168 | * resolve package location without require.resolve ([b097d3f](https://github.com/JeremyRH/storybook-addon-code-editor/commit/b097d3f4079719a4c49eaea903657c399ac8886f)) 169 | 170 | ## [2.1.0](https://github.com/JeremyRH/storybook-addon-code-editor/compare/v2.0.2...v2.1.0) (2023-04-04) 171 | 172 | 173 | ### Features 174 | 175 | * **Playground:** add id to persist code changes until page reload ([4a8ae8f](https://github.com/JeremyRH/storybook-addon-code-editor/commit/4a8ae8f3a0877ed6c6d9c61fc2046326cea8a595)) 176 | 177 | ## 2.0.2 (2023-04-01) 178 | 179 | 180 | ### Bug Fixes 181 | 182 | * update rock-paper-scissors example ([a8add75](https://github.com/JeremyRH/storybook-addon-code-editor/commit/a8add7531d77728f8da99647c877f3311c625370)) 183 | 184 | ## 2.0.0 185 | 186 | ### ⚠ BREAKING CHANGES 187 | 188 | * require `staticDirs` in .storybook/main 189 | * drop support for webpack 4 and add support for vite 190 | * remove `setupEditor` option and add `setupMonaco` function 191 | * rename `onCreateEditor` option to `modifyEditor` 192 | 193 | ### Features 194 | 195 | * support vite 196 | * make react types optional 197 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jeremy Holcomb 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 | # storybook-addon-code-editor 2 | 3 | A Storybook add-on for live editing stories. Supports React and TypeScript. 4 | 5 | [See it in action.](https://jeremyrh.github.io/storybook-addon-code-editor) 6 | 7 | [See an example project using this add-on.](./example) 8 | 9 | ## What is it? 10 | 11 | This is a [Storybook addon](https://storybook.js.org/addons) that enables live editing of React components with real-time previews. 12 | Think of it like a lightweight [CodeSandbox](https://codesandbox.io), directly in stories or MDX pages. 13 | 14 | It uses [Monaco Editor](https://github.com/microsoft/monaco-editor) (VS Code for the browser) for an excellent TypeScript editing experience. 15 | 16 | ## Get started 17 | 18 | 1. Install as a dev dependency: 19 | 20 | ```sh 21 | npm install --save-dev storybook-addon-code-editor 22 | # Or yarn: 23 | yarn add --dev storybook-addon-code-editor 24 | ``` 25 | 26 | 2. Add `storybook-addon-code-editor` in your `.storybook/main.ts` file and ensure the `staticDirs`, `addons`, and `framework` fields contain the following: 27 | 28 | ```ts 29 | // .storybook/main.ts 30 | import type { StorybookConfig } from '@storybook/react-vite'; 31 | import { getCodeEditorStaticDirs } from 'storybook-addon-code-editor/getStaticDirs'; 32 | 33 | const config: StorybookConfig = { 34 | staticDirs: [...getCodeEditorStaticDirs(__filename)], 35 | addons: ['storybook-addon-code-editor'], 36 | framework: { 37 | name: '@storybook/react-vite', 38 | options: {}, 39 | }, 40 | }; 41 | 42 | export default config; 43 | ``` 44 | 45 |
46 | About `staticDirs` 47 | 48 | `staticDirs` sets a list of directories of static files to be loaded by Storybook. 49 | The editor ([monaco-editor](https://github.com/microsoft/monaco-editor)) requires these extra static files to be available at runtime. 50 | 51 | Additional static files can be added using the `getExtraStaticDir` helper from `storybook-addon-code-editor/getStaticDirs`: 52 | 53 | ```ts 54 | // .storybook/main.ts 55 | import { 56 | getCodeEditorStaticDirs, 57 | getExtraStaticDir, 58 | } from 'storybook-addon-code-editor/getStaticDirs'; 59 | 60 | const config: StorybookConfig = { 61 | staticDirs: [ 62 | ...getCodeEditorStaticDirs(__filename), 63 | // files will be available at: /monaco-editor/esm/* 64 | getExtraStaticDir('monaco-editor/esm'), 65 | ``` 66 | 67 |
68 | 69 |
70 | 71 | **Important:** 72 | 73 | `@storybook/react-vite` is the only supported framework at this time. 74 | 75 |
76 | 77 | ## API 78 | 79 | ### `Playground` 80 | 81 | Use the `Playground` component in [MDX format](https://storybook.js.org/docs/writing-docs/mdx). 82 | 83 | ```mdx 84 | // MyComponent.stories.mdx 85 | import { Playground } from 'storybook-addon-code-editor' 86 | 87 | 88 | ``` 89 | 90 |
91 | More advanced example 92 | 93 | ```mdx 94 | // MyComponent.stories.mdx 95 | import { Playground } from 'storybook-addon-code-editor'; 96 | import \* as MyLibrary from './index'; 97 | import storyCode from './MyStory.source.tsx?raw'; 98 | 99 | // TypeScript might complain about not finding this import or 100 | // importing things from .d.ts files wihtout `import type`. 101 | // Ignore this, we need the string contents of this file. 102 | // @ts-ignore 103 | import MyLibraryTypes from '../dist/types.d.ts?raw'; 104 | 105 | { 111 | // editor docs: https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneCodeEditor.html 112 | // monaco docs: https://microsoft.github.io/monaco-editor/api/modules/monaco.html 113 | editor.getModel().updateOptions({ tabSize: 2 }); 114 | monaco.editor.setTheme('vs-dark'); 115 | monaco.languages.typescript.typescriptDefaults.addExtraLib( 116 | MyLibraryTypes, 117 | 'file:///node_modules/my-library/index.d.ts', 118 | ); 119 | }} 120 | /> 121 | ``` 122 | 123 |
124 | 125 |
126 | 127 | `Playground` props: 128 | 129 | ```ts 130 | interface PlaygroundProps { 131 | availableImports?: { 132 | [importSpecifier: string]: { 133 | [namedImport: string]: any; 134 | }; 135 | }; 136 | code?: string; 137 | defaultEditorOptions?: Monaco.editor.IEditorOptions; 138 | height?: string; 139 | id?: string | number | symbol; 140 | modifyEditor?: (monaco: Monaco, editor: Monaco.editor.IStandaloneCodeEditor) => any; 141 | } 142 | ``` 143 | 144 | `React` is automatically imported if `code` does not import it. 145 | React TypeScript definitions will be automatically loaded if `@types/react` is available. 146 | 147 | ### `makeLiveEditStory` 148 | 149 | Use the `makeLiveEditStory` function in traditional stories to show a code editor panel: 150 | 151 | ```ts 152 | // MyComponent.stories.ts 153 | import type { Meta, StoryObj } from '@storybook/react'; 154 | import { makeLiveEditStory } from 'storybook-addon-code-editor'; 155 | import * as MyLibrary from './index'; 156 | import storyCode from './MyStory.source.tsx?raw'; 157 | 158 | const meta = { 159 | // Story defaults 160 | } satisfies Meta; 161 | 162 | export default meta; 163 | 164 | type Story = StoryObj; 165 | 166 | export const MyStory: Story = { 167 | // Story config 168 | }; 169 | 170 | makeLiveEditStory(MyStory, { 171 | availableImports: { 'my-library': MyLibrary }, 172 | code: storyCode, 173 | }); 174 | ``` 175 | 176 | `makeLiveEditStory` options: 177 | 178 | ```ts 179 | interface LiveEditStoryOptions { 180 | availableImports?: { 181 | [importSpecifier: string]: { 182 | [namedImport: string]: any; 183 | }; 184 | }; 185 | code: string; 186 | modifyEditor?: (monaco: Monaco, editor: Monaco.editor.IStandaloneCodeEditor) => any; 187 | defaultEditorOptions?: Monaco.editor.IEditorOptions; 188 | } 189 | ``` 190 | 191 | ### `setupMonaco` 192 | 193 | `setupMonaco` allows customization of [`monaco-editor`](https://github.com/microsoft/monaco-editor). 194 | 195 | Use this in your `.storybook/preview.ts` to add type definitions or integrations. 196 | 197 | Check out [examples of `monaco-editor`](https://github.com/microsoft/monaco-editor/tree/ae158a25246af016a0c56e2b47df83bd4b1c2426/samples) with different configurations. 198 | 199 | ```ts 200 | // .storybook/preview.ts 201 | import { setupMonaco } from 'storybook-addon-code-editor'; 202 | 203 | setupMonaco({ 204 | // https://microsoft.github.io/monaco-editor/typedoc/interfaces/Environment.html 205 | monacoEnvironment: { 206 | getWorker(moduleId, label) { 207 | ... 208 | }, 209 | }, 210 | // onMonacoLoad is called when monaco is first loaded, before an editor instance is created. 211 | onMonacoLoad(monaco) { 212 | ... 213 | }, 214 | }); 215 | ``` 216 | 217 | `setupMonaco` options: 218 | 219 | ```ts 220 | interface MonacoSetup { 221 | monacoEnvironment?: Monaco.Environment; 222 | onMonacoLoad?: (monaco: Monaco) => any; 223 | } 224 | ``` 225 | 226 |
227 | 228 | ## Contributing 229 | 230 | ### Install dependencies 231 | 232 | ```sh 233 | npm install 234 | ``` 235 | 236 | ### Run example 237 | 238 | ```sh 239 | npm run start-example 240 | ``` 241 | 242 | When making changes to the library, the server needs to be manually restarted. 243 | 244 | ### Run tests 245 | 246 | ```sh 247 | npm run test 248 | ``` 249 | 250 | ### Format code 251 | 252 | ```sh 253 | npm run format 254 | ``` 255 | 256 | ### Build library 257 | 258 | ```sh 259 | npm run build 260 | ``` 261 | 262 | ### Commits 263 | 264 | Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) to allow automatic versioned releases. 265 | 266 | - `fix:` represents bug fixes, and correlates to a SemVer patch. 267 | - `feat:` represents a new feature, and correlates to a SemVer minor. 268 | - `feat!:`, or `fix!:`, `refactor!:`, etc., represent a breaking change (indicated by the !) and will result in a SemVer major. 269 | 270 | ### Publishing 271 | 272 | The automated [release-please](https://github.com/googleapis/release-please) PR to the main branch can be merged to deploy a release. 273 | -------------------------------------------------------------------------------- /example/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/react-vite'; 2 | import { 3 | getCodeEditorStaticDirs, 4 | getExtraStaticDir, 5 | } from 'storybook-addon-code-editor/getStaticDirs'; 6 | 7 | const config: StorybookConfig = { 8 | stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], 9 | staticDirs: [ 10 | // monaco-editor needs static files to be available at runtime. 11 | ...getCodeEditorStaticDirs(__filename), 12 | 13 | // Extra static files can be added like below. 14 | // getExtraStaticDir('monaco-editor/esm'), 15 | ], 16 | addons: [ 17 | { 18 | name: '@storybook/addon-essentials', 19 | options: { 20 | actions: false, 21 | }, 22 | }, 23 | 'storybook-addon-code-editor', 24 | ], 25 | framework: { 26 | name: '@storybook/react-vite', 27 | options: {}, 28 | }, 29 | }; 30 | 31 | export default config; 32 | -------------------------------------------------------------------------------- /example/.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import type { Preview } from '@storybook/react'; 2 | import { setupMonaco } from 'storybook-addon-code-editor'; 3 | // @ts-ignore 4 | import ExampleLibraryTypes from '../dist/types.d.ts?raw'; 5 | 6 | // When customizing monaco-editor, setupMonaco needs to be called before any story loads. 7 | // .storybook/preview.ts is probably the best place for this. 8 | 9 | setupMonaco({ 10 | // This is an example of how to configure monaco-editor workers manually. 11 | // These worker files are not available by default. To add them: 12 | 13 | /* in .storybook/main.ts 14 | 15 | import { 16 | getCodeEditorStaticDirs, 17 | getExtraStaticDir, 18 | } from 'storybook-addon-code-editor/getStaticDirs'; 19 | 20 | const config: StorybookConfig = { 21 | staticDirs: [ 22 | ...getCodeEditorStaticDirs(), 23 | getExtraStaticDir('monaco-editor/esm'), 24 | ], 25 | ... 26 | */ 27 | 28 | // The reason monaco-editor/esm directory is not a static directory by default is because it's 29 | // massive and will bloat storybook sites. 30 | 31 | // monacoEnvironment: { 32 | // getWorker(moduleId, label) { 33 | // if (label === 'json') { 34 | // return new Worker('monaco-editor/esm/vs/language/json/json.worker.js', { type: 'module' }); 35 | // } 36 | // if (label === 'css' || label === 'scss' || label === 'less') { 37 | // return new Worker('monaco-editor/esm/vs/language/css/css.worker.js', { type: 'module' }); 38 | // } 39 | // if (label === 'html' || label === 'handlebars' || label === 'razor') { 40 | // return new Worker('monaco-editor/esm/vs/language/html/html.worker.js', { type: 'module' }); 41 | // } 42 | // if (label === 'typescript' || label === 'javascript') { 43 | // return new Worker('monaco-editor/esm/vs/language/typescript/ts.worker.js', { 44 | // type: 'module', 45 | // }); 46 | // } 47 | // return new Worker('monaco-editor/esm/vs/editor/editor.worker.js', { type: 'module' }); 48 | // }, 49 | // }, 50 | 51 | onMonacoLoad(monaco) { 52 | // Add type definitions for this example library. 53 | monaco.languages.typescript.typescriptDefaults.addExtraLib( 54 | ExampleLibraryTypes, 55 | 'file:///node_modules/example-library/index.d.ts' 56 | ); 57 | }, 58 | }); 59 | 60 | const preview: Preview = { 61 | parameters: { 62 | controls: { 63 | matchers: { 64 | color: /(background|color)$/i, 65 | date: /Date$/i, 66 | }, 67 | }, 68 | }, 69 | }; 70 | 71 | export default preview; 72 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example-library 2 | 3 | This is an example of a React library using `storybook-addon-code-editor`. 4 | 5 | [Storybook site](https://jeremyrh.github.io/storybook-addon-code-editor) 6 | 7 | Check out the story files: 8 | 9 | - [src/intro.stories.mdx](https://raw.githubusercontent.com/JeremyRH/storybook-addon-code-editor/main/example/src/intro.stories.mdx) 10 | - [src/Button/stories/Button.stories.tsx](./src/Button/stories/Button.stories.tsx) 11 | 12 | You can write standalone source files (contents for the editor) if you don't want to use an inline string. 13 | These are imported using [Vite's `?raw` loader](https://vite.dev/guide/assets#importing-asset-as-string). 14 | 15 | - [src/playgroundExample.source.tsx](./src/playgroundExample.source.tsx) 16 | -------------------------------------------------------------------------------- /example/declarations.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*?raw'; 2 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "example-library", 4 | "version": "0.0.0", 5 | "scripts": { 6 | "storybook:build": "tsc -p tsconfig.build.json && storybook build -o ../storybook-site", 7 | "storybook:dev": "tsc -p tsconfig.build.json && storybook dev -p 6006" 8 | }, 9 | "peerDependencies": { 10 | "react": "17.x.x || 18.x.x || 19.x.x" 11 | }, 12 | "devDependencies": { 13 | "@storybook/addon-essentials": "^8.6.11", 14 | "@storybook/blocks": "^8.6.11", 15 | "@storybook/react": "^8.6.11", 16 | "@storybook/react-vite": "^8.6.11", 17 | "@types/react": "^19.0.12", 18 | "@types/react-dom": "^19.0.4", 19 | "@vitejs/plugin-react": "^4.3.4", 20 | "react": "^19.1.0", 21 | "react-dom": "^19.1.0", 22 | "storybook": "^8.6.11", 23 | "storybook-addon-code-editor": "file:../storybook-addon-code-editor-0.0.0.tgz", 24 | "typescript": "^5.8.2", 25 | "vite": "^6.2.5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /example/src/Button/Button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | type ButtonProps = React.ComponentProps<'button'> & { 4 | as?: 'primary' | 'secondary' | 'link'; 5 | }; 6 | 7 | const Button = React.forwardRef( 8 | ({ as = 'primary', ...props }: ButtonProps, ref: React.ForwardedRef) => { 9 | const defaultStyle = { 10 | padding: '10px 20px', 11 | borderRadius: '5px', 12 | border: 'none', 13 | cursor: 'pointer', 14 | fontSize: '16px', 15 | }; 16 | 17 | const styles = { 18 | primary: { 19 | ...defaultStyle, 20 | backgroundColor: '#007bff', 21 | color: '#fff', 22 | }, 23 | secondary: { 24 | ...defaultStyle, 25 | backgroundColor: '#6c757d', 26 | color: '#fff', 27 | }, 28 | link: { 29 | ...defaultStyle, 30 | backgroundColor: 'transparent', 31 | color: '#007bff', 32 | textDecoration: 'underline', 33 | }, 34 | }; 35 | 36 | return ; 5 | }; 6 | -------------------------------------------------------------------------------- /example/src/Button/stories/editableStory.source.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from 'example-library'; 2 | 3 | const props: React.ComponentProps = { 4 | as: 'secondary', 5 | children: 'Secondary', 6 | }; 7 | 8 | export default () => 49 | 50 | ); 51 | }`; 52 | 53 | const Container = (props) => ( 54 |
55 |
56 | {props.preview} 57 |
58 |
59 | {props.editor} 60 |
61 |
62 | ); 63 | 64 | return ( 65 | { 77 | monaco.editor.setTheme('vs-dark'); 78 | }} 79 | /> 80 | ); 81 | })()} 82 | 83 | [See the MDX file used to create this page.](https://raw.githubusercontent.com/JeremyRH/storybook-addon-code-editor/refs/heads/main/example/src/intro.mdx) 84 | -------------------------------------------------------------------------------- /example/src/playgroundExample.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: 3 | 'Nunito Sans', 4 | -apple-system, 5 | sans-serif; 6 | } 7 | 8 | .button { 9 | background-color: #1976d2; 10 | border-radius: 4px; 11 | border: none; 12 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6); 13 | color: #ecf0f1; 14 | font-size: 14pt; 15 | outline: none; 16 | overflow: hidden; 17 | padding: 10px 20px; 18 | position: relative; 19 | transition: background-color 0.3s; 20 | } 21 | 22 | .button:hover, 23 | .button:focus { 24 | background-color: #12589f; 25 | } 26 | 27 | .button:before { 28 | background-color: rgba(236, 240, 241, 0.3); 29 | border-radius: 100%; 30 | content: ''; 31 | display: block; 32 | left: 50%; 33 | padding-top: 0; 34 | position: absolute; 35 | top: 50%; 36 | transform: translate(-50%, -50%); 37 | width: 0; 38 | } 39 | 40 | .button:active:before { 41 | padding-top: 120%; 42 | transition: 43 | width 0.2s ease-out, 44 | padding-top 0.2s ease-out; 45 | width: 120%; 46 | } 47 | 48 | .block-container { 49 | display: flex; 50 | gap: 15px; 51 | margin-bottom: 25px; 52 | } 53 | 54 | .block { 55 | border-radius: 10px; 56 | height: 100px; 57 | width: 200px; 58 | } 59 | -------------------------------------------------------------------------------- /example/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "emitDeclarationOnly": true, 5 | "isolatedModules": false, 6 | // "module": "AMD" produces a single .d.ts file for the whole library. 7 | "module": "AMD", 8 | "moduleResolution": "Node10", 9 | "outFile": "dist/types" 10 | }, 11 | "include": ["src"], 12 | "exclude": [ 13 | "src/**/stories", 14 | "src/**/*.stories.*", 15 | "src/**/*.source.*", 16 | "src/**/tests", 17 | "src/**/*.test.*" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "isolatedModules": true, 8 | "jsx": "react-jsx", 9 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 10 | "module": "Preserve", 11 | "moduleResolution": "Node10", 12 | "noEmitOnError": true, 13 | "paths": { 14 | "example-library": ["src/index"] 15 | }, 16 | "resolveJsonModule": true, 17 | "skipLibCheck": true, 18 | "strict": true, 19 | "target": "ES2023" 20 | }, 21 | "include": ["src", "declarations.d.ts", ".storybook"], 22 | } 23 | -------------------------------------------------------------------------------- /example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeremyRH/storybook-addon-code-editor/5dcb720e7ebb39bf21f5f74b885f85ac867a990f/icon.png -------------------------------------------------------------------------------- /manager.js: -------------------------------------------------------------------------------- 1 | import './dist/es/manager'; 2 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storybook-addon-code-editor", 3 | "version": "4.1.2", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "storybook-addon-code-editor", 9 | "version": "4.1.2", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@babel/standalone": "^7.27.0", 13 | "@storybook/components": "^8.6.11", 14 | "@storybook/manager-api": "^8.6.11", 15 | "@storybook/types": "^8.6.11", 16 | "monaco-editor": "0.52.2" 17 | }, 18 | "devDependencies": { 19 | "@testing-library/dom": "^10.4.0", 20 | "@testing-library/react": "^16.2.0", 21 | "@types/node": "^22.13.14", 22 | "@types/react": "^18.3.16", 23 | "@types/react-dom": "^18.3.5", 24 | "happy-dom": "^17.4.4", 25 | "prettier": "^3.5.3", 26 | "react": "^18.3.1", 27 | "react-dom": "^18.3.1", 28 | "typescript": "^5.8.2", 29 | "vite": "^6.2.5", 30 | "vitest": "^3.1.1" 31 | }, 32 | "peerDependencies": { 33 | "@types/react": "17.x.x || 18.x.x || 19.x.x", 34 | "react": "17.x.x || 18.x.x || 19.x.x" 35 | }, 36 | "peerDependenciesMeta": { 37 | "@types/react": { 38 | "optional": true 39 | } 40 | } 41 | }, 42 | "node_modules/@babel/code-frame": { 43 | "version": "7.26.2", 44 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", 45 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", 46 | "dev": true, 47 | "license": "MIT", 48 | "dependencies": { 49 | "@babel/helper-validator-identifier": "^7.25.9", 50 | "js-tokens": "^4.0.0", 51 | "picocolors": "^1.0.0" 52 | }, 53 | "engines": { 54 | "node": ">=6.9.0" 55 | } 56 | }, 57 | "node_modules/@babel/helper-validator-identifier": { 58 | "version": "7.25.9", 59 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 60 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 61 | "dev": true, 62 | "license": "MIT", 63 | "engines": { 64 | "node": ">=6.9.0" 65 | } 66 | }, 67 | "node_modules/@babel/runtime": { 68 | "version": "7.27.0", 69 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", 70 | "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", 71 | "dev": true, 72 | "license": "MIT", 73 | "dependencies": { 74 | "regenerator-runtime": "^0.14.0" 75 | }, 76 | "engines": { 77 | "node": ">=6.9.0" 78 | } 79 | }, 80 | "node_modules/@babel/standalone": { 81 | "version": "7.27.0", 82 | "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.27.0.tgz", 83 | "integrity": "sha512-UxFDpi+BuSz6Q1X73P3ZSM1CB7Nbbqys+7COi/tdouRuaqRsJ6GAzUyxTswbqItHSItVY3frQdd+paBHHGEk9g==", 84 | "license": "MIT", 85 | "engines": { 86 | "node": ">=6.9.0" 87 | } 88 | }, 89 | "node_modules/@esbuild/aix-ppc64": { 90 | "version": "0.25.2", 91 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", 92 | "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", 93 | "cpu": [ 94 | "ppc64" 95 | ], 96 | "license": "MIT", 97 | "optional": true, 98 | "os": [ 99 | "aix" 100 | ], 101 | "engines": { 102 | "node": ">=18" 103 | } 104 | }, 105 | "node_modules/@esbuild/android-arm": { 106 | "version": "0.25.2", 107 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", 108 | "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", 109 | "cpu": [ 110 | "arm" 111 | ], 112 | "license": "MIT", 113 | "optional": true, 114 | "os": [ 115 | "android" 116 | ], 117 | "engines": { 118 | "node": ">=18" 119 | } 120 | }, 121 | "node_modules/@esbuild/android-arm64": { 122 | "version": "0.25.2", 123 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", 124 | "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", 125 | "cpu": [ 126 | "arm64" 127 | ], 128 | "license": "MIT", 129 | "optional": true, 130 | "os": [ 131 | "android" 132 | ], 133 | "engines": { 134 | "node": ">=18" 135 | } 136 | }, 137 | "node_modules/@esbuild/android-x64": { 138 | "version": "0.25.2", 139 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", 140 | "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", 141 | "cpu": [ 142 | "x64" 143 | ], 144 | "license": "MIT", 145 | "optional": true, 146 | "os": [ 147 | "android" 148 | ], 149 | "engines": { 150 | "node": ">=18" 151 | } 152 | }, 153 | "node_modules/@esbuild/darwin-arm64": { 154 | "version": "0.25.2", 155 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", 156 | "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", 157 | "cpu": [ 158 | "arm64" 159 | ], 160 | "license": "MIT", 161 | "optional": true, 162 | "os": [ 163 | "darwin" 164 | ], 165 | "engines": { 166 | "node": ">=18" 167 | } 168 | }, 169 | "node_modules/@esbuild/darwin-x64": { 170 | "version": "0.25.2", 171 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", 172 | "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", 173 | "cpu": [ 174 | "x64" 175 | ], 176 | "license": "MIT", 177 | "optional": true, 178 | "os": [ 179 | "darwin" 180 | ], 181 | "engines": { 182 | "node": ">=18" 183 | } 184 | }, 185 | "node_modules/@esbuild/freebsd-arm64": { 186 | "version": "0.25.2", 187 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", 188 | "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", 189 | "cpu": [ 190 | "arm64" 191 | ], 192 | "license": "MIT", 193 | "optional": true, 194 | "os": [ 195 | "freebsd" 196 | ], 197 | "engines": { 198 | "node": ">=18" 199 | } 200 | }, 201 | "node_modules/@esbuild/freebsd-x64": { 202 | "version": "0.25.2", 203 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", 204 | "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", 205 | "cpu": [ 206 | "x64" 207 | ], 208 | "license": "MIT", 209 | "optional": true, 210 | "os": [ 211 | "freebsd" 212 | ], 213 | "engines": { 214 | "node": ">=18" 215 | } 216 | }, 217 | "node_modules/@esbuild/linux-arm": { 218 | "version": "0.25.2", 219 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", 220 | "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", 221 | "cpu": [ 222 | "arm" 223 | ], 224 | "license": "MIT", 225 | "optional": true, 226 | "os": [ 227 | "linux" 228 | ], 229 | "engines": { 230 | "node": ">=18" 231 | } 232 | }, 233 | "node_modules/@esbuild/linux-arm64": { 234 | "version": "0.25.2", 235 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", 236 | "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", 237 | "cpu": [ 238 | "arm64" 239 | ], 240 | "license": "MIT", 241 | "optional": true, 242 | "os": [ 243 | "linux" 244 | ], 245 | "engines": { 246 | "node": ">=18" 247 | } 248 | }, 249 | "node_modules/@esbuild/linux-ia32": { 250 | "version": "0.25.2", 251 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", 252 | "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", 253 | "cpu": [ 254 | "ia32" 255 | ], 256 | "license": "MIT", 257 | "optional": true, 258 | "os": [ 259 | "linux" 260 | ], 261 | "engines": { 262 | "node": ">=18" 263 | } 264 | }, 265 | "node_modules/@esbuild/linux-loong64": { 266 | "version": "0.25.2", 267 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", 268 | "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", 269 | "cpu": [ 270 | "loong64" 271 | ], 272 | "license": "MIT", 273 | "optional": true, 274 | "os": [ 275 | "linux" 276 | ], 277 | "engines": { 278 | "node": ">=18" 279 | } 280 | }, 281 | "node_modules/@esbuild/linux-mips64el": { 282 | "version": "0.25.2", 283 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", 284 | "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", 285 | "cpu": [ 286 | "mips64el" 287 | ], 288 | "license": "MIT", 289 | "optional": true, 290 | "os": [ 291 | "linux" 292 | ], 293 | "engines": { 294 | "node": ">=18" 295 | } 296 | }, 297 | "node_modules/@esbuild/linux-ppc64": { 298 | "version": "0.25.2", 299 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", 300 | "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", 301 | "cpu": [ 302 | "ppc64" 303 | ], 304 | "license": "MIT", 305 | "optional": true, 306 | "os": [ 307 | "linux" 308 | ], 309 | "engines": { 310 | "node": ">=18" 311 | } 312 | }, 313 | "node_modules/@esbuild/linux-riscv64": { 314 | "version": "0.25.2", 315 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", 316 | "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", 317 | "cpu": [ 318 | "riscv64" 319 | ], 320 | "license": "MIT", 321 | "optional": true, 322 | "os": [ 323 | "linux" 324 | ], 325 | "engines": { 326 | "node": ">=18" 327 | } 328 | }, 329 | "node_modules/@esbuild/linux-s390x": { 330 | "version": "0.25.2", 331 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", 332 | "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", 333 | "cpu": [ 334 | "s390x" 335 | ], 336 | "license": "MIT", 337 | "optional": true, 338 | "os": [ 339 | "linux" 340 | ], 341 | "engines": { 342 | "node": ">=18" 343 | } 344 | }, 345 | "node_modules/@esbuild/linux-x64": { 346 | "version": "0.25.2", 347 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", 348 | "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", 349 | "cpu": [ 350 | "x64" 351 | ], 352 | "license": "MIT", 353 | "optional": true, 354 | "os": [ 355 | "linux" 356 | ], 357 | "engines": { 358 | "node": ">=18" 359 | } 360 | }, 361 | "node_modules/@esbuild/netbsd-arm64": { 362 | "version": "0.25.2", 363 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", 364 | "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", 365 | "cpu": [ 366 | "arm64" 367 | ], 368 | "license": "MIT", 369 | "optional": true, 370 | "os": [ 371 | "netbsd" 372 | ], 373 | "engines": { 374 | "node": ">=18" 375 | } 376 | }, 377 | "node_modules/@esbuild/netbsd-x64": { 378 | "version": "0.25.2", 379 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", 380 | "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", 381 | "cpu": [ 382 | "x64" 383 | ], 384 | "license": "MIT", 385 | "optional": true, 386 | "os": [ 387 | "netbsd" 388 | ], 389 | "engines": { 390 | "node": ">=18" 391 | } 392 | }, 393 | "node_modules/@esbuild/openbsd-arm64": { 394 | "version": "0.25.2", 395 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", 396 | "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", 397 | "cpu": [ 398 | "arm64" 399 | ], 400 | "license": "MIT", 401 | "optional": true, 402 | "os": [ 403 | "openbsd" 404 | ], 405 | "engines": { 406 | "node": ">=18" 407 | } 408 | }, 409 | "node_modules/@esbuild/openbsd-x64": { 410 | "version": "0.25.2", 411 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", 412 | "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", 413 | "cpu": [ 414 | "x64" 415 | ], 416 | "license": "MIT", 417 | "optional": true, 418 | "os": [ 419 | "openbsd" 420 | ], 421 | "engines": { 422 | "node": ">=18" 423 | } 424 | }, 425 | "node_modules/@esbuild/sunos-x64": { 426 | "version": "0.25.2", 427 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", 428 | "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", 429 | "cpu": [ 430 | "x64" 431 | ], 432 | "license": "MIT", 433 | "optional": true, 434 | "os": [ 435 | "sunos" 436 | ], 437 | "engines": { 438 | "node": ">=18" 439 | } 440 | }, 441 | "node_modules/@esbuild/win32-arm64": { 442 | "version": "0.25.2", 443 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", 444 | "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", 445 | "cpu": [ 446 | "arm64" 447 | ], 448 | "license": "MIT", 449 | "optional": true, 450 | "os": [ 451 | "win32" 452 | ], 453 | "engines": { 454 | "node": ">=18" 455 | } 456 | }, 457 | "node_modules/@esbuild/win32-ia32": { 458 | "version": "0.25.2", 459 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", 460 | "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", 461 | "cpu": [ 462 | "ia32" 463 | ], 464 | "license": "MIT", 465 | "optional": true, 466 | "os": [ 467 | "win32" 468 | ], 469 | "engines": { 470 | "node": ">=18" 471 | } 472 | }, 473 | "node_modules/@esbuild/win32-x64": { 474 | "version": "0.25.2", 475 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", 476 | "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", 477 | "cpu": [ 478 | "x64" 479 | ], 480 | "license": "MIT", 481 | "optional": true, 482 | "os": [ 483 | "win32" 484 | ], 485 | "engines": { 486 | "node": ">=18" 487 | } 488 | }, 489 | "node_modules/@jridgewell/sourcemap-codec": { 490 | "version": "1.5.0", 491 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 492 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 493 | "dev": true, 494 | "license": "MIT" 495 | }, 496 | "node_modules/@rollup/rollup-android-arm-eabi": { 497 | "version": "4.38.0", 498 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz", 499 | "integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==", 500 | "cpu": [ 501 | "arm" 502 | ], 503 | "dev": true, 504 | "license": "MIT", 505 | "optional": true, 506 | "os": [ 507 | "android" 508 | ] 509 | }, 510 | "node_modules/@rollup/rollup-android-arm64": { 511 | "version": "4.38.0", 512 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz", 513 | "integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==", 514 | "cpu": [ 515 | "arm64" 516 | ], 517 | "dev": true, 518 | "license": "MIT", 519 | "optional": true, 520 | "os": [ 521 | "android" 522 | ] 523 | }, 524 | "node_modules/@rollup/rollup-darwin-arm64": { 525 | "version": "4.38.0", 526 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz", 527 | "integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==", 528 | "cpu": [ 529 | "arm64" 530 | ], 531 | "dev": true, 532 | "license": "MIT", 533 | "optional": true, 534 | "os": [ 535 | "darwin" 536 | ] 537 | }, 538 | "node_modules/@rollup/rollup-darwin-x64": { 539 | "version": "4.38.0", 540 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz", 541 | "integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==", 542 | "cpu": [ 543 | "x64" 544 | ], 545 | "dev": true, 546 | "license": "MIT", 547 | "optional": true, 548 | "os": [ 549 | "darwin" 550 | ] 551 | }, 552 | "node_modules/@rollup/rollup-freebsd-arm64": { 553 | "version": "4.38.0", 554 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz", 555 | "integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==", 556 | "cpu": [ 557 | "arm64" 558 | ], 559 | "dev": true, 560 | "license": "MIT", 561 | "optional": true, 562 | "os": [ 563 | "freebsd" 564 | ] 565 | }, 566 | "node_modules/@rollup/rollup-freebsd-x64": { 567 | "version": "4.38.0", 568 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz", 569 | "integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==", 570 | "cpu": [ 571 | "x64" 572 | ], 573 | "dev": true, 574 | "license": "MIT", 575 | "optional": true, 576 | "os": [ 577 | "freebsd" 578 | ] 579 | }, 580 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 581 | "version": "4.38.0", 582 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz", 583 | "integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==", 584 | "cpu": [ 585 | "arm" 586 | ], 587 | "dev": true, 588 | "license": "MIT", 589 | "optional": true, 590 | "os": [ 591 | "linux" 592 | ] 593 | }, 594 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 595 | "version": "4.38.0", 596 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz", 597 | "integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==", 598 | "cpu": [ 599 | "arm" 600 | ], 601 | "dev": true, 602 | "license": "MIT", 603 | "optional": true, 604 | "os": [ 605 | "linux" 606 | ] 607 | }, 608 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 609 | "version": "4.38.0", 610 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz", 611 | "integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==", 612 | "cpu": [ 613 | "arm64" 614 | ], 615 | "dev": true, 616 | "license": "MIT", 617 | "optional": true, 618 | "os": [ 619 | "linux" 620 | ] 621 | }, 622 | "node_modules/@rollup/rollup-linux-arm64-musl": { 623 | "version": "4.38.0", 624 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz", 625 | "integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==", 626 | "cpu": [ 627 | "arm64" 628 | ], 629 | "dev": true, 630 | "license": "MIT", 631 | "optional": true, 632 | "os": [ 633 | "linux" 634 | ] 635 | }, 636 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 637 | "version": "4.38.0", 638 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz", 639 | "integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==", 640 | "cpu": [ 641 | "loong64" 642 | ], 643 | "dev": true, 644 | "license": "MIT", 645 | "optional": true, 646 | "os": [ 647 | "linux" 648 | ] 649 | }, 650 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 651 | "version": "4.38.0", 652 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz", 653 | "integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==", 654 | "cpu": [ 655 | "ppc64" 656 | ], 657 | "dev": true, 658 | "license": "MIT", 659 | "optional": true, 660 | "os": [ 661 | "linux" 662 | ] 663 | }, 664 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 665 | "version": "4.38.0", 666 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz", 667 | "integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==", 668 | "cpu": [ 669 | "riscv64" 670 | ], 671 | "dev": true, 672 | "license": "MIT", 673 | "optional": true, 674 | "os": [ 675 | "linux" 676 | ] 677 | }, 678 | "node_modules/@rollup/rollup-linux-riscv64-musl": { 679 | "version": "4.38.0", 680 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz", 681 | "integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==", 682 | "cpu": [ 683 | "riscv64" 684 | ], 685 | "dev": true, 686 | "license": "MIT", 687 | "optional": true, 688 | "os": [ 689 | "linux" 690 | ] 691 | }, 692 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 693 | "version": "4.38.0", 694 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz", 695 | "integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==", 696 | "cpu": [ 697 | "s390x" 698 | ], 699 | "dev": true, 700 | "license": "MIT", 701 | "optional": true, 702 | "os": [ 703 | "linux" 704 | ] 705 | }, 706 | "node_modules/@rollup/rollup-linux-x64-gnu": { 707 | "version": "4.38.0", 708 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz", 709 | "integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==", 710 | "cpu": [ 711 | "x64" 712 | ], 713 | "dev": true, 714 | "license": "MIT", 715 | "optional": true, 716 | "os": [ 717 | "linux" 718 | ] 719 | }, 720 | "node_modules/@rollup/rollup-linux-x64-musl": { 721 | "version": "4.38.0", 722 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz", 723 | "integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==", 724 | "cpu": [ 725 | "x64" 726 | ], 727 | "dev": true, 728 | "license": "MIT", 729 | "optional": true, 730 | "os": [ 731 | "linux" 732 | ] 733 | }, 734 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 735 | "version": "4.38.0", 736 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz", 737 | "integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==", 738 | "cpu": [ 739 | "arm64" 740 | ], 741 | "dev": true, 742 | "license": "MIT", 743 | "optional": true, 744 | "os": [ 745 | "win32" 746 | ] 747 | }, 748 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 749 | "version": "4.38.0", 750 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz", 751 | "integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==", 752 | "cpu": [ 753 | "ia32" 754 | ], 755 | "dev": true, 756 | "license": "MIT", 757 | "optional": true, 758 | "os": [ 759 | "win32" 760 | ] 761 | }, 762 | "node_modules/@rollup/rollup-win32-x64-msvc": { 763 | "version": "4.38.0", 764 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz", 765 | "integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==", 766 | "cpu": [ 767 | "x64" 768 | ], 769 | "dev": true, 770 | "license": "MIT", 771 | "optional": true, 772 | "os": [ 773 | "win32" 774 | ] 775 | }, 776 | "node_modules/@storybook/components": { 777 | "version": "8.6.11", 778 | "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.11.tgz", 779 | "integrity": "sha512-+lHcwQsSO8usKTXIBBmgmRCAa0L+KQaLJ5ARqkRTm6OjzkVVS+EPnIgL4H1nqzbwiTVXxSSOwAk+rST83KICnA==", 780 | "license": "MIT", 781 | "funding": { 782 | "type": "opencollective", 783 | "url": "https://opencollective.com/storybook" 784 | }, 785 | "peerDependencies": { 786 | "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" 787 | } 788 | }, 789 | "node_modules/@storybook/core": { 790 | "version": "8.6.11", 791 | "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.11.tgz", 792 | "integrity": "sha512-fhzLQ9HpljbLpkHykafmcjIERHI5j6SZhylFCDwEWkETuZtRbyCs3mmULutcEOzKhxRgNtiIRoRmZPdQcPtHNg==", 793 | "license": "MIT", 794 | "peer": true, 795 | "dependencies": { 796 | "@storybook/theming": "8.6.11", 797 | "better-opn": "^3.0.2", 798 | "browser-assert": "^1.2.1", 799 | "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", 800 | "esbuild-register": "^3.5.0", 801 | "jsdoc-type-pratt-parser": "^4.0.0", 802 | "process": "^0.11.10", 803 | "recast": "^0.23.5", 804 | "semver": "^7.6.2", 805 | "util": "^0.12.5", 806 | "ws": "^8.2.3" 807 | }, 808 | "funding": { 809 | "type": "opencollective", 810 | "url": "https://opencollective.com/storybook" 811 | }, 812 | "peerDependencies": { 813 | "prettier": "^2 || ^3" 814 | }, 815 | "peerDependenciesMeta": { 816 | "prettier": { 817 | "optional": true 818 | } 819 | } 820 | }, 821 | "node_modules/@storybook/manager-api": { 822 | "version": "8.6.11", 823 | "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.11.tgz", 824 | "integrity": "sha512-U3ijEFX7B7wNYzFctmTIXOiN0zLlt8/9EHbZQUUrQ1pf7bQzADJCy63Y3B+kir8i+n3LsBWB42X2aSiT0lLaKQ==", 825 | "license": "MIT", 826 | "funding": { 827 | "type": "opencollective", 828 | "url": "https://opencollective.com/storybook" 829 | }, 830 | "peerDependencies": { 831 | "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" 832 | } 833 | }, 834 | "node_modules/@storybook/theming": { 835 | "version": "8.6.11", 836 | "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.11.tgz", 837 | "integrity": "sha512-G7IK5P9gzofUjfYhMo9Pdgbqcr22eoKFLD808Q8RxJopDoypdZKg4tes2iD+6YnrtnHS0nEoP/soMmfFYl9FIw==", 838 | "license": "MIT", 839 | "peer": true, 840 | "funding": { 841 | "type": "opencollective", 842 | "url": "https://opencollective.com/storybook" 843 | }, 844 | "peerDependencies": { 845 | "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" 846 | } 847 | }, 848 | "node_modules/@storybook/types": { 849 | "version": "8.6.11", 850 | "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.6.11.tgz", 851 | "integrity": "sha512-Rg8n6cATtZEZtJxxRhMArpbLKoYOHT/eAZTQH5Il3k4JQUUKEyUlTA/3qVnbU3RTGpaLgpiwMDzc9lOd/fdKDQ==", 852 | "license": "MIT", 853 | "funding": { 854 | "type": "opencollective", 855 | "url": "https://opencollective.com/storybook" 856 | }, 857 | "peerDependencies": { 858 | "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" 859 | } 860 | }, 861 | "node_modules/@testing-library/dom": { 862 | "version": "10.4.0", 863 | "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", 864 | "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", 865 | "dev": true, 866 | "license": "MIT", 867 | "dependencies": { 868 | "@babel/code-frame": "^7.10.4", 869 | "@babel/runtime": "^7.12.5", 870 | "@types/aria-query": "^5.0.1", 871 | "aria-query": "5.3.0", 872 | "chalk": "^4.1.0", 873 | "dom-accessibility-api": "^0.5.9", 874 | "lz-string": "^1.5.0", 875 | "pretty-format": "^27.0.2" 876 | }, 877 | "engines": { 878 | "node": ">=18" 879 | } 880 | }, 881 | "node_modules/@testing-library/react": { 882 | "version": "16.2.0", 883 | "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.2.0.tgz", 884 | "integrity": "sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==", 885 | "dev": true, 886 | "license": "MIT", 887 | "dependencies": { 888 | "@babel/runtime": "^7.12.5" 889 | }, 890 | "engines": { 891 | "node": ">=18" 892 | }, 893 | "peerDependencies": { 894 | "@testing-library/dom": "^10.0.0", 895 | "@types/react": "^18.0.0 || ^19.0.0", 896 | "@types/react-dom": "^18.0.0 || ^19.0.0", 897 | "react": "^18.0.0 || ^19.0.0", 898 | "react-dom": "^18.0.0 || ^19.0.0" 899 | }, 900 | "peerDependenciesMeta": { 901 | "@types/react": { 902 | "optional": true 903 | }, 904 | "@types/react-dom": { 905 | "optional": true 906 | } 907 | } 908 | }, 909 | "node_modules/@types/aria-query": { 910 | "version": "5.0.4", 911 | "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", 912 | "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", 913 | "dev": true, 914 | "license": "MIT" 915 | }, 916 | "node_modules/@types/estree": { 917 | "version": "1.0.7", 918 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 919 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 920 | "dev": true, 921 | "license": "MIT" 922 | }, 923 | "node_modules/@types/node": { 924 | "version": "22.13.14", 925 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz", 926 | "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==", 927 | "dev": true, 928 | "license": "MIT", 929 | "dependencies": { 930 | "undici-types": "~6.20.0" 931 | } 932 | }, 933 | "node_modules/@types/prop-types": { 934 | "version": "15.7.14", 935 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", 936 | "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", 937 | "dev": true, 938 | "license": "MIT" 939 | }, 940 | "node_modules/@types/react": { 941 | "version": "18.3.20", 942 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz", 943 | "integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==", 944 | "dev": true, 945 | "license": "MIT", 946 | "dependencies": { 947 | "@types/prop-types": "*", 948 | "csstype": "^3.0.2" 949 | } 950 | }, 951 | "node_modules/@types/react-dom": { 952 | "version": "18.3.5", 953 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", 954 | "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", 955 | "dev": true, 956 | "license": "MIT", 957 | "peerDependencies": { 958 | "@types/react": "^18.0.0" 959 | } 960 | }, 961 | "node_modules/@vitest/expect": { 962 | "version": "3.1.1", 963 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz", 964 | "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==", 965 | "dev": true, 966 | "license": "MIT", 967 | "dependencies": { 968 | "@vitest/spy": "3.1.1", 969 | "@vitest/utils": "3.1.1", 970 | "chai": "^5.2.0", 971 | "tinyrainbow": "^2.0.0" 972 | }, 973 | "funding": { 974 | "url": "https://opencollective.com/vitest" 975 | } 976 | }, 977 | "node_modules/@vitest/mocker": { 978 | "version": "3.1.1", 979 | "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz", 980 | "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==", 981 | "dev": true, 982 | "license": "MIT", 983 | "dependencies": { 984 | "@vitest/spy": "3.1.1", 985 | "estree-walker": "^3.0.3", 986 | "magic-string": "^0.30.17" 987 | }, 988 | "funding": { 989 | "url": "https://opencollective.com/vitest" 990 | }, 991 | "peerDependencies": { 992 | "msw": "^2.4.9", 993 | "vite": "^5.0.0 || ^6.0.0" 994 | }, 995 | "peerDependenciesMeta": { 996 | "msw": { 997 | "optional": true 998 | }, 999 | "vite": { 1000 | "optional": true 1001 | } 1002 | } 1003 | }, 1004 | "node_modules/@vitest/pretty-format": { 1005 | "version": "3.1.1", 1006 | "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz", 1007 | "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==", 1008 | "dev": true, 1009 | "license": "MIT", 1010 | "dependencies": { 1011 | "tinyrainbow": "^2.0.0" 1012 | }, 1013 | "funding": { 1014 | "url": "https://opencollective.com/vitest" 1015 | } 1016 | }, 1017 | "node_modules/@vitest/runner": { 1018 | "version": "3.1.1", 1019 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz", 1020 | "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==", 1021 | "dev": true, 1022 | "license": "MIT", 1023 | "dependencies": { 1024 | "@vitest/utils": "3.1.1", 1025 | "pathe": "^2.0.3" 1026 | }, 1027 | "funding": { 1028 | "url": "https://opencollective.com/vitest" 1029 | } 1030 | }, 1031 | "node_modules/@vitest/snapshot": { 1032 | "version": "3.1.1", 1033 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz", 1034 | "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==", 1035 | "dev": true, 1036 | "license": "MIT", 1037 | "dependencies": { 1038 | "@vitest/pretty-format": "3.1.1", 1039 | "magic-string": "^0.30.17", 1040 | "pathe": "^2.0.3" 1041 | }, 1042 | "funding": { 1043 | "url": "https://opencollective.com/vitest" 1044 | } 1045 | }, 1046 | "node_modules/@vitest/spy": { 1047 | "version": "3.1.1", 1048 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz", 1049 | "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==", 1050 | "dev": true, 1051 | "license": "MIT", 1052 | "dependencies": { 1053 | "tinyspy": "^3.0.2" 1054 | }, 1055 | "funding": { 1056 | "url": "https://opencollective.com/vitest" 1057 | } 1058 | }, 1059 | "node_modules/@vitest/utils": { 1060 | "version": "3.1.1", 1061 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz", 1062 | "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==", 1063 | "dev": true, 1064 | "license": "MIT", 1065 | "dependencies": { 1066 | "@vitest/pretty-format": "3.1.1", 1067 | "loupe": "^3.1.3", 1068 | "tinyrainbow": "^2.0.0" 1069 | }, 1070 | "funding": { 1071 | "url": "https://opencollective.com/vitest" 1072 | } 1073 | }, 1074 | "node_modules/ansi-regex": { 1075 | "version": "5.0.1", 1076 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1077 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1078 | "dev": true, 1079 | "license": "MIT", 1080 | "engines": { 1081 | "node": ">=8" 1082 | } 1083 | }, 1084 | "node_modules/ansi-styles": { 1085 | "version": "4.3.0", 1086 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1087 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1088 | "dev": true, 1089 | "license": "MIT", 1090 | "dependencies": { 1091 | "color-convert": "^2.0.1" 1092 | }, 1093 | "engines": { 1094 | "node": ">=8" 1095 | }, 1096 | "funding": { 1097 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1098 | } 1099 | }, 1100 | "node_modules/aria-query": { 1101 | "version": "5.3.0", 1102 | "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", 1103 | "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", 1104 | "dev": true, 1105 | "license": "Apache-2.0", 1106 | "dependencies": { 1107 | "dequal": "^2.0.3" 1108 | } 1109 | }, 1110 | "node_modules/assertion-error": { 1111 | "version": "2.0.1", 1112 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", 1113 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", 1114 | "dev": true, 1115 | "license": "MIT", 1116 | "engines": { 1117 | "node": ">=12" 1118 | } 1119 | }, 1120 | "node_modules/ast-types": { 1121 | "version": "0.16.1", 1122 | "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", 1123 | "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", 1124 | "license": "MIT", 1125 | "peer": true, 1126 | "dependencies": { 1127 | "tslib": "^2.0.1" 1128 | }, 1129 | "engines": { 1130 | "node": ">=4" 1131 | } 1132 | }, 1133 | "node_modules/available-typed-arrays": { 1134 | "version": "1.0.7", 1135 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", 1136 | "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", 1137 | "license": "MIT", 1138 | "peer": true, 1139 | "dependencies": { 1140 | "possible-typed-array-names": "^1.0.0" 1141 | }, 1142 | "engines": { 1143 | "node": ">= 0.4" 1144 | }, 1145 | "funding": { 1146 | "url": "https://github.com/sponsors/ljharb" 1147 | } 1148 | }, 1149 | "node_modules/better-opn": { 1150 | "version": "3.0.2", 1151 | "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", 1152 | "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", 1153 | "license": "MIT", 1154 | "peer": true, 1155 | "dependencies": { 1156 | "open": "^8.0.4" 1157 | }, 1158 | "engines": { 1159 | "node": ">=12.0.0" 1160 | } 1161 | }, 1162 | "node_modules/browser-assert": { 1163 | "version": "1.2.1", 1164 | "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", 1165 | "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", 1166 | "peer": true 1167 | }, 1168 | "node_modules/cac": { 1169 | "version": "6.7.14", 1170 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 1171 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 1172 | "dev": true, 1173 | "license": "MIT", 1174 | "engines": { 1175 | "node": ">=8" 1176 | } 1177 | }, 1178 | "node_modules/call-bind": { 1179 | "version": "1.0.8", 1180 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", 1181 | "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", 1182 | "license": "MIT", 1183 | "peer": true, 1184 | "dependencies": { 1185 | "call-bind-apply-helpers": "^1.0.0", 1186 | "es-define-property": "^1.0.0", 1187 | "get-intrinsic": "^1.2.4", 1188 | "set-function-length": "^1.2.2" 1189 | }, 1190 | "engines": { 1191 | "node": ">= 0.4" 1192 | }, 1193 | "funding": { 1194 | "url": "https://github.com/sponsors/ljharb" 1195 | } 1196 | }, 1197 | "node_modules/call-bind-apply-helpers": { 1198 | "version": "1.0.2", 1199 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 1200 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 1201 | "license": "MIT", 1202 | "peer": true, 1203 | "dependencies": { 1204 | "es-errors": "^1.3.0", 1205 | "function-bind": "^1.1.2" 1206 | }, 1207 | "engines": { 1208 | "node": ">= 0.4" 1209 | } 1210 | }, 1211 | "node_modules/call-bound": { 1212 | "version": "1.0.4", 1213 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 1214 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 1215 | "license": "MIT", 1216 | "peer": true, 1217 | "dependencies": { 1218 | "call-bind-apply-helpers": "^1.0.2", 1219 | "get-intrinsic": "^1.3.0" 1220 | }, 1221 | "engines": { 1222 | "node": ">= 0.4" 1223 | }, 1224 | "funding": { 1225 | "url": "https://github.com/sponsors/ljharb" 1226 | } 1227 | }, 1228 | "node_modules/chai": { 1229 | "version": "5.2.0", 1230 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", 1231 | "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", 1232 | "dev": true, 1233 | "license": "MIT", 1234 | "dependencies": { 1235 | "assertion-error": "^2.0.1", 1236 | "check-error": "^2.1.1", 1237 | "deep-eql": "^5.0.1", 1238 | "loupe": "^3.1.0", 1239 | "pathval": "^2.0.0" 1240 | }, 1241 | "engines": { 1242 | "node": ">=12" 1243 | } 1244 | }, 1245 | "node_modules/chalk": { 1246 | "version": "4.1.2", 1247 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1248 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1249 | "dev": true, 1250 | "license": "MIT", 1251 | "dependencies": { 1252 | "ansi-styles": "^4.1.0", 1253 | "supports-color": "^7.1.0" 1254 | }, 1255 | "engines": { 1256 | "node": ">=10" 1257 | }, 1258 | "funding": { 1259 | "url": "https://github.com/chalk/chalk?sponsor=1" 1260 | } 1261 | }, 1262 | "node_modules/check-error": { 1263 | "version": "2.1.1", 1264 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", 1265 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", 1266 | "dev": true, 1267 | "license": "MIT", 1268 | "engines": { 1269 | "node": ">= 16" 1270 | } 1271 | }, 1272 | "node_modules/color-convert": { 1273 | "version": "2.0.1", 1274 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1275 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1276 | "dev": true, 1277 | "license": "MIT", 1278 | "dependencies": { 1279 | "color-name": "~1.1.4" 1280 | }, 1281 | "engines": { 1282 | "node": ">=7.0.0" 1283 | } 1284 | }, 1285 | "node_modules/color-name": { 1286 | "version": "1.1.4", 1287 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1288 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1289 | "dev": true, 1290 | "license": "MIT" 1291 | }, 1292 | "node_modules/csstype": { 1293 | "version": "3.1.3", 1294 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", 1295 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", 1296 | "dev": true, 1297 | "license": "MIT" 1298 | }, 1299 | "node_modules/debug": { 1300 | "version": "4.4.0", 1301 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1302 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1303 | "license": "MIT", 1304 | "dependencies": { 1305 | "ms": "^2.1.3" 1306 | }, 1307 | "engines": { 1308 | "node": ">=6.0" 1309 | }, 1310 | "peerDependenciesMeta": { 1311 | "supports-color": { 1312 | "optional": true 1313 | } 1314 | } 1315 | }, 1316 | "node_modules/deep-eql": { 1317 | "version": "5.0.2", 1318 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", 1319 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", 1320 | "dev": true, 1321 | "license": "MIT", 1322 | "engines": { 1323 | "node": ">=6" 1324 | } 1325 | }, 1326 | "node_modules/define-data-property": { 1327 | "version": "1.1.4", 1328 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 1329 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 1330 | "license": "MIT", 1331 | "peer": true, 1332 | "dependencies": { 1333 | "es-define-property": "^1.0.0", 1334 | "es-errors": "^1.3.0", 1335 | "gopd": "^1.0.1" 1336 | }, 1337 | "engines": { 1338 | "node": ">= 0.4" 1339 | }, 1340 | "funding": { 1341 | "url": "https://github.com/sponsors/ljharb" 1342 | } 1343 | }, 1344 | "node_modules/define-lazy-prop": { 1345 | "version": "2.0.0", 1346 | "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", 1347 | "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", 1348 | "license": "MIT", 1349 | "peer": true, 1350 | "engines": { 1351 | "node": ">=8" 1352 | } 1353 | }, 1354 | "node_modules/dequal": { 1355 | "version": "2.0.3", 1356 | "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", 1357 | "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", 1358 | "dev": true, 1359 | "license": "MIT", 1360 | "engines": { 1361 | "node": ">=6" 1362 | } 1363 | }, 1364 | "node_modules/dom-accessibility-api": { 1365 | "version": "0.5.16", 1366 | "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", 1367 | "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", 1368 | "dev": true, 1369 | "license": "MIT" 1370 | }, 1371 | "node_modules/dunder-proto": { 1372 | "version": "1.0.1", 1373 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 1374 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 1375 | "license": "MIT", 1376 | "peer": true, 1377 | "dependencies": { 1378 | "call-bind-apply-helpers": "^1.0.1", 1379 | "es-errors": "^1.3.0", 1380 | "gopd": "^1.2.0" 1381 | }, 1382 | "engines": { 1383 | "node": ">= 0.4" 1384 | } 1385 | }, 1386 | "node_modules/es-define-property": { 1387 | "version": "1.0.1", 1388 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 1389 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 1390 | "license": "MIT", 1391 | "peer": true, 1392 | "engines": { 1393 | "node": ">= 0.4" 1394 | } 1395 | }, 1396 | "node_modules/es-errors": { 1397 | "version": "1.3.0", 1398 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 1399 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 1400 | "license": "MIT", 1401 | "peer": true, 1402 | "engines": { 1403 | "node": ">= 0.4" 1404 | } 1405 | }, 1406 | "node_modules/es-module-lexer": { 1407 | "version": "1.6.0", 1408 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", 1409 | "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", 1410 | "dev": true, 1411 | "license": "MIT" 1412 | }, 1413 | "node_modules/es-object-atoms": { 1414 | "version": "1.1.1", 1415 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 1416 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 1417 | "license": "MIT", 1418 | "peer": true, 1419 | "dependencies": { 1420 | "es-errors": "^1.3.0" 1421 | }, 1422 | "engines": { 1423 | "node": ">= 0.4" 1424 | } 1425 | }, 1426 | "node_modules/esbuild": { 1427 | "version": "0.25.2", 1428 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", 1429 | "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", 1430 | "hasInstallScript": true, 1431 | "license": "MIT", 1432 | "bin": { 1433 | "esbuild": "bin/esbuild" 1434 | }, 1435 | "engines": { 1436 | "node": ">=18" 1437 | }, 1438 | "optionalDependencies": { 1439 | "@esbuild/aix-ppc64": "0.25.2", 1440 | "@esbuild/android-arm": "0.25.2", 1441 | "@esbuild/android-arm64": "0.25.2", 1442 | "@esbuild/android-x64": "0.25.2", 1443 | "@esbuild/darwin-arm64": "0.25.2", 1444 | "@esbuild/darwin-x64": "0.25.2", 1445 | "@esbuild/freebsd-arm64": "0.25.2", 1446 | "@esbuild/freebsd-x64": "0.25.2", 1447 | "@esbuild/linux-arm": "0.25.2", 1448 | "@esbuild/linux-arm64": "0.25.2", 1449 | "@esbuild/linux-ia32": "0.25.2", 1450 | "@esbuild/linux-loong64": "0.25.2", 1451 | "@esbuild/linux-mips64el": "0.25.2", 1452 | "@esbuild/linux-ppc64": "0.25.2", 1453 | "@esbuild/linux-riscv64": "0.25.2", 1454 | "@esbuild/linux-s390x": "0.25.2", 1455 | "@esbuild/linux-x64": "0.25.2", 1456 | "@esbuild/netbsd-arm64": "0.25.2", 1457 | "@esbuild/netbsd-x64": "0.25.2", 1458 | "@esbuild/openbsd-arm64": "0.25.2", 1459 | "@esbuild/openbsd-x64": "0.25.2", 1460 | "@esbuild/sunos-x64": "0.25.2", 1461 | "@esbuild/win32-arm64": "0.25.2", 1462 | "@esbuild/win32-ia32": "0.25.2", 1463 | "@esbuild/win32-x64": "0.25.2" 1464 | } 1465 | }, 1466 | "node_modules/esbuild-register": { 1467 | "version": "3.6.0", 1468 | "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", 1469 | "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", 1470 | "license": "MIT", 1471 | "peer": true, 1472 | "dependencies": { 1473 | "debug": "^4.3.4" 1474 | }, 1475 | "peerDependencies": { 1476 | "esbuild": ">=0.12 <1" 1477 | } 1478 | }, 1479 | "node_modules/esprima": { 1480 | "version": "4.0.1", 1481 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1482 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1483 | "license": "BSD-2-Clause", 1484 | "peer": true, 1485 | "bin": { 1486 | "esparse": "bin/esparse.js", 1487 | "esvalidate": "bin/esvalidate.js" 1488 | }, 1489 | "engines": { 1490 | "node": ">=4" 1491 | } 1492 | }, 1493 | "node_modules/estree-walker": { 1494 | "version": "3.0.3", 1495 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1496 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1497 | "dev": true, 1498 | "license": "MIT", 1499 | "dependencies": { 1500 | "@types/estree": "^1.0.0" 1501 | } 1502 | }, 1503 | "node_modules/expect-type": { 1504 | "version": "1.2.0", 1505 | "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", 1506 | "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", 1507 | "dev": true, 1508 | "license": "Apache-2.0", 1509 | "engines": { 1510 | "node": ">=12.0.0" 1511 | } 1512 | }, 1513 | "node_modules/for-each": { 1514 | "version": "0.3.5", 1515 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", 1516 | "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", 1517 | "license": "MIT", 1518 | "peer": true, 1519 | "dependencies": { 1520 | "is-callable": "^1.2.7" 1521 | }, 1522 | "engines": { 1523 | "node": ">= 0.4" 1524 | }, 1525 | "funding": { 1526 | "url": "https://github.com/sponsors/ljharb" 1527 | } 1528 | }, 1529 | "node_modules/fsevents": { 1530 | "version": "2.3.3", 1531 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1532 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1533 | "dev": true, 1534 | "hasInstallScript": true, 1535 | "license": "MIT", 1536 | "optional": true, 1537 | "os": [ 1538 | "darwin" 1539 | ], 1540 | "engines": { 1541 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1542 | } 1543 | }, 1544 | "node_modules/function-bind": { 1545 | "version": "1.1.2", 1546 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1547 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1548 | "license": "MIT", 1549 | "peer": true, 1550 | "funding": { 1551 | "url": "https://github.com/sponsors/ljharb" 1552 | } 1553 | }, 1554 | "node_modules/get-intrinsic": { 1555 | "version": "1.3.0", 1556 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 1557 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 1558 | "license": "MIT", 1559 | "peer": true, 1560 | "dependencies": { 1561 | "call-bind-apply-helpers": "^1.0.2", 1562 | "es-define-property": "^1.0.1", 1563 | "es-errors": "^1.3.0", 1564 | "es-object-atoms": "^1.1.1", 1565 | "function-bind": "^1.1.2", 1566 | "get-proto": "^1.0.1", 1567 | "gopd": "^1.2.0", 1568 | "has-symbols": "^1.1.0", 1569 | "hasown": "^2.0.2", 1570 | "math-intrinsics": "^1.1.0" 1571 | }, 1572 | "engines": { 1573 | "node": ">= 0.4" 1574 | }, 1575 | "funding": { 1576 | "url": "https://github.com/sponsors/ljharb" 1577 | } 1578 | }, 1579 | "node_modules/get-proto": { 1580 | "version": "1.0.1", 1581 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 1582 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 1583 | "license": "MIT", 1584 | "peer": true, 1585 | "dependencies": { 1586 | "dunder-proto": "^1.0.1", 1587 | "es-object-atoms": "^1.0.0" 1588 | }, 1589 | "engines": { 1590 | "node": ">= 0.4" 1591 | } 1592 | }, 1593 | "node_modules/gopd": { 1594 | "version": "1.2.0", 1595 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 1596 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 1597 | "license": "MIT", 1598 | "peer": true, 1599 | "engines": { 1600 | "node": ">= 0.4" 1601 | }, 1602 | "funding": { 1603 | "url": "https://github.com/sponsors/ljharb" 1604 | } 1605 | }, 1606 | "node_modules/happy-dom": { 1607 | "version": "17.4.4", 1608 | "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz", 1609 | "integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==", 1610 | "dev": true, 1611 | "license": "MIT", 1612 | "dependencies": { 1613 | "webidl-conversions": "^7.0.0", 1614 | "whatwg-mimetype": "^3.0.0" 1615 | }, 1616 | "engines": { 1617 | "node": ">=18.0.0" 1618 | } 1619 | }, 1620 | "node_modules/has-flag": { 1621 | "version": "4.0.0", 1622 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1623 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1624 | "dev": true, 1625 | "license": "MIT", 1626 | "engines": { 1627 | "node": ">=8" 1628 | } 1629 | }, 1630 | "node_modules/has-property-descriptors": { 1631 | "version": "1.0.2", 1632 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 1633 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 1634 | "license": "MIT", 1635 | "peer": true, 1636 | "dependencies": { 1637 | "es-define-property": "^1.0.0" 1638 | }, 1639 | "funding": { 1640 | "url": "https://github.com/sponsors/ljharb" 1641 | } 1642 | }, 1643 | "node_modules/has-symbols": { 1644 | "version": "1.1.0", 1645 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 1646 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 1647 | "license": "MIT", 1648 | "peer": true, 1649 | "engines": { 1650 | "node": ">= 0.4" 1651 | }, 1652 | "funding": { 1653 | "url": "https://github.com/sponsors/ljharb" 1654 | } 1655 | }, 1656 | "node_modules/has-tostringtag": { 1657 | "version": "1.0.2", 1658 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 1659 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 1660 | "license": "MIT", 1661 | "peer": true, 1662 | "dependencies": { 1663 | "has-symbols": "^1.0.3" 1664 | }, 1665 | "engines": { 1666 | "node": ">= 0.4" 1667 | }, 1668 | "funding": { 1669 | "url": "https://github.com/sponsors/ljharb" 1670 | } 1671 | }, 1672 | "node_modules/hasown": { 1673 | "version": "2.0.2", 1674 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1675 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1676 | "license": "MIT", 1677 | "peer": true, 1678 | "dependencies": { 1679 | "function-bind": "^1.1.2" 1680 | }, 1681 | "engines": { 1682 | "node": ">= 0.4" 1683 | } 1684 | }, 1685 | "node_modules/inherits": { 1686 | "version": "2.0.4", 1687 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1688 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1689 | "license": "ISC", 1690 | "peer": true 1691 | }, 1692 | "node_modules/is-arguments": { 1693 | "version": "1.2.0", 1694 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", 1695 | "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", 1696 | "license": "MIT", 1697 | "peer": true, 1698 | "dependencies": { 1699 | "call-bound": "^1.0.2", 1700 | "has-tostringtag": "^1.0.2" 1701 | }, 1702 | "engines": { 1703 | "node": ">= 0.4" 1704 | }, 1705 | "funding": { 1706 | "url": "https://github.com/sponsors/ljharb" 1707 | } 1708 | }, 1709 | "node_modules/is-callable": { 1710 | "version": "1.2.7", 1711 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 1712 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 1713 | "license": "MIT", 1714 | "peer": true, 1715 | "engines": { 1716 | "node": ">= 0.4" 1717 | }, 1718 | "funding": { 1719 | "url": "https://github.com/sponsors/ljharb" 1720 | } 1721 | }, 1722 | "node_modules/is-docker": { 1723 | "version": "2.2.1", 1724 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", 1725 | "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", 1726 | "license": "MIT", 1727 | "peer": true, 1728 | "bin": { 1729 | "is-docker": "cli.js" 1730 | }, 1731 | "engines": { 1732 | "node": ">=8" 1733 | }, 1734 | "funding": { 1735 | "url": "https://github.com/sponsors/sindresorhus" 1736 | } 1737 | }, 1738 | "node_modules/is-generator-function": { 1739 | "version": "1.1.0", 1740 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", 1741 | "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", 1742 | "license": "MIT", 1743 | "peer": true, 1744 | "dependencies": { 1745 | "call-bound": "^1.0.3", 1746 | "get-proto": "^1.0.0", 1747 | "has-tostringtag": "^1.0.2", 1748 | "safe-regex-test": "^1.1.0" 1749 | }, 1750 | "engines": { 1751 | "node": ">= 0.4" 1752 | }, 1753 | "funding": { 1754 | "url": "https://github.com/sponsors/ljharb" 1755 | } 1756 | }, 1757 | "node_modules/is-regex": { 1758 | "version": "1.2.1", 1759 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", 1760 | "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", 1761 | "license": "MIT", 1762 | "peer": true, 1763 | "dependencies": { 1764 | "call-bound": "^1.0.2", 1765 | "gopd": "^1.2.0", 1766 | "has-tostringtag": "^1.0.2", 1767 | "hasown": "^2.0.2" 1768 | }, 1769 | "engines": { 1770 | "node": ">= 0.4" 1771 | }, 1772 | "funding": { 1773 | "url": "https://github.com/sponsors/ljharb" 1774 | } 1775 | }, 1776 | "node_modules/is-typed-array": { 1777 | "version": "1.1.15", 1778 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", 1779 | "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", 1780 | "license": "MIT", 1781 | "peer": true, 1782 | "dependencies": { 1783 | "which-typed-array": "^1.1.16" 1784 | }, 1785 | "engines": { 1786 | "node": ">= 0.4" 1787 | }, 1788 | "funding": { 1789 | "url": "https://github.com/sponsors/ljharb" 1790 | } 1791 | }, 1792 | "node_modules/is-wsl": { 1793 | "version": "2.2.0", 1794 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", 1795 | "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", 1796 | "license": "MIT", 1797 | "peer": true, 1798 | "dependencies": { 1799 | "is-docker": "^2.0.0" 1800 | }, 1801 | "engines": { 1802 | "node": ">=8" 1803 | } 1804 | }, 1805 | "node_modules/js-tokens": { 1806 | "version": "4.0.0", 1807 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1808 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1809 | "dev": true, 1810 | "license": "MIT" 1811 | }, 1812 | "node_modules/jsdoc-type-pratt-parser": { 1813 | "version": "4.1.0", 1814 | "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", 1815 | "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", 1816 | "license": "MIT", 1817 | "peer": true, 1818 | "engines": { 1819 | "node": ">=12.0.0" 1820 | } 1821 | }, 1822 | "node_modules/loose-envify": { 1823 | "version": "1.4.0", 1824 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 1825 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 1826 | "dev": true, 1827 | "license": "MIT", 1828 | "dependencies": { 1829 | "js-tokens": "^3.0.0 || ^4.0.0" 1830 | }, 1831 | "bin": { 1832 | "loose-envify": "cli.js" 1833 | } 1834 | }, 1835 | "node_modules/loupe": { 1836 | "version": "3.1.3", 1837 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", 1838 | "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", 1839 | "dev": true, 1840 | "license": "MIT" 1841 | }, 1842 | "node_modules/lz-string": { 1843 | "version": "1.5.0", 1844 | "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", 1845 | "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", 1846 | "dev": true, 1847 | "license": "MIT", 1848 | "bin": { 1849 | "lz-string": "bin/bin.js" 1850 | } 1851 | }, 1852 | "node_modules/magic-string": { 1853 | "version": "0.30.17", 1854 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 1855 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 1856 | "dev": true, 1857 | "license": "MIT", 1858 | "dependencies": { 1859 | "@jridgewell/sourcemap-codec": "^1.5.0" 1860 | } 1861 | }, 1862 | "node_modules/math-intrinsics": { 1863 | "version": "1.1.0", 1864 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1865 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1866 | "license": "MIT", 1867 | "peer": true, 1868 | "engines": { 1869 | "node": ">= 0.4" 1870 | } 1871 | }, 1872 | "node_modules/monaco-editor": { 1873 | "version": "0.52.2", 1874 | "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", 1875 | "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", 1876 | "license": "MIT" 1877 | }, 1878 | "node_modules/ms": { 1879 | "version": "2.1.3", 1880 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1881 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1882 | "license": "MIT" 1883 | }, 1884 | "node_modules/nanoid": { 1885 | "version": "3.3.11", 1886 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", 1887 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 1888 | "dev": true, 1889 | "funding": [ 1890 | { 1891 | "type": "github", 1892 | "url": "https://github.com/sponsors/ai" 1893 | } 1894 | ], 1895 | "license": "MIT", 1896 | "bin": { 1897 | "nanoid": "bin/nanoid.cjs" 1898 | }, 1899 | "engines": { 1900 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1901 | } 1902 | }, 1903 | "node_modules/open": { 1904 | "version": "8.4.2", 1905 | "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", 1906 | "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", 1907 | "license": "MIT", 1908 | "peer": true, 1909 | "dependencies": { 1910 | "define-lazy-prop": "^2.0.0", 1911 | "is-docker": "^2.1.1", 1912 | "is-wsl": "^2.2.0" 1913 | }, 1914 | "engines": { 1915 | "node": ">=12" 1916 | }, 1917 | "funding": { 1918 | "url": "https://github.com/sponsors/sindresorhus" 1919 | } 1920 | }, 1921 | "node_modules/pathe": { 1922 | "version": "2.0.3", 1923 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", 1924 | "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", 1925 | "dev": true, 1926 | "license": "MIT" 1927 | }, 1928 | "node_modules/pathval": { 1929 | "version": "2.0.0", 1930 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", 1931 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", 1932 | "dev": true, 1933 | "license": "MIT", 1934 | "engines": { 1935 | "node": ">= 14.16" 1936 | } 1937 | }, 1938 | "node_modules/picocolors": { 1939 | "version": "1.1.1", 1940 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1941 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1942 | "dev": true, 1943 | "license": "ISC" 1944 | }, 1945 | "node_modules/possible-typed-array-names": { 1946 | "version": "1.1.0", 1947 | "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", 1948 | "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", 1949 | "license": "MIT", 1950 | "peer": true, 1951 | "engines": { 1952 | "node": ">= 0.4" 1953 | } 1954 | }, 1955 | "node_modules/postcss": { 1956 | "version": "8.5.3", 1957 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", 1958 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 1959 | "dev": true, 1960 | "funding": [ 1961 | { 1962 | "type": "opencollective", 1963 | "url": "https://opencollective.com/postcss/" 1964 | }, 1965 | { 1966 | "type": "tidelift", 1967 | "url": "https://tidelift.com/funding/github/npm/postcss" 1968 | }, 1969 | { 1970 | "type": "github", 1971 | "url": "https://github.com/sponsors/ai" 1972 | } 1973 | ], 1974 | "license": "MIT", 1975 | "dependencies": { 1976 | "nanoid": "^3.3.8", 1977 | "picocolors": "^1.1.1", 1978 | "source-map-js": "^1.2.1" 1979 | }, 1980 | "engines": { 1981 | "node": "^10 || ^12 || >=14" 1982 | } 1983 | }, 1984 | "node_modules/prettier": { 1985 | "version": "3.5.3", 1986 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 1987 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 1988 | "devOptional": true, 1989 | "license": "MIT", 1990 | "bin": { 1991 | "prettier": "bin/prettier.cjs" 1992 | }, 1993 | "engines": { 1994 | "node": ">=14" 1995 | }, 1996 | "funding": { 1997 | "url": "https://github.com/prettier/prettier?sponsor=1" 1998 | } 1999 | }, 2000 | "node_modules/pretty-format": { 2001 | "version": "27.5.1", 2002 | "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", 2003 | "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", 2004 | "dev": true, 2005 | "license": "MIT", 2006 | "dependencies": { 2007 | "ansi-regex": "^5.0.1", 2008 | "ansi-styles": "^5.0.0", 2009 | "react-is": "^17.0.1" 2010 | }, 2011 | "engines": { 2012 | "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" 2013 | } 2014 | }, 2015 | "node_modules/pretty-format/node_modules/ansi-styles": { 2016 | "version": "5.2.0", 2017 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", 2018 | "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", 2019 | "dev": true, 2020 | "license": "MIT", 2021 | "engines": { 2022 | "node": ">=10" 2023 | }, 2024 | "funding": { 2025 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2026 | } 2027 | }, 2028 | "node_modules/process": { 2029 | "version": "0.11.10", 2030 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 2031 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 2032 | "license": "MIT", 2033 | "peer": true, 2034 | "engines": { 2035 | "node": ">= 0.6.0" 2036 | } 2037 | }, 2038 | "node_modules/react": { 2039 | "version": "18.3.1", 2040 | "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", 2041 | "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", 2042 | "dev": true, 2043 | "license": "MIT", 2044 | "dependencies": { 2045 | "loose-envify": "^1.1.0" 2046 | }, 2047 | "engines": { 2048 | "node": ">=0.10.0" 2049 | } 2050 | }, 2051 | "node_modules/react-dom": { 2052 | "version": "18.3.1", 2053 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", 2054 | "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", 2055 | "dev": true, 2056 | "license": "MIT", 2057 | "dependencies": { 2058 | "loose-envify": "^1.1.0", 2059 | "scheduler": "^0.23.2" 2060 | }, 2061 | "peerDependencies": { 2062 | "react": "^18.3.1" 2063 | } 2064 | }, 2065 | "node_modules/react-is": { 2066 | "version": "17.0.2", 2067 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", 2068 | "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", 2069 | "dev": true, 2070 | "license": "MIT" 2071 | }, 2072 | "node_modules/recast": { 2073 | "version": "0.23.11", 2074 | "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", 2075 | "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", 2076 | "license": "MIT", 2077 | "peer": true, 2078 | "dependencies": { 2079 | "ast-types": "^0.16.1", 2080 | "esprima": "~4.0.0", 2081 | "source-map": "~0.6.1", 2082 | "tiny-invariant": "^1.3.3", 2083 | "tslib": "^2.0.1" 2084 | }, 2085 | "engines": { 2086 | "node": ">= 4" 2087 | } 2088 | }, 2089 | "node_modules/regenerator-runtime": { 2090 | "version": "0.14.1", 2091 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", 2092 | "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", 2093 | "dev": true, 2094 | "license": "MIT" 2095 | }, 2096 | "node_modules/rollup": { 2097 | "version": "4.38.0", 2098 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz", 2099 | "integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==", 2100 | "dev": true, 2101 | "license": "MIT", 2102 | "dependencies": { 2103 | "@types/estree": "1.0.7" 2104 | }, 2105 | "bin": { 2106 | "rollup": "dist/bin/rollup" 2107 | }, 2108 | "engines": { 2109 | "node": ">=18.0.0", 2110 | "npm": ">=8.0.0" 2111 | }, 2112 | "optionalDependencies": { 2113 | "@rollup/rollup-android-arm-eabi": "4.38.0", 2114 | "@rollup/rollup-android-arm64": "4.38.0", 2115 | "@rollup/rollup-darwin-arm64": "4.38.0", 2116 | "@rollup/rollup-darwin-x64": "4.38.0", 2117 | "@rollup/rollup-freebsd-arm64": "4.38.0", 2118 | "@rollup/rollup-freebsd-x64": "4.38.0", 2119 | "@rollup/rollup-linux-arm-gnueabihf": "4.38.0", 2120 | "@rollup/rollup-linux-arm-musleabihf": "4.38.0", 2121 | "@rollup/rollup-linux-arm64-gnu": "4.38.0", 2122 | "@rollup/rollup-linux-arm64-musl": "4.38.0", 2123 | "@rollup/rollup-linux-loongarch64-gnu": "4.38.0", 2124 | "@rollup/rollup-linux-powerpc64le-gnu": "4.38.0", 2125 | "@rollup/rollup-linux-riscv64-gnu": "4.38.0", 2126 | "@rollup/rollup-linux-riscv64-musl": "4.38.0", 2127 | "@rollup/rollup-linux-s390x-gnu": "4.38.0", 2128 | "@rollup/rollup-linux-x64-gnu": "4.38.0", 2129 | "@rollup/rollup-linux-x64-musl": "4.38.0", 2130 | "@rollup/rollup-win32-arm64-msvc": "4.38.0", 2131 | "@rollup/rollup-win32-ia32-msvc": "4.38.0", 2132 | "@rollup/rollup-win32-x64-msvc": "4.38.0", 2133 | "fsevents": "~2.3.2" 2134 | } 2135 | }, 2136 | "node_modules/safe-regex-test": { 2137 | "version": "1.1.0", 2138 | "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", 2139 | "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", 2140 | "license": "MIT", 2141 | "peer": true, 2142 | "dependencies": { 2143 | "call-bound": "^1.0.2", 2144 | "es-errors": "^1.3.0", 2145 | "is-regex": "^1.2.1" 2146 | }, 2147 | "engines": { 2148 | "node": ">= 0.4" 2149 | }, 2150 | "funding": { 2151 | "url": "https://github.com/sponsors/ljharb" 2152 | } 2153 | }, 2154 | "node_modules/scheduler": { 2155 | "version": "0.23.2", 2156 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", 2157 | "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", 2158 | "dev": true, 2159 | "license": "MIT", 2160 | "dependencies": { 2161 | "loose-envify": "^1.1.0" 2162 | } 2163 | }, 2164 | "node_modules/semver": { 2165 | "version": "7.7.1", 2166 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", 2167 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", 2168 | "license": "ISC", 2169 | "peer": true, 2170 | "bin": { 2171 | "semver": "bin/semver.js" 2172 | }, 2173 | "engines": { 2174 | "node": ">=10" 2175 | } 2176 | }, 2177 | "node_modules/set-function-length": { 2178 | "version": "1.2.2", 2179 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 2180 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 2181 | "license": "MIT", 2182 | "peer": true, 2183 | "dependencies": { 2184 | "define-data-property": "^1.1.4", 2185 | "es-errors": "^1.3.0", 2186 | "function-bind": "^1.1.2", 2187 | "get-intrinsic": "^1.2.4", 2188 | "gopd": "^1.0.1", 2189 | "has-property-descriptors": "^1.0.2" 2190 | }, 2191 | "engines": { 2192 | "node": ">= 0.4" 2193 | } 2194 | }, 2195 | "node_modules/siginfo": { 2196 | "version": "2.0.0", 2197 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 2198 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 2199 | "dev": true, 2200 | "license": "ISC" 2201 | }, 2202 | "node_modules/source-map": { 2203 | "version": "0.6.1", 2204 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2205 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2206 | "license": "BSD-3-Clause", 2207 | "peer": true, 2208 | "engines": { 2209 | "node": ">=0.10.0" 2210 | } 2211 | }, 2212 | "node_modules/source-map-js": { 2213 | "version": "1.2.1", 2214 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 2215 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 2216 | "dev": true, 2217 | "license": "BSD-3-Clause", 2218 | "engines": { 2219 | "node": ">=0.10.0" 2220 | } 2221 | }, 2222 | "node_modules/stackback": { 2223 | "version": "0.0.2", 2224 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", 2225 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", 2226 | "dev": true, 2227 | "license": "MIT" 2228 | }, 2229 | "node_modules/std-env": { 2230 | "version": "3.8.1", 2231 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", 2232 | "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", 2233 | "dev": true, 2234 | "license": "MIT" 2235 | }, 2236 | "node_modules/storybook": { 2237 | "version": "8.6.11", 2238 | "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.11.tgz", 2239 | "integrity": "sha512-B2wxpmq1QYS4JV7RQu1mOHD7akfoGbuoUSkx2D2GZgv/zXAHZmDpSFcTvvBBm8FAtzChI9HhITSJ0YS0ePfnJQ==", 2240 | "license": "MIT", 2241 | "peer": true, 2242 | "dependencies": { 2243 | "@storybook/core": "8.6.11" 2244 | }, 2245 | "bin": { 2246 | "getstorybook": "bin/index.cjs", 2247 | "sb": "bin/index.cjs", 2248 | "storybook": "bin/index.cjs" 2249 | }, 2250 | "funding": { 2251 | "type": "opencollective", 2252 | "url": "https://opencollective.com/storybook" 2253 | }, 2254 | "peerDependencies": { 2255 | "prettier": "^2 || ^3" 2256 | }, 2257 | "peerDependenciesMeta": { 2258 | "prettier": { 2259 | "optional": true 2260 | } 2261 | } 2262 | }, 2263 | "node_modules/supports-color": { 2264 | "version": "7.2.0", 2265 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2266 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2267 | "dev": true, 2268 | "license": "MIT", 2269 | "dependencies": { 2270 | "has-flag": "^4.0.0" 2271 | }, 2272 | "engines": { 2273 | "node": ">=8" 2274 | } 2275 | }, 2276 | "node_modules/tiny-invariant": { 2277 | "version": "1.3.3", 2278 | "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", 2279 | "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", 2280 | "license": "MIT", 2281 | "peer": true 2282 | }, 2283 | "node_modules/tinybench": { 2284 | "version": "2.9.0", 2285 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", 2286 | "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", 2287 | "dev": true, 2288 | "license": "MIT" 2289 | }, 2290 | "node_modules/tinyexec": { 2291 | "version": "0.3.2", 2292 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", 2293 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", 2294 | "dev": true, 2295 | "license": "MIT" 2296 | }, 2297 | "node_modules/tinypool": { 2298 | "version": "1.0.2", 2299 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", 2300 | "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", 2301 | "dev": true, 2302 | "license": "MIT", 2303 | "engines": { 2304 | "node": "^18.0.0 || >=20.0.0" 2305 | } 2306 | }, 2307 | "node_modules/tinyrainbow": { 2308 | "version": "2.0.0", 2309 | "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", 2310 | "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", 2311 | "dev": true, 2312 | "license": "MIT", 2313 | "engines": { 2314 | "node": ">=14.0.0" 2315 | } 2316 | }, 2317 | "node_modules/tinyspy": { 2318 | "version": "3.0.2", 2319 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", 2320 | "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", 2321 | "dev": true, 2322 | "license": "MIT", 2323 | "engines": { 2324 | "node": ">=14.0.0" 2325 | } 2326 | }, 2327 | "node_modules/tslib": { 2328 | "version": "2.8.1", 2329 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 2330 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 2331 | "license": "0BSD", 2332 | "peer": true 2333 | }, 2334 | "node_modules/typescript": { 2335 | "version": "5.8.2", 2336 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 2337 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 2338 | "dev": true, 2339 | "license": "Apache-2.0", 2340 | "bin": { 2341 | "tsc": "bin/tsc", 2342 | "tsserver": "bin/tsserver" 2343 | }, 2344 | "engines": { 2345 | "node": ">=14.17" 2346 | } 2347 | }, 2348 | "node_modules/undici-types": { 2349 | "version": "6.20.0", 2350 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 2351 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 2352 | "dev": true, 2353 | "license": "MIT" 2354 | }, 2355 | "node_modules/util": { 2356 | "version": "0.12.5", 2357 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 2358 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 2359 | "license": "MIT", 2360 | "peer": true, 2361 | "dependencies": { 2362 | "inherits": "^2.0.3", 2363 | "is-arguments": "^1.0.4", 2364 | "is-generator-function": "^1.0.7", 2365 | "is-typed-array": "^1.1.3", 2366 | "which-typed-array": "^1.1.2" 2367 | } 2368 | }, 2369 | "node_modules/vite": { 2370 | "version": "6.2.5", 2371 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", 2372 | "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", 2373 | "dev": true, 2374 | "license": "MIT", 2375 | "dependencies": { 2376 | "esbuild": "^0.25.0", 2377 | "postcss": "^8.5.3", 2378 | "rollup": "^4.30.1" 2379 | }, 2380 | "bin": { 2381 | "vite": "bin/vite.js" 2382 | }, 2383 | "engines": { 2384 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2385 | }, 2386 | "funding": { 2387 | "url": "https://github.com/vitejs/vite?sponsor=1" 2388 | }, 2389 | "optionalDependencies": { 2390 | "fsevents": "~2.3.3" 2391 | }, 2392 | "peerDependencies": { 2393 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 2394 | "jiti": ">=1.21.0", 2395 | "less": "*", 2396 | "lightningcss": "^1.21.0", 2397 | "sass": "*", 2398 | "sass-embedded": "*", 2399 | "stylus": "*", 2400 | "sugarss": "*", 2401 | "terser": "^5.16.0", 2402 | "tsx": "^4.8.1", 2403 | "yaml": "^2.4.2" 2404 | }, 2405 | "peerDependenciesMeta": { 2406 | "@types/node": { 2407 | "optional": true 2408 | }, 2409 | "jiti": { 2410 | "optional": true 2411 | }, 2412 | "less": { 2413 | "optional": true 2414 | }, 2415 | "lightningcss": { 2416 | "optional": true 2417 | }, 2418 | "sass": { 2419 | "optional": true 2420 | }, 2421 | "sass-embedded": { 2422 | "optional": true 2423 | }, 2424 | "stylus": { 2425 | "optional": true 2426 | }, 2427 | "sugarss": { 2428 | "optional": true 2429 | }, 2430 | "terser": { 2431 | "optional": true 2432 | }, 2433 | "tsx": { 2434 | "optional": true 2435 | }, 2436 | "yaml": { 2437 | "optional": true 2438 | } 2439 | } 2440 | }, 2441 | "node_modules/vite-node": { 2442 | "version": "3.1.1", 2443 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz", 2444 | "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==", 2445 | "dev": true, 2446 | "license": "MIT", 2447 | "dependencies": { 2448 | "cac": "^6.7.14", 2449 | "debug": "^4.4.0", 2450 | "es-module-lexer": "^1.6.0", 2451 | "pathe": "^2.0.3", 2452 | "vite": "^5.0.0 || ^6.0.0" 2453 | }, 2454 | "bin": { 2455 | "vite-node": "vite-node.mjs" 2456 | }, 2457 | "engines": { 2458 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2459 | }, 2460 | "funding": { 2461 | "url": "https://opencollective.com/vitest" 2462 | } 2463 | }, 2464 | "node_modules/vitest": { 2465 | "version": "3.1.1", 2466 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz", 2467 | "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==", 2468 | "dev": true, 2469 | "license": "MIT", 2470 | "dependencies": { 2471 | "@vitest/expect": "3.1.1", 2472 | "@vitest/mocker": "3.1.1", 2473 | "@vitest/pretty-format": "^3.1.1", 2474 | "@vitest/runner": "3.1.1", 2475 | "@vitest/snapshot": "3.1.1", 2476 | "@vitest/spy": "3.1.1", 2477 | "@vitest/utils": "3.1.1", 2478 | "chai": "^5.2.0", 2479 | "debug": "^4.4.0", 2480 | "expect-type": "^1.2.0", 2481 | "magic-string": "^0.30.17", 2482 | "pathe": "^2.0.3", 2483 | "std-env": "^3.8.1", 2484 | "tinybench": "^2.9.0", 2485 | "tinyexec": "^0.3.2", 2486 | "tinypool": "^1.0.2", 2487 | "tinyrainbow": "^2.0.0", 2488 | "vite": "^5.0.0 || ^6.0.0", 2489 | "vite-node": "3.1.1", 2490 | "why-is-node-running": "^2.3.0" 2491 | }, 2492 | "bin": { 2493 | "vitest": "vitest.mjs" 2494 | }, 2495 | "engines": { 2496 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2497 | }, 2498 | "funding": { 2499 | "url": "https://opencollective.com/vitest" 2500 | }, 2501 | "peerDependencies": { 2502 | "@edge-runtime/vm": "*", 2503 | "@types/debug": "^4.1.12", 2504 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 2505 | "@vitest/browser": "3.1.1", 2506 | "@vitest/ui": "3.1.1", 2507 | "happy-dom": "*", 2508 | "jsdom": "*" 2509 | }, 2510 | "peerDependenciesMeta": { 2511 | "@edge-runtime/vm": { 2512 | "optional": true 2513 | }, 2514 | "@types/debug": { 2515 | "optional": true 2516 | }, 2517 | "@types/node": { 2518 | "optional": true 2519 | }, 2520 | "@vitest/browser": { 2521 | "optional": true 2522 | }, 2523 | "@vitest/ui": { 2524 | "optional": true 2525 | }, 2526 | "happy-dom": { 2527 | "optional": true 2528 | }, 2529 | "jsdom": { 2530 | "optional": true 2531 | } 2532 | } 2533 | }, 2534 | "node_modules/webidl-conversions": { 2535 | "version": "7.0.0", 2536 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 2537 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 2538 | "dev": true, 2539 | "license": "BSD-2-Clause", 2540 | "engines": { 2541 | "node": ">=12" 2542 | } 2543 | }, 2544 | "node_modules/whatwg-mimetype": { 2545 | "version": "3.0.0", 2546 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", 2547 | "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", 2548 | "dev": true, 2549 | "license": "MIT", 2550 | "engines": { 2551 | "node": ">=12" 2552 | } 2553 | }, 2554 | "node_modules/which-typed-array": { 2555 | "version": "1.1.19", 2556 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", 2557 | "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", 2558 | "license": "MIT", 2559 | "peer": true, 2560 | "dependencies": { 2561 | "available-typed-arrays": "^1.0.7", 2562 | "call-bind": "^1.0.8", 2563 | "call-bound": "^1.0.4", 2564 | "for-each": "^0.3.5", 2565 | "get-proto": "^1.0.1", 2566 | "gopd": "^1.2.0", 2567 | "has-tostringtag": "^1.0.2" 2568 | }, 2569 | "engines": { 2570 | "node": ">= 0.4" 2571 | }, 2572 | "funding": { 2573 | "url": "https://github.com/sponsors/ljharb" 2574 | } 2575 | }, 2576 | "node_modules/why-is-node-running": { 2577 | "version": "2.3.0", 2578 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", 2579 | "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", 2580 | "dev": true, 2581 | "license": "MIT", 2582 | "dependencies": { 2583 | "siginfo": "^2.0.0", 2584 | "stackback": "0.0.2" 2585 | }, 2586 | "bin": { 2587 | "why-is-node-running": "cli.js" 2588 | }, 2589 | "engines": { 2590 | "node": ">=8" 2591 | } 2592 | }, 2593 | "node_modules/ws": { 2594 | "version": "8.18.1", 2595 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", 2596 | "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", 2597 | "license": "MIT", 2598 | "peer": true, 2599 | "engines": { 2600 | "node": ">=10.0.0" 2601 | }, 2602 | "peerDependencies": { 2603 | "bufferutil": "^4.0.1", 2604 | "utf-8-validate": ">=5.0.2" 2605 | }, 2606 | "peerDependenciesMeta": { 2607 | "bufferutil": { 2608 | "optional": true 2609 | }, 2610 | "utf-8-validate": { 2611 | "optional": true 2612 | } 2613 | } 2614 | } 2615 | } 2616 | } 2617 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storybook-addon-code-editor", 3 | "version": "4.1.2", 4 | "description": "A Storybook add-on for live editing stories. Supports React and TypeScript.", 5 | "keywords": [ 6 | "storybook-addons", 7 | "code", 8 | "editor", 9 | "live", 10 | "real-time" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/JeremyRH/storybook-addon-code-editor" 15 | }, 16 | "author": "JeremyRH ", 17 | "license": "MIT", 18 | "type": "module", 19 | "exports": { 20 | ".": { 21 | "types": "./dist/es/index.d.ts", 22 | "import": "./dist/es/index.js", 23 | "require": "./dist/cjs/index.js" 24 | }, 25 | "./getStaticDirs": { 26 | "types": "./dist/es/getStaticDirs.d.ts", 27 | "import": "./dist/es/getStaticDirs.js", 28 | "require": "./dist/cjs/getStaticDirs.js" 29 | }, 30 | "./manager": "./dist/es/manager.js", 31 | "./package.json": "./package.json" 32 | }, 33 | "main": "dist/cjs/index.js", 34 | "module": "dist/es/index.js", 35 | "types": "dist/es/index.d.ts", 36 | "files": [ 37 | "dist", 38 | "manager.js" 39 | ], 40 | "scripts": { 41 | "build": "node scripts/rm.js dist && tsc --outDir dist/es && tsc --project tsconfig-cjs.json --outDir dist/cjs && node scripts/post-build.js", 42 | "format": "prettier src example/src --write", 43 | "start-example": "npm run build && cd example && npm i ../storybook-addon-code-editor-0.0.0.tgz && npm run storybook:dev", 44 | "build-example": "npm run build && cd example && npm i ../storybook-addon-code-editor-0.0.0.tgz && npm run storybook:build", 45 | "test": "vitest run" 46 | }, 47 | "dependencies": { 48 | "@babel/standalone": "^7.27.0", 49 | "@storybook/components": "^8.6.11", 50 | "@storybook/manager-api": "^8.6.11", 51 | "@storybook/types": "^8.6.11", 52 | "monaco-editor": "0.52.2" 53 | }, 54 | "peerDependencies": { 55 | "@types/react": "17.x.x || 18.x.x || 19.x.x", 56 | "react": "17.x.x || 18.x.x || 19.x.x" 57 | }, 58 | "peerDependenciesMeta": { 59 | "@types/react": { 60 | "optional": true 61 | } 62 | }, 63 | "devDependencies": { 64 | "@testing-library/dom": "^10.4.0", 65 | "@testing-library/react": "^16.2.0", 66 | "@types/node": "^22.13.14", 67 | "@types/react": "^18.3.16", 68 | "@types/react-dom": "^18.3.5", 69 | "happy-dom": "^17.4.4", 70 | "prettier": "^3.5.3", 71 | "react": "^18.3.1", 72 | "react-dom": "^18.3.1", 73 | "typescript": "^5.8.2", 74 | "vite": "^6.2.5", 75 | "vitest": "^3.1.1" 76 | }, 77 | "storybook": { 78 | "displayName": "Live Code Editor", 79 | "supportedFrameworks": [ 80 | "react" 81 | ], 82 | "icon": "https://raw.githubusercontent.com/jeremyrh/storybook-addon-code-editor/refs/heads/main/icon.png" 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /scripts/createChildProcess.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import { spawn } from 'node:child_process'; 4 | 5 | // Collect all child processes and kill them when this node process exits. 6 | const childProcesses = new Set(); 7 | process.on('exit', () => childProcesses.forEach((child) => child.kill())); 8 | 9 | export function createChildProcess(command, args, options = {}) { 10 | let resolve; 11 | let reject; 12 | const promise = new Promise((res, rej) => { 13 | resolve = res; 14 | reject = rej; 15 | }); 16 | 17 | const childP = spawn(command, args, options); 18 | 19 | childProcesses.add(childP); 20 | 21 | childP.once('error', (err) => { 22 | reject(err); 23 | }); 24 | 25 | childP.once('close', (code) => { 26 | childProcesses.delete(childP); 27 | if (code !== 0) { 28 | reject(new Error(`Command "${command} ${args.join(' ')}" exited with code ${code}`)); 29 | return; 30 | } 31 | resolve(); 32 | }); 33 | 34 | return { 35 | childProcess: childP, 36 | promise, 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /scripts/post-build.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import path from 'node:path'; 4 | import fs from 'node:fs'; 5 | import { createChildProcess } from './createChildProcess.js'; 6 | import pkgJson from '../package.json' with { type: 'json' }; 7 | 8 | const repoRoot = path.resolve(import.meta.dirname, '..'); 9 | 10 | function exec(command) { 11 | console.log(command); 12 | const [cmd, ...args] = command.split(' '); 13 | return createChildProcess(cmd, args, { stdio: 'inherit', cwd: repoRoot }).promise; 14 | } 15 | 16 | (async () => { 17 | // .js files that are commonjs need a package.json with type: "commonjs" 18 | await fs.promises.writeFile( 19 | path.join(repoRoot, 'dist', 'cjs', 'package.json'), 20 | '{ "type": "commonjs" }', 21 | ), 22 | 23 | // Create a .tgz file for the package to test it thoroughly in /example. 24 | // Set the version to 0.0.0 before packing, then set it back to the original version 25 | // to allow /example to always use the latest build of the package. 26 | await exec('npm pkg set version=0.0.0'); 27 | await exec('npm pack'); 28 | })().finally(() => exec(`npm pkg set version=${pkgJson.version}`)); 29 | -------------------------------------------------------------------------------- /scripts/rm.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import fs from 'node:fs'; 4 | import path from 'node:path'; 5 | 6 | const dirToDelete = path.resolve(process.argv[2]); 7 | 8 | fs.promises.rm(dirToDelete, { recursive: true, force: true }); 9 | -------------------------------------------------------------------------------- /src/Editor/Editor.tsx: -------------------------------------------------------------------------------- 1 | import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api'; 2 | import * as React from 'react'; 3 | import { getMonacoOverflowContainer } from './getMonacoOverflowContainer'; 4 | import { monacoLoader } from './monacoLoader'; 5 | import { reactTypesLoader } from './reactTypesLoader'; 6 | import { getMonacoSetup } from './setupMonaco'; 7 | 8 | let monacoPromise: Promise | undefined; 9 | 10 | export type EditorOptions = Monaco.editor.IEditorOptions; 11 | 12 | function loadMonacoEditor() { 13 | const monacoSetup = getMonacoSetup(); 14 | 15 | window.MonacoEnvironment = monacoSetup.monacoEnvironment; 16 | 17 | return (monacoPromise ||= Promise.all([monacoLoader(), reactTypesLoader()]).then( 18 | ([monaco, reactTypes]) => { 19 | monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ 20 | jsx: monaco.languages.typescript.JsxEmit.Preserve, 21 | }); 22 | monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ 23 | noSemanticValidation: true, 24 | noSyntaxValidation: false, 25 | }); 26 | 27 | reactTypes.forEach(([packageName, dTsFile]) => { 28 | const pName = packageName.replace('@types/', ''); 29 | monaco.languages.typescript.typescriptDefaults.addExtraLib( 30 | dTsFile, 31 | `file:///node_modules/${pName}`, 32 | ); 33 | }); 34 | 35 | monacoSetup.onMonacoLoad?.(monaco); 36 | 37 | return monaco; 38 | }, 39 | )); 40 | } 41 | 42 | let fileCount = 1; 43 | 44 | function createEditor( 45 | monaco: typeof Monaco, 46 | code: string, 47 | container: HTMLElement, 48 | defaultEditorOptions?: EditorOptions, 49 | ) { 50 | const uri = monaco.Uri.parse(`file:///index${fileCount++}.tsx`); 51 | 52 | return monaco.editor.create(container, { 53 | automaticLayout: true, 54 | fixedOverflowWidgets: true, 55 | model: monaco.editor.createModel(code, 'typescript', uri), 56 | overflowWidgetsDomNode: getMonacoOverflowContainer('monacoOverflowContainer'), 57 | tabSize: 2, 58 | ...defaultEditorOptions, 59 | }); 60 | } 61 | 62 | interface EditorProps { 63 | onInput: (value: string) => any; 64 | value: string; 65 | modifyEditor?: (monaco: typeof Monaco, editor: Monaco.editor.IStandaloneCodeEditor) => any; 66 | parentSize?: string; 67 | defaultEditorOptions?: EditorOptions; 68 | } 69 | 70 | interface EditorState { 71 | onInput: EditorProps['onInput']; 72 | editor?: Monaco.editor.IStandaloneCodeEditor; 73 | editorContainer?: HTMLDivElement; 74 | monaco?: typeof Monaco; 75 | } 76 | 77 | export default function Editor(props: EditorProps) { 78 | const stateRef = React.useRef({ onInput: props.onInput }).current; 79 | const [_, forceUpdate] = React.useReducer((n) => n + 1, 0); 80 | let resolveContainer: (...args: any[]) => any = () => {}; 81 | 82 | React.useState(() => { 83 | const containerPromise = new Promise((resolve) => { 84 | resolveContainer = resolve; 85 | }); 86 | 87 | Promise.all([containerPromise, loadMonacoEditor()]).then(([editorContainer, monaco]) => { 88 | stateRef.monaco = monaco; 89 | stateRef.editor = createEditor( 90 | monaco, 91 | props.value, 92 | editorContainer, 93 | props.defaultEditorOptions, 94 | ); 95 | 96 | stateRef.editor.onDidChangeModelContent(() => { 97 | const currentValue = stateRef.editor?.getValue(); 98 | if (typeof currentValue === 'string') { 99 | stateRef.onInput(currentValue); 100 | } 101 | }); 102 | 103 | forceUpdate(); 104 | }); 105 | }); 106 | 107 | React.useLayoutEffect(() => { 108 | stateRef.onInput = props.onInput; 109 | }, [props.onInput]); 110 | 111 | React.useEffect(() => { 112 | if (stateRef.editor && stateRef.editor.getValue() !== props.value) { 113 | stateRef.editor.setValue(props.value); 114 | } 115 | }, [props.value]); 116 | 117 | React.useEffect(() => { 118 | if (stateRef.monaco && stateRef.editor) { 119 | props.modifyEditor?.(stateRef.monaco, stateRef.editor); 120 | } 121 | }, [stateRef.monaco, props.modifyEditor]); 122 | 123 | React.useEffect(() => { 124 | return () => { 125 | stateRef.editor?.dispose(); 126 | stateRef.editor = undefined; 127 | }; 128 | }, []); 129 | 130 | return ( 131 |
{ 133 | if (props.parentSize) { 134 | const parent = container?.parentElement; 135 | if (parent) { 136 | parent.style.height = props.parentSize; 137 | } 138 | } 139 | stateRef.editorContainer = container || undefined; 140 | resolveContainer(container); 141 | }} 142 | style={{ height: '100%' }} 143 | className="sb-unstyled" 144 | /> 145 | ); 146 | } 147 | -------------------------------------------------------------------------------- /src/Editor/getMonacoOverflowContainer.ts: -------------------------------------------------------------------------------- 1 | export function getMonacoOverflowContainer(id: string) { 2 | let container = document.getElementById(id); 3 | 4 | if (container) { 5 | return container; 6 | } 7 | 8 | container = document.createElement('div'); 9 | container.id = id; 10 | container.classList.add('monaco-editor', 'sb-unstyled'); 11 | 12 | document.body.appendChild(container); 13 | 14 | return container; 15 | } 16 | -------------------------------------------------------------------------------- /src/Editor/monacoLoader.ts: -------------------------------------------------------------------------------- 1 | import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api'; 2 | 3 | function injectScript(url: string) { 4 | return new Promise((resolve, reject) => { 5 | const script = document.createElement('script'); 6 | script.src = url; 7 | script.defer = true; 8 | script.onload = resolve; 9 | script.onerror = reject; 10 | document.head.append(script); 11 | }); 12 | } 13 | 14 | export function monacoLoader(): Promise { 15 | const relativeLoaderScriptPath = 'monaco-editor/min/vs/loader.js'; 16 | return injectScript(relativeLoaderScriptPath).then((e) => { 17 | const loaderScriptSrc: string = (e.target as any)?.src || window.location.origin + '/'; 18 | const baseUrl = loaderScriptSrc.replace(relativeLoaderScriptPath, ''); 19 | return new Promise((resolve) => { 20 | (window as any).require.config({ paths: { vs: `${baseUrl}monaco-editor/min/vs` } }); 21 | (window as any).require(['vs/editor/editor.main'], resolve); 22 | }); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /src/Editor/reactTypesLoader.ts: -------------------------------------------------------------------------------- 1 | export function reactTypesLoader() { 2 | const typeLibs = ['@types/react/index.d.ts', '@types/react/jsx-runtime.d.ts']; 3 | 4 | return Promise.all( 5 | typeLibs.map((typeLib) => { 6 | return fetch(typeLib, { headers: { accept: 'text/plain' } }).then( 7 | async (resp) => [typeLib, await resp.text()], 8 | () => {}, 9 | ); 10 | }), 11 | ).then((typeLibs) => { 12 | return typeLibs.filter((l) => Array.isArray(l)); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /src/Editor/setupMonaco.ts: -------------------------------------------------------------------------------- 1 | import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api'; 2 | import { createStore } from '../createStore'; 3 | 4 | interface MonacoSetup { 5 | monacoEnvironment?: Monaco.Environment; 6 | onMonacoLoad?: (monaco: typeof Monaco) => any; 7 | } 8 | 9 | const store = createStore(); 10 | 11 | export function setupMonaco(options: MonacoSetup) { 12 | store.setValue('monacoSetup', options); 13 | } 14 | 15 | export function getMonacoSetup() { 16 | return store.getValue('monacoSetup') || {}; 17 | } 18 | -------------------------------------------------------------------------------- /src/ErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | interface ErrorBoundaryProps { 4 | resetRef: React.MutableRefObject<(() => void) | undefined>; 5 | children: React.ReactNode; 6 | } 7 | 8 | export const errorStyle = { 9 | backgroundColor: '#f8d7da', 10 | borderRadius: '5px', 11 | color: '#721c24', 12 | fontFamily: 'monospace', 13 | margin: '0', 14 | padding: '20px', 15 | }; 16 | 17 | class ErrorBoundary extends React.Component { 18 | state = { error: undefined }; 19 | 20 | constructor(props: ErrorBoundaryProps) { 21 | super(props); 22 | this.props.resetRef.current = this.setState.bind(this, this.state); 23 | } 24 | 25 | static getDerivedStateFromError(error: unknown) { 26 | return { error }; 27 | } 28 | 29 | render() { 30 | if (this.state.error) { 31 | return
{String(this.state.error)}
; 32 | } 33 | 34 | return this.props.children; 35 | } 36 | } 37 | 38 | export default ErrorBoundary; 39 | -------------------------------------------------------------------------------- /src/Preview.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { EsModules, evalModule } from './evalModule'; 3 | import { errorStyle } from './ErrorBoundary'; 4 | 5 | interface PreviewProps { 6 | availableImports: EsModules; 7 | code: string; 8 | componentProps?: any; 9 | } 10 | 11 | export default function Preview({ availableImports, code, componentProps }: PreviewProps) { 12 | let DefaultExport: any; 13 | 14 | try { 15 | DefaultExport = code ? evalModule(code, availableImports).default : undefined; 16 | const isObject = DefaultExport && typeof DefaultExport === 'object'; 17 | const isFunction = typeof DefaultExport === 'function'; 18 | if (!isObject && !isFunction) { 19 | throw new TypeError('Default export is not a React component'); 20 | } 21 | } catch (error) { 22 | return
{String(error)}
; 23 | } 24 | 25 | return ; 26 | } 27 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const paramId = 'liveCodeEditor'; 2 | export const addonId = 'liveCodeEditorAddon'; 3 | export const panelId = 'liveCodeEditorPanel'; 4 | -------------------------------------------------------------------------------- /src/createStore.ts: -------------------------------------------------------------------------------- 1 | // This provides shared state and the ability to subscribe to changes 2 | // between the manager and preview iframes. 3 | // Attempted to use Storybook's `addons.getChannel()` but it doesn't emit 4 | // across iframes. 5 | 6 | type Callback = (newValue: T) => any; 7 | 8 | interface Store { 9 | onChange(callback: Callback): () => void; 10 | getValue(): T | undefined; 11 | setValue(newValue: T): void; 12 | } 13 | 14 | function newStore(initialValue?: T): Store { 15 | const callbacks = new Set>(); 16 | let value = initialValue; 17 | 18 | return { 19 | onChange(callback) { 20 | callbacks.add(callback); 21 | return () => { 22 | callbacks.delete(callback); 23 | }; 24 | }, 25 | getValue: () => value, 26 | setValue(newValue) { 27 | value = newValue; 28 | callbacks.forEach((callback) => { 29 | try { 30 | callback(newValue); 31 | } catch (error) { 32 | console.error(error); 33 | } 34 | }); 35 | }, 36 | }; 37 | } 38 | 39 | interface KeyStore { 40 | onChange(key: string, callback: Callback): () => void; 41 | getValue(key: string): T | undefined; 42 | setValue(key: string, newValue: T): void; 43 | } 44 | 45 | function newKeyStore(): KeyStore { 46 | const stores: Record> = {}; 47 | 48 | return { 49 | onChange: (key, callback) => (stores[key] ||= newStore()).onChange(callback), 50 | getValue: (key) => (stores[key] ||= newStore()).getValue(), 51 | setValue: (key, newValue) => (stores[key] ||= newStore()).setValue(newValue), 52 | }; 53 | } 54 | 55 | export function createStore(): KeyStore { 56 | const getStore = (managerWindow: any) => 57 | (managerWindow._addon_code_editor_store ||= newKeyStore()); 58 | try { 59 | // This will throw in the manager if the storybook site is in an iframe. 60 | return getStore(window.parent); 61 | } catch { 62 | return getStore(window); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/declarations.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@babel/standalone'; 2 | -------------------------------------------------------------------------------- /src/evalModule.ts: -------------------------------------------------------------------------------- 1 | import { transform } from '@babel/standalone'; 2 | 3 | export type EsModules = Record>; 4 | 5 | export function evalModule( 6 | moduleCode: string, 7 | availableImports: EsModules, 8 | ): Record { 9 | const { code } = transform(moduleCode, { 10 | filename: 'index.tsx', 11 | presets: ['typescript', 'react'], 12 | plugins: ['transform-modules-commonjs'], 13 | }); 14 | const setExports = new Function('require', 'exports', code); 15 | const require = (moduleId: string) => { 16 | const module = availableImports[moduleId]; 17 | if (!module) { 18 | throw new TypeError(`Failed to resolve module specifier "${moduleId}"`); 19 | } 20 | return module; 21 | }; 22 | const exports = {}; 23 | 24 | setExports(require, exports); 25 | 26 | return exports; 27 | } 28 | -------------------------------------------------------------------------------- /src/getStaticDirs.ts: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'node:module'; 2 | import path from 'node:path'; 3 | 4 | // Why not use `__filename` or `import.meta.filename`? Because this file gets compiled to both 5 | // CommonJS and ES module. `import.meta.filename` is a syntax error in CommonJS and `__filename` 6 | // is not available in ES modules. We can't use `import.meta.url` at all so we need a workaround. 7 | function getFileNameFromStack() { 8 | const isWindows = process.platform === 'win32'; 9 | const fullPathRegex = isWindows 10 | ? /[a-zA-Z]:\\.*\\getStaticDirs\.[cm]?js/ 11 | : /\/.*\/getStaticDirs\.[cm]?js/; 12 | const match = fullPathRegex.exec(new Error().stack || ''); 13 | if (!match) { 14 | throw new Error('Could not get the file path of storybook-addon-code-editor/getStaticDirs'); 15 | } 16 | return match[0]; 17 | } 18 | 19 | const filename = typeof __filename === 'string' ? __filename : getFileNameFromStack(); 20 | 21 | function resolve(reqFn: NodeRequire, packageName: string) { 22 | try { 23 | return reqFn.resolve(`${packageName}/package.json`); 24 | } catch (err) { 25 | return reqFn.resolve(packageName); 26 | } 27 | } 28 | 29 | function resolvePackagePath(reqFn: NodeRequire, packageName: string) { 30 | let error: Error | undefined; 31 | let result: string | undefined; 32 | try { 33 | const packageEntryFile = resolve(reqFn, packageName); 34 | const namePosition = packageEntryFile.indexOf(`${path.sep}${packageName}${path.sep}`); 35 | if (namePosition === -1) { 36 | error = new Error( 37 | `Cannot resolve package path for: '${packageName}'.\nEntry file: ${packageEntryFile}`, 38 | ); 39 | } else { 40 | result = `${packageEntryFile.slice(0, namePosition)}${path.sep}${packageName}${path.sep}`; 41 | } 42 | } catch (err: any) { 43 | // Sometimes the require function can't find the entry file but knows the path. 44 | result = 45 | /Source path: (.+)/.exec(err?.message)?.[1] || 46 | /main defined in (.+?)[\\/]package\.json/.exec(err?.message)?.[1]; 47 | if (!result) { 48 | error = err; 49 | } 50 | } 51 | if (result) { 52 | return result; 53 | } 54 | throw error; 55 | } 56 | 57 | export function getExtraStaticDir(specifier: string, relativeToFile = filename) { 58 | const specifierParts = specifier.split('/'); 59 | const isScopedPackage = specifier.startsWith('@') && !!specifierParts[1]; 60 | const pathParts = isScopedPackage ? specifierParts.slice(2) : specifierParts.slice(1); 61 | const packageName = isScopedPackage 62 | ? `${specifierParts[0]}/${specifierParts[1]}` 63 | : specifierParts[0]; 64 | const require = createRequire(relativeToFile); 65 | const packageDir = resolvePackagePath(require, packageName); 66 | 67 | return { 68 | from: path.join(packageDir, ...pathParts), 69 | to: specifier, 70 | }; 71 | } 72 | 73 | function tryGetStaticDir(packageName: string, relativeToFile?: string) { 74 | try { 75 | return getExtraStaticDir(packageName, relativeToFile); 76 | } catch (err) {} 77 | } 78 | 79 | export function getCodeEditorStaticDirs(relativeToFile?: string) { 80 | const result = [getExtraStaticDir('monaco-editor/min', filename)]; 81 | const reactTypesDir = tryGetStaticDir('@types/react', relativeToFile); 82 | if (reactTypesDir) { 83 | result.push(reactTypesDir); 84 | } 85 | return result; 86 | } 87 | -------------------------------------------------------------------------------- /src/index.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import * as React from 'react'; 3 | import { afterEach, describe, expect, test } from 'vitest'; 4 | import { createStore } from './createStore'; 5 | import { getCodeEditorStaticDirs, getExtraStaticDir } from './getStaticDirs'; 6 | import { makeLiveEditStory, Playground, setupMonaco, type StoryState } from './index'; 7 | 8 | type StorybookStory = { 9 | render: (...args: any[]) => React.ReactNode; 10 | parameters: { 11 | liveCodeEditor: { 12 | disable: boolean; 13 | id: string; 14 | }; 15 | }; 16 | [key: string]: unknown; 17 | }; 18 | 19 | const originalConsoleError = console.error; 20 | 21 | afterEach(() => { 22 | // Some tests silence console.error to quiet logs. 23 | console.error = originalConsoleError; 24 | document.body.innerHTML = ''; 25 | }); 26 | 27 | describe('makeLiveEditStory', () => { 28 | test('is a function', () => { 29 | expect(typeof makeLiveEditStory).toBe('function'); 30 | }); 31 | 32 | test('renders error', async () => { 33 | const Story = {} as StorybookStory; 34 | makeLiveEditStory(Story, { code: '' }); 35 | 36 | render(Story.render()); 37 | 38 | await screen.findByText('TypeError: Default export is not a React component'); 39 | }); 40 | 41 | test("renders eval'd code", async () => { 42 | const Story = {} as StorybookStory; 43 | makeLiveEditStory(Story, { code: 'export default () =>
Hello
' }); 44 | 45 | render(Story.render()); 46 | 47 | await screen.findByText('Hello'); 48 | }); 49 | 50 | test('allows import React', async () => { 51 | const Story = {} as StorybookStory; 52 | makeLiveEditStory(Story, { 53 | code: `import React from 'react'; 54 | export default () =>
Hello
;`, 55 | }); 56 | 57 | render(Story.render()); 58 | 59 | await screen.findByText('Hello'); 60 | }); 61 | 62 | test('allows import * as React', async () => { 63 | const Story = {} as StorybookStory; 64 | makeLiveEditStory(Story, { 65 | code: `import * as React from 'react'; 66 | export default () =>
Hello
;`, 67 | }); 68 | 69 | render(Story.render()); 70 | 71 | await screen.findByText('Hello'); 72 | }); 73 | 74 | test("allows import { named } from 'react'", async () => { 75 | const Story = {} as StorybookStory; 76 | makeLiveEditStory(Story, { 77 | code: `import { useState } from 'react'; 78 | export default () =>
Hello
;`, 79 | }); 80 | 81 | render(Story.render()); 82 | 83 | await screen.findByText('Hello'); 84 | }); 85 | 86 | test("allows import React, { named } from 'react'", async () => { 87 | const Story = {} as StorybookStory; 88 | makeLiveEditStory(Story, { 89 | code: `import React, { useState } from 'react'; 90 | export default () =>
Hello
;`, 91 | }); 92 | 93 | render(Story.render()); 94 | 95 | await screen.findByText('Hello'); 96 | }); 97 | 98 | test('adds available imports', async () => { 99 | const Story = {} as StorybookStory; 100 | makeLiveEditStory(Story, { 101 | availableImports: { a: { b: 'c' } }, 102 | code: `import { b } from 'a'; 103 | export default () =>
{b}
;`, 104 | }); 105 | 106 | render(Story.render()); 107 | 108 | await screen.findByText('c'); 109 | }); 110 | 111 | test('passes props to evaluated component', async () => { 112 | const Story = {} as StorybookStory; 113 | makeLiveEditStory(Story, { code: 'export default (props) =>
{props.a}
;' }); 114 | 115 | render(Story.render({ a: 'b' })); 116 | 117 | await screen.findByText('b'); 118 | }); 119 | 120 | test('recovers from syntax errors', async () => { 121 | const Story = {} as StorybookStory; 122 | makeLiveEditStory(Story, { code: '] this is not valid code [' }); 123 | 124 | render(Story.render()); 125 | 126 | await screen.findByText('SyntaxError', { exact: false }); 127 | 128 | createStore().setValue(Story.parameters.liveCodeEditor.id, { 129 | code: 'export default () =>
Hello
', 130 | }); 131 | 132 | await screen.findByText('Hello'); 133 | }); 134 | 135 | test('recovers from runtime errors', async () => { 136 | const Story = {} as StorybookStory; 137 | makeLiveEditStory(Story, { code: 'window.thisIsNot.defined' }); 138 | 139 | render(Story.render()); 140 | 141 | await screen.findByText("TypeError: Cannot read properties of undefined (reading 'defined')"); 142 | 143 | createStore().setValue(Story.parameters.liveCodeEditor.id, { 144 | code: 'export default () =>
Hello
', 145 | }); 146 | 147 | await screen.findByText('Hello'); 148 | }); 149 | 150 | test('recovers from runtime errors in the default export function', async () => { 151 | // React's error boundaries use console.error and make this test noisy. 152 | console.error = () => {}; 153 | 154 | const Story = {} as StorybookStory; 155 | makeLiveEditStory(Story, { 156 | code: 'export default () =>
{window.thisIsNot.defined}
', 157 | }); 158 | 159 | render(Story.render()); 160 | 161 | await screen.findByText("TypeError: Cannot read properties of undefined (reading 'defined')"); 162 | 163 | createStore().setValue(Story.parameters.liveCodeEditor.id, { 164 | code: 'export default () =>
Hello
', 165 | }); 166 | 167 | await screen.findByText('Hello'); 168 | }); 169 | }); 170 | 171 | describe('Playground', () => { 172 | test('is a function', () => { 173 | expect(typeof Playground).toBe('function'); 174 | }); 175 | }); 176 | 177 | describe('setupMonaco', () => { 178 | test('is a function', () => { 179 | expect(typeof setupMonaco).toBe('function'); 180 | }); 181 | }); 182 | 183 | describe('getCodeEditorStaticDirs', () => { 184 | test('is a function', () => { 185 | expect(typeof getCodeEditorStaticDirs).toBe('function'); 186 | }); 187 | 188 | test('returns an array of objects', () => { 189 | const result = getCodeEditorStaticDirs(); 190 | expect(Array.isArray(result)).toBe(true); 191 | expect(typeof result[0].to).toBe('string'); 192 | expect(typeof result[0].from).toBe('string'); 193 | }); 194 | }); 195 | 196 | describe('getExtraStaticDir', () => { 197 | test('is a function', () => { 198 | expect(typeof getExtraStaticDir).toBe('function'); 199 | }); 200 | 201 | test('returns an object', () => { 202 | const result = getExtraStaticDir('typescript'); 203 | expect(typeof result.to).toBe('string'); 204 | expect(typeof result.from).toBe('string'); 205 | }); 206 | }); 207 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { createStore } from './createStore'; 3 | import Editor, { EditorOptions } from './Editor/Editor'; 4 | import ErrorBoundary from './ErrorBoundary'; 5 | import Preview from './Preview'; 6 | export { setupMonaco } from './Editor/setupMonaco'; 7 | 8 | export interface StoryState { 9 | code: string; 10 | availableImports?: Record>; 11 | modifyEditor?: React.ComponentProps['modifyEditor']; 12 | defaultEditorOptions?: EditorOptions; 13 | } 14 | 15 | const store = createStore(); 16 | const hasReactRegex = /import\s+(\*\s+as\s+)?React[,\s]/; 17 | const noop = () => {}; 18 | 19 | function LivePreview({ storyId, storyArgs }: { storyId: string; storyArgs?: any }) { 20 | const [state, setState] = React.useState(store.getValue(storyId)); 21 | const errorBoundaryResetRef = React.useRef(noop); 22 | const fullCode = hasReactRegex.test(state!.code) 23 | ? state!.code 24 | : "import * as React from 'react';" + state!.code; 25 | 26 | React.useEffect(() => { 27 | return store.onChange(storyId, (newState) => { 28 | setState(newState); 29 | errorBoundaryResetRef.current(); 30 | }); 31 | }, [storyId]); 32 | 33 | return ( 34 | 35 | 40 | 41 | ); 42 | } 43 | 44 | type AnyFn = (...args: any[]) => unknown; 45 | 46 | // Only define the types from Storybook that are used in makeLiveEditStory. 47 | // This allows us to support multiple versions of Storybook. 48 | type MinimalStoryObj = { 49 | tags?: string[]; 50 | parameters?: { 51 | liveCodeEditor?: { 52 | disable: boolean; 53 | id: string; 54 | }; 55 | docs?: { 56 | source?: Record; 57 | [k: string]: any; 58 | }; 59 | [k: string]: any; 60 | }; 61 | render?: AnyFn; 62 | [k: string]: any; 63 | }; 64 | 65 | // A story can be a function or an object. 66 | type MinimalStory = MinimalStoryObj | (AnyFn & MinimalStoryObj); 67 | 68 | /** 69 | * Returns a story with live editing capabilities. 70 | * 71 | * @deprecated Use the {@link makeLiveEditStory} function instead. 72 | */ 73 | export function createLiveEditStory({ 74 | code, 75 | availableImports, 76 | modifyEditor, 77 | defaultEditorOptions, 78 | ...storyOptions 79 | }: StoryState & T) { 80 | const id = `id_${Math.random()}`; 81 | 82 | store.setValue(id, { code, availableImports, modifyEditor, defaultEditorOptions }); 83 | 84 | return { 85 | ...storyOptions, 86 | parameters: { 87 | ...storyOptions.parameters, 88 | liveCodeEditor: { disable: false, id }, 89 | docs: { 90 | ...storyOptions.parameters?.docs, 91 | source: { 92 | ...storyOptions.parameters?.docs?.source, 93 | transform: (code: string) => store.getValue(id)?.code ?? code, 94 | }, 95 | }, 96 | }, 97 | render: (props: any) => , 98 | } as unknown as T; 99 | } 100 | 101 | /** 102 | * Modifies a story to include a live code editor addon panel. 103 | */ 104 | export function makeLiveEditStory( 105 | story: T, 106 | { code, availableImports, modifyEditor, defaultEditorOptions }: StoryState, 107 | ): void { 108 | const id = `id_${Math.random()}`; 109 | 110 | store.setValue(id, { code, availableImports, modifyEditor, defaultEditorOptions }); 111 | 112 | story.parameters = { 113 | ...story.parameters, 114 | liveCodeEditor: { disable: false, id }, 115 | docs: { 116 | ...story.parameters?.docs, 117 | source: { 118 | ...story.parameters?.docs?.source, 119 | transform: (code: string) => store.getValue(id)?.code ?? code, 120 | }, 121 | }, 122 | }; 123 | 124 | story.render = (props: any) => ; 125 | } 126 | 127 | const savedCode: Record = {}; 128 | 129 | /** 130 | * React component containing a live code editor and preview. 131 | */ 132 | export function Playground({ 133 | availableImports, 134 | code, 135 | height = '200px', 136 | id, 137 | Container, 138 | ...editorProps 139 | }: Partial & { 140 | height?: string; 141 | id?: string; 142 | Container?: React.ComponentType<{ editor: React.ReactNode; preview: React.ReactNode }>; 143 | }) { 144 | let initialCode = code ?? ''; 145 | if (id !== undefined) { 146 | savedCode[id] ??= initialCode; 147 | initialCode = savedCode[id]; 148 | } 149 | const [currentCode, setCurrentCode] = React.useState(initialCode); 150 | const errorBoundaryResetRef = React.useRef(noop); 151 | const fullCode = hasReactRegex.test(currentCode) 152 | ? currentCode 153 | : "import * as React from 'react';" + currentCode; 154 | 155 | const editor = ( 156 | { 159 | if (id !== undefined) { 160 | savedCode[id] = newCode; 161 | } 162 | setCurrentCode(newCode); 163 | errorBoundaryResetRef.current(); 164 | }} 165 | value={currentCode} 166 | /> 167 | ); 168 | 169 | const preview = ( 170 | 171 | 172 | 173 | ); 174 | 175 | return Container ? ( 176 | 177 | ) : ( 178 |
179 |
180 | {preview} 181 |
182 |
183 | {editor} 184 |
185 |
186 | ); 187 | } 188 | -------------------------------------------------------------------------------- /src/manager.tsx: -------------------------------------------------------------------------------- 1 | import { addons, types } from '@storybook/manager-api'; 2 | import { AddonPanel } from '@storybook/components'; 3 | import * as React from 'react'; 4 | import { addonId, panelId, paramId } from './constants'; 5 | import { createStore } from './createStore'; 6 | import Editor from './Editor/Editor'; 7 | import type { StoryState } from './index'; 8 | 9 | const store = createStore(); 10 | 11 | addons.register(addonId, (api) => { 12 | const getCodeEditorStoryId = (): string | undefined => 13 | (api.getCurrentStoryData()?.parameters as any)?.liveCodeEditor?.id; 14 | 15 | addons.add(panelId, { 16 | id: addonId, 17 | title: 'Live code editor', 18 | type: types.PANEL, 19 | disabled: () => !getCodeEditorStoryId(), 20 | render({ active }) { 21 | const storyId = getCodeEditorStoryId(); 22 | 23 | if (!active || !storyId) { 24 | return null; 25 | } 26 | 27 | const storyState = store.getValue(storyId)!; 28 | 29 | return ( 30 | 31 | { 34 | store.setValue(storyId, { ...storyState, code: newCode }); 35 | }} 36 | value={storyState.code} 37 | parentSize="100%" 38 | /> 39 | 40 | ); 41 | }, 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tsconfig-cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "moduleResolution": "Node10" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "isolatedModules": true, 8 | "jsx": "react", 9 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 10 | "module": "Preserve", 11 | "moduleResolution": "Bundler", 12 | "noEmitOnError": true, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true, 15 | "strict": true, 16 | "target": "ES2023" 17 | }, 18 | "include": ["src"], 19 | "exclude": ["src/**/*.test.*"] 20 | } 21 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: 'happy-dom', 6 | }, 7 | }) 8 | --------------------------------------------------------------------------------