├── .nvmrc ├── .gitignore ├── vite ├── scss │ ├── style.ts │ └── styles │ │ └── style.scss ├── plugins │ ├── index.ts │ └── CopyFilePlugin.ts ├── ts │ ├── components │ │ └── HelloWorld.ts │ └── index.ts ├── package.json ├── vite.config.ts └── package-lock.json ├── manifest.json ├── screenshot.png ├── index.php ├── style.css ├── functions.php ├── LICENSE ├── inc └── hmr.php └── README.md /.nvmrc: -------------------------------------------------------------------------------- 1 | v18.14.2 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules -------------------------------------------------------------------------------- /vite/scss/style.ts: -------------------------------------------------------------------------------- 1 | import './styles/style.scss'; -------------------------------------------------------------------------------- /vite/scss/styles/style.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background: blue; 3 | } -------------------------------------------------------------------------------- /vite/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export { CopyFilePlugin } from './CopyFilePlugin'; -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | {"index":"/dist/js/index-7726082b.js","style.css":"/dist/style/style-a8a337e4.css"} -------------------------------------------------------------------------------- /vite/ts/components/HelloWorld.ts: -------------------------------------------------------------------------------- 1 | export default () => { 2 | console.log('Hello World'); 3 | } -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/milesaylward/wp-theme-vite-template/HEAD/screenshot.png -------------------------------------------------------------------------------- /vite/ts/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import HelloWorld from './components/HelloWorld'; 3 | // @ts-expect-error 4 | const $ = jQuery; 5 | 6 | $(document).ready(() => { 7 | HelloWorld(); 8 | }); 9 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 10 |
11 | -------------------------------------------------------------------------------- /vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "start": "npm run dev", 9 | "build": "vite build", 10 | "preview": "vite preview" 11 | }, 12 | "devDependencies": { 13 | "sass": "^1.64.1", 14 | "typescript": "^5.0.2", 15 | "vite": "^4.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: Wp Theme Vite Template 3 | Theme URI: https://github.com/milesaylward/wp-theme-vite-template.git 4 | Description: An example on using Vite to compile Typescript & SCSS to create a custom wordpress theme. 5 | Author: Miles Aylward 6 | Author URI: https://github.com/milesaylward/ 7 | Version: 1.0.0 8 | Text Domain: wp-theme-vite-template 9 | License: MIT 10 | License URI: https://choosealicense.com/licenses/mit/ 11 | */ 12 | 13 | /* Add your custom styles here */ 14 | -------------------------------------------------------------------------------- /vite/plugins/CopyFilePlugin.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { resolve as resolvePath, dirname } from 'path'; 3 | 4 | import { Plugin } from 'vite'; 5 | 6 | export const CopyFilePlugin = ({ 7 | sourceFileName, 8 | absolutePathToDestination, 9 | }: { 10 | sourceFileName: string; 11 | absolutePathToDestination: string; 12 | }): Plugin => ({ 13 | name: 'copy-file-plugin', 14 | writeBundle: async (options: any, bundle) => { 15 | const fileToCopy = Object.values(bundle).find(({ name }) => name === sourceFileName); 16 | if (!fileToCopy) return; 17 | 18 | const sourcePath = resolvePath(options.dir, fileToCopy.fileName); 19 | 20 | await fs.promises.mkdir(dirname(absolutePathToDestination), { recursive: true }); 21 | await fs.promises.copyFile(sourcePath, `${absolutePathToDestination}/${fileToCopy.fileName.replace('assets/', '')}`); 22 | }, 23 | }); -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | $indexJS, array('jquery'), null); 21 | wp_enqueue_style($indexCSS, get_stylesheet_directory_uri() . $GLOBALS['manifest']->$indexCSS, array(), null); 22 | } 23 | } 24 | 25 | add_action('wp_enqueue_scripts', 'enqueue_scripts_styles', 20); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Miles Aylward 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 | -------------------------------------------------------------------------------- /inc/hmr.php: -------------------------------------------------------------------------------- 1 | ', 22 | esc_url($src) 23 | ); 24 | } 25 | return $tag; 26 | }, 10, 3 27 | ); 28 | } 29 | 30 | if (!isViteHMRAvailable()) { 31 | return; 32 | } 33 | 34 | add_filter('stylesheet_uri', function () { return getViteDevServerAddress().'/sass/styles/style.scss'; } ); 35 | 36 | const VITE_HMR_CLIENT_HANDLE = 'vite-client'; 37 | function loadScript() { 38 | wp_enqueue_script(VITE_HMR_CLIENT_HANDLE, getViteDevServerAddress().'/@vite/client', array(), null); 39 | loadJSScriptAsESModule(VITE_HMR_CLIENT_HANDLE); 40 | } 41 | add_action('wp_enqueue_scripts', 'loadScript'); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wp Theme Vite Template 2 | 3 | An example on using Vite to compile Typescript & SCSS to create a custom Wordpress theme. 4 | 5 | ## Installation 6 | Clone the project into the themes folder of your WP instance. 7 | ```bash 8 | cd wp-theme-vite-template 9 | ``` 10 | Suggested Node version > 18. 11 | ```bash 12 | cd vite && npm install 13 | ``` 14 | 15 | ## Usage 16 | From the vite folder in the theme start the vite server 17 | ```bash 18 | npm start 19 | ``` 20 | This will create the server at http://localhost:1337. 21 | When php detects that the current server contains the string `local` it will assume that the vite server is running and attempt to load files from the vite server. See the [HMR](./inc/hmr.php) file for how this behavior works. 22 | 23 | All SCSS changes should reflect immediately for TS changes you will have to refresh the page as php does not re-render itself. 24 | 25 | `Entries` in [vite.config.ts](./vite/vite.config.ts) determine what files are built into the themes dist folder create as many entries as needed so you can make your loading modular. Just be sure to update the `enqueue_scripts_styles` function found in [functions.php]('./functions.php'). 26 | 27 | # Build 28 | ```bash 29 | npm run build 30 | ``` 31 | This will build your themes TS and SCSS into JS and CSS and place them in a folder at the root of your theme `[THEME_NAME]/dist/js/[HASHED_FILE_NAME]` & `[THEME_NAME]/dist/css/[HASHED_FILE_NAME]`. 32 | 33 | A manifest file ([manifest.json](./manifest.json)) is created for cache busting when you build. When not in HMR mode the [functions.php]('./functions.php') will read the manifest file and use the file names in order to load the correct hashed files. This doesn't just load everything in manifest because you may want different CSS to load for Posts, Pages, and Singles so you have to enqueue styles and scripts as you want them. 34 | 35 | ## Callout 36 | If you're using a tool like WP Local and don't want your source files pushed to WP Engine add the name of your themes vite folder to your `.wpe-push-ignore` file located at the root of the WP Local public folder. 37 | This will ensure that only built files are deployed to your site. 38 | > EX for base version: 39 | `wp-content/themes/wp-theme-vite-template/vite` 40 | ## License 41 | 42 | [MIT](https://choosealicense.com/licenses/mit/) -------------------------------------------------------------------------------- /vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve as resolvePath } from 'path'; 2 | 3 | import { defineConfig } from 'vite'; 4 | import { rm, mkdir, writeFile } from 'node:fs/promises' 5 | import { resolve } from 'path' 6 | import { CopyFilePlugin } from './plugins'; 7 | 8 | const __dirname = new URL('.', import.meta.url).pathname; 9 | const getEntries = (entries): any => { const out = {}; entries.forEach(entry => { out[entry.name] = entry.source; }); return out; }; 10 | 11 | const entries = [ 12 | { name: 'index', source: './ts/index.ts', type: 'js' }, 13 | { name: 'style', source: './scss/style.ts', type: 'css' }, 14 | ]; 15 | 16 | export default defineConfig({ 17 | plugins: [ 18 | ...entries.map(entry => CopyFilePlugin({ 19 | sourceFileName: entry.type === 'css' ? `${entry.name}.css` : entry.name, 20 | absolutePathToDestination: entry.type === 'css' ? resolvePath(__dirname, '../dist/style/') : resolvePath(__dirname, '../dist/js/'), 21 | })), 22 | { 23 | name: "Cleaning theme folder", 24 | async buildStart() { 25 | await rm(resolve(__dirname, '../dist/js'), { recursive: true, force: true }); 26 | await rm(resolve(__dirname, '../dist/style'), { recursive: true, force: true }); 27 | await mkdir(resolve(__dirname, '../dist/js'), { recursive: true }); 28 | await mkdir(resolve(__dirname, '../dist/style'), { recursive: true }); 29 | } 30 | }, 31 | { 32 | name: "Create Manifest", 33 | writeBundle: async (data: any, output) => { 34 | const out = {}; 35 | entries.map(entry => { 36 | const isStyle = entry.type === 'css'; 37 | const sourceName = isStyle ? `${entry.name}.css` : entry.name; 38 | const destination = isStyle ? '/dist/style' : '/dist/js'; 39 | const item = Object.values(output).find(({ name }) => name === sourceName); 40 | if (!item) return; 41 | out[sourceName] = item.fileName.replace('assets', destination); 42 | }); 43 | const jsonData = JSON.stringify(out); 44 | await rm(resolve(__dirname, '../manifest.json'), { force: true }); 45 | await writeFile(resolve(__dirname, '../manifest.json'), jsonData); 46 | } 47 | }, 48 | ], 49 | build: { 50 | target: 'modules', 51 | outDir: '.vite-dist', 52 | rollupOptions: { input: getEntries(entries) }, 53 | }, 54 | server: { 55 | port: 1337, 56 | host: '0.0.0.0', 57 | }, 58 | }); 59 | -------------------------------------------------------------------------------- /vite/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "vite", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "sass": "^1.64.1", 12 | "typescript": "^5.0.2", 13 | "vite": "^4.4.5" 14 | } 15 | }, 16 | "node_modules/@esbuild/android-arm": { 17 | "version": "0.18.16", 18 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.16.tgz", 19 | "integrity": "sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug==", 20 | "cpu": [ 21 | "arm" 22 | ], 23 | "dev": true, 24 | "optional": true, 25 | "os": [ 26 | "android" 27 | ], 28 | "engines": { 29 | "node": ">=12" 30 | } 31 | }, 32 | "node_modules/@esbuild/android-arm64": { 33 | "version": "0.18.16", 34 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.16.tgz", 35 | "integrity": "sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA==", 36 | "cpu": [ 37 | "arm64" 38 | ], 39 | "dev": true, 40 | "optional": true, 41 | "os": [ 42 | "android" 43 | ], 44 | "engines": { 45 | "node": ">=12" 46 | } 47 | }, 48 | "node_modules/@esbuild/android-x64": { 49 | "version": "0.18.16", 50 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.16.tgz", 51 | "integrity": "sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw==", 52 | "cpu": [ 53 | "x64" 54 | ], 55 | "dev": true, 56 | "optional": true, 57 | "os": [ 58 | "android" 59 | ], 60 | "engines": { 61 | "node": ">=12" 62 | } 63 | }, 64 | "node_modules/@esbuild/darwin-arm64": { 65 | "version": "0.18.16", 66 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.16.tgz", 67 | "integrity": "sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw==", 68 | "cpu": [ 69 | "arm64" 70 | ], 71 | "dev": true, 72 | "optional": true, 73 | "os": [ 74 | "darwin" 75 | ], 76 | "engines": { 77 | "node": ">=12" 78 | } 79 | }, 80 | "node_modules/@esbuild/darwin-x64": { 81 | "version": "0.18.16", 82 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.16.tgz", 83 | "integrity": "sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA==", 84 | "cpu": [ 85 | "x64" 86 | ], 87 | "dev": true, 88 | "optional": true, 89 | "os": [ 90 | "darwin" 91 | ], 92 | "engines": { 93 | "node": ">=12" 94 | } 95 | }, 96 | "node_modules/@esbuild/freebsd-arm64": { 97 | "version": "0.18.16", 98 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.16.tgz", 99 | "integrity": "sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ==", 100 | "cpu": [ 101 | "arm64" 102 | ], 103 | "dev": true, 104 | "optional": true, 105 | "os": [ 106 | "freebsd" 107 | ], 108 | "engines": { 109 | "node": ">=12" 110 | } 111 | }, 112 | "node_modules/@esbuild/freebsd-x64": { 113 | "version": "0.18.16", 114 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.16.tgz", 115 | "integrity": "sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg==", 116 | "cpu": [ 117 | "x64" 118 | ], 119 | "dev": true, 120 | "optional": true, 121 | "os": [ 122 | "freebsd" 123 | ], 124 | "engines": { 125 | "node": ">=12" 126 | } 127 | }, 128 | "node_modules/@esbuild/linux-arm": { 129 | "version": "0.18.16", 130 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.16.tgz", 131 | "integrity": "sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw==", 132 | "cpu": [ 133 | "arm" 134 | ], 135 | "dev": true, 136 | "optional": true, 137 | "os": [ 138 | "linux" 139 | ], 140 | "engines": { 141 | "node": ">=12" 142 | } 143 | }, 144 | "node_modules/@esbuild/linux-arm64": { 145 | "version": "0.18.16", 146 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.16.tgz", 147 | "integrity": "sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ==", 148 | "cpu": [ 149 | "arm64" 150 | ], 151 | "dev": true, 152 | "optional": true, 153 | "os": [ 154 | "linux" 155 | ], 156 | "engines": { 157 | "node": ">=12" 158 | } 159 | }, 160 | "node_modules/@esbuild/linux-ia32": { 161 | "version": "0.18.16", 162 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.16.tgz", 163 | "integrity": "sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow==", 164 | "cpu": [ 165 | "ia32" 166 | ], 167 | "dev": true, 168 | "optional": true, 169 | "os": [ 170 | "linux" 171 | ], 172 | "engines": { 173 | "node": ">=12" 174 | } 175 | }, 176 | "node_modules/@esbuild/linux-loong64": { 177 | "version": "0.18.16", 178 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.16.tgz", 179 | "integrity": "sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g==", 180 | "cpu": [ 181 | "loong64" 182 | ], 183 | "dev": true, 184 | "optional": true, 185 | "os": [ 186 | "linux" 187 | ], 188 | "engines": { 189 | "node": ">=12" 190 | } 191 | }, 192 | "node_modules/@esbuild/linux-mips64el": { 193 | "version": "0.18.16", 194 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.16.tgz", 195 | "integrity": "sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ==", 196 | "cpu": [ 197 | "mips64el" 198 | ], 199 | "dev": true, 200 | "optional": true, 201 | "os": [ 202 | "linux" 203 | ], 204 | "engines": { 205 | "node": ">=12" 206 | } 207 | }, 208 | "node_modules/@esbuild/linux-ppc64": { 209 | "version": "0.18.16", 210 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.16.tgz", 211 | "integrity": "sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ==", 212 | "cpu": [ 213 | "ppc64" 214 | ], 215 | "dev": true, 216 | "optional": true, 217 | "os": [ 218 | "linux" 219 | ], 220 | "engines": { 221 | "node": ">=12" 222 | } 223 | }, 224 | "node_modules/@esbuild/linux-riscv64": { 225 | "version": "0.18.16", 226 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.16.tgz", 227 | "integrity": "sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ==", 228 | "cpu": [ 229 | "riscv64" 230 | ], 231 | "dev": true, 232 | "optional": true, 233 | "os": [ 234 | "linux" 235 | ], 236 | "engines": { 237 | "node": ">=12" 238 | } 239 | }, 240 | "node_modules/@esbuild/linux-s390x": { 241 | "version": "0.18.16", 242 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.16.tgz", 243 | "integrity": "sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg==", 244 | "cpu": [ 245 | "s390x" 246 | ], 247 | "dev": true, 248 | "optional": true, 249 | "os": [ 250 | "linux" 251 | ], 252 | "engines": { 253 | "node": ">=12" 254 | } 255 | }, 256 | "node_modules/@esbuild/linux-x64": { 257 | "version": "0.18.16", 258 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.16.tgz", 259 | "integrity": "sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA==", 260 | "cpu": [ 261 | "x64" 262 | ], 263 | "dev": true, 264 | "optional": true, 265 | "os": [ 266 | "linux" 267 | ], 268 | "engines": { 269 | "node": ">=12" 270 | } 271 | }, 272 | "node_modules/@esbuild/netbsd-x64": { 273 | "version": "0.18.16", 274 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.16.tgz", 275 | "integrity": "sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw==", 276 | "cpu": [ 277 | "x64" 278 | ], 279 | "dev": true, 280 | "optional": true, 281 | "os": [ 282 | "netbsd" 283 | ], 284 | "engines": { 285 | "node": ">=12" 286 | } 287 | }, 288 | "node_modules/@esbuild/openbsd-x64": { 289 | "version": "0.18.16", 290 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.16.tgz", 291 | "integrity": "sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA==", 292 | "cpu": [ 293 | "x64" 294 | ], 295 | "dev": true, 296 | "optional": true, 297 | "os": [ 298 | "openbsd" 299 | ], 300 | "engines": { 301 | "node": ">=12" 302 | } 303 | }, 304 | "node_modules/@esbuild/sunos-x64": { 305 | "version": "0.18.16", 306 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.16.tgz", 307 | "integrity": "sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ==", 308 | "cpu": [ 309 | "x64" 310 | ], 311 | "dev": true, 312 | "optional": true, 313 | "os": [ 314 | "sunos" 315 | ], 316 | "engines": { 317 | "node": ">=12" 318 | } 319 | }, 320 | "node_modules/@esbuild/win32-arm64": { 321 | "version": "0.18.16", 322 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.16.tgz", 323 | "integrity": "sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw==", 324 | "cpu": [ 325 | "arm64" 326 | ], 327 | "dev": true, 328 | "optional": true, 329 | "os": [ 330 | "win32" 331 | ], 332 | "engines": { 333 | "node": ">=12" 334 | } 335 | }, 336 | "node_modules/@esbuild/win32-ia32": { 337 | "version": "0.18.16", 338 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.16.tgz", 339 | "integrity": "sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ==", 340 | "cpu": [ 341 | "ia32" 342 | ], 343 | "dev": true, 344 | "optional": true, 345 | "os": [ 346 | "win32" 347 | ], 348 | "engines": { 349 | "node": ">=12" 350 | } 351 | }, 352 | "node_modules/@esbuild/win32-x64": { 353 | "version": "0.18.16", 354 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.16.tgz", 355 | "integrity": "sha512-sCIVrrtcWN5Ua7jYXNG1xD199IalrbfV2+0k/2Zf2OyV2FtnQnMgdzgpRAbi4AWlKJj1jkX+M+fEGPQj6BQB4w==", 356 | "cpu": [ 357 | "x64" 358 | ], 359 | "dev": true, 360 | "optional": true, 361 | "os": [ 362 | "win32" 363 | ], 364 | "engines": { 365 | "node": ">=12" 366 | } 367 | }, 368 | "node_modules/anymatch": { 369 | "version": "3.1.3", 370 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 371 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 372 | "dev": true, 373 | "dependencies": { 374 | "normalize-path": "^3.0.0", 375 | "picomatch": "^2.0.4" 376 | }, 377 | "engines": { 378 | "node": ">= 8" 379 | } 380 | }, 381 | "node_modules/binary-extensions": { 382 | "version": "2.2.0", 383 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 384 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 385 | "dev": true, 386 | "engines": { 387 | "node": ">=8" 388 | } 389 | }, 390 | "node_modules/braces": { 391 | "version": "3.0.2", 392 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 393 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 394 | "dev": true, 395 | "dependencies": { 396 | "fill-range": "^7.0.1" 397 | }, 398 | "engines": { 399 | "node": ">=8" 400 | } 401 | }, 402 | "node_modules/chokidar": { 403 | "version": "3.5.3", 404 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 405 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 406 | "dev": true, 407 | "funding": [ 408 | { 409 | "type": "individual", 410 | "url": "https://paulmillr.com/funding/" 411 | } 412 | ], 413 | "dependencies": { 414 | "anymatch": "~3.1.2", 415 | "braces": "~3.0.2", 416 | "glob-parent": "~5.1.2", 417 | "is-binary-path": "~2.1.0", 418 | "is-glob": "~4.0.1", 419 | "normalize-path": "~3.0.0", 420 | "readdirp": "~3.6.0" 421 | }, 422 | "engines": { 423 | "node": ">= 8.10.0" 424 | }, 425 | "optionalDependencies": { 426 | "fsevents": "~2.3.2" 427 | } 428 | }, 429 | "node_modules/esbuild": { 430 | "version": "0.18.16", 431 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.16.tgz", 432 | "integrity": "sha512-1xLsOXrDqwdHxyXb/x/SOyg59jpf/SH7YMvU5RNSU7z3TInaASNJWNFJ6iRvLvLETZMasF3d1DdZLg7sgRimRQ==", 433 | "dev": true, 434 | "hasInstallScript": true, 435 | "bin": { 436 | "esbuild": "bin/esbuild" 437 | }, 438 | "engines": { 439 | "node": ">=12" 440 | }, 441 | "optionalDependencies": { 442 | "@esbuild/android-arm": "0.18.16", 443 | "@esbuild/android-arm64": "0.18.16", 444 | "@esbuild/android-x64": "0.18.16", 445 | "@esbuild/darwin-arm64": "0.18.16", 446 | "@esbuild/darwin-x64": "0.18.16", 447 | "@esbuild/freebsd-arm64": "0.18.16", 448 | "@esbuild/freebsd-x64": "0.18.16", 449 | "@esbuild/linux-arm": "0.18.16", 450 | "@esbuild/linux-arm64": "0.18.16", 451 | "@esbuild/linux-ia32": "0.18.16", 452 | "@esbuild/linux-loong64": "0.18.16", 453 | "@esbuild/linux-mips64el": "0.18.16", 454 | "@esbuild/linux-ppc64": "0.18.16", 455 | "@esbuild/linux-riscv64": "0.18.16", 456 | "@esbuild/linux-s390x": "0.18.16", 457 | "@esbuild/linux-x64": "0.18.16", 458 | "@esbuild/netbsd-x64": "0.18.16", 459 | "@esbuild/openbsd-x64": "0.18.16", 460 | "@esbuild/sunos-x64": "0.18.16", 461 | "@esbuild/win32-arm64": "0.18.16", 462 | "@esbuild/win32-ia32": "0.18.16", 463 | "@esbuild/win32-x64": "0.18.16" 464 | } 465 | }, 466 | "node_modules/fill-range": { 467 | "version": "7.0.1", 468 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 469 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 470 | "dev": true, 471 | "dependencies": { 472 | "to-regex-range": "^5.0.1" 473 | }, 474 | "engines": { 475 | "node": ">=8" 476 | } 477 | }, 478 | "node_modules/fsevents": { 479 | "version": "2.3.2", 480 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 481 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 482 | "dev": true, 483 | "hasInstallScript": true, 484 | "optional": true, 485 | "os": [ 486 | "darwin" 487 | ], 488 | "engines": { 489 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 490 | } 491 | }, 492 | "node_modules/glob-parent": { 493 | "version": "5.1.2", 494 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 495 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 496 | "dev": true, 497 | "dependencies": { 498 | "is-glob": "^4.0.1" 499 | }, 500 | "engines": { 501 | "node": ">= 6" 502 | } 503 | }, 504 | "node_modules/immutable": { 505 | "version": "4.3.1", 506 | "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz", 507 | "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==", 508 | "dev": true 509 | }, 510 | "node_modules/is-binary-path": { 511 | "version": "2.1.0", 512 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 513 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 514 | "dev": true, 515 | "dependencies": { 516 | "binary-extensions": "^2.0.0" 517 | }, 518 | "engines": { 519 | "node": ">=8" 520 | } 521 | }, 522 | "node_modules/is-extglob": { 523 | "version": "2.1.1", 524 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 525 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 526 | "dev": true, 527 | "engines": { 528 | "node": ">=0.10.0" 529 | } 530 | }, 531 | "node_modules/is-glob": { 532 | "version": "4.0.3", 533 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 534 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 535 | "dev": true, 536 | "dependencies": { 537 | "is-extglob": "^2.1.1" 538 | }, 539 | "engines": { 540 | "node": ">=0.10.0" 541 | } 542 | }, 543 | "node_modules/is-number": { 544 | "version": "7.0.0", 545 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 546 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 547 | "dev": true, 548 | "engines": { 549 | "node": ">=0.12.0" 550 | } 551 | }, 552 | "node_modules/nanoid": { 553 | "version": "3.3.6", 554 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 555 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 556 | "dev": true, 557 | "funding": [ 558 | { 559 | "type": "github", 560 | "url": "https://github.com/sponsors/ai" 561 | } 562 | ], 563 | "bin": { 564 | "nanoid": "bin/nanoid.cjs" 565 | }, 566 | "engines": { 567 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 568 | } 569 | }, 570 | "node_modules/normalize-path": { 571 | "version": "3.0.0", 572 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 573 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 574 | "dev": true, 575 | "engines": { 576 | "node": ">=0.10.0" 577 | } 578 | }, 579 | "node_modules/picocolors": { 580 | "version": "1.0.0", 581 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 582 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 583 | "dev": true 584 | }, 585 | "node_modules/picomatch": { 586 | "version": "2.3.1", 587 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 588 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 589 | "dev": true, 590 | "engines": { 591 | "node": ">=8.6" 592 | }, 593 | "funding": { 594 | "url": "https://github.com/sponsors/jonschlinkert" 595 | } 596 | }, 597 | "node_modules/postcss": { 598 | "version": "8.4.27", 599 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 600 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 601 | "dev": true, 602 | "funding": [ 603 | { 604 | "type": "opencollective", 605 | "url": "https://opencollective.com/postcss/" 606 | }, 607 | { 608 | "type": "tidelift", 609 | "url": "https://tidelift.com/funding/github/npm/postcss" 610 | }, 611 | { 612 | "type": "github", 613 | "url": "https://github.com/sponsors/ai" 614 | } 615 | ], 616 | "dependencies": { 617 | "nanoid": "^3.3.6", 618 | "picocolors": "^1.0.0", 619 | "source-map-js": "^1.0.2" 620 | }, 621 | "engines": { 622 | "node": "^10 || ^12 || >=14" 623 | } 624 | }, 625 | "node_modules/readdirp": { 626 | "version": "3.6.0", 627 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 628 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 629 | "dev": true, 630 | "dependencies": { 631 | "picomatch": "^2.2.1" 632 | }, 633 | "engines": { 634 | "node": ">=8.10.0" 635 | } 636 | }, 637 | "node_modules/rollup": { 638 | "version": "3.26.3", 639 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 640 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 641 | "dev": true, 642 | "bin": { 643 | "rollup": "dist/bin/rollup" 644 | }, 645 | "engines": { 646 | "node": ">=14.18.0", 647 | "npm": ">=8.0.0" 648 | }, 649 | "optionalDependencies": { 650 | "fsevents": "~2.3.2" 651 | } 652 | }, 653 | "node_modules/sass": { 654 | "version": "1.64.1", 655 | "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz", 656 | "integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==", 657 | "dev": true, 658 | "dependencies": { 659 | "chokidar": ">=3.0.0 <4.0.0", 660 | "immutable": "^4.0.0", 661 | "source-map-js": ">=0.6.2 <2.0.0" 662 | }, 663 | "bin": { 664 | "sass": "sass.js" 665 | }, 666 | "engines": { 667 | "node": ">=14.0.0" 668 | } 669 | }, 670 | "node_modules/source-map-js": { 671 | "version": "1.0.2", 672 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 673 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 674 | "dev": true, 675 | "engines": { 676 | "node": ">=0.10.0" 677 | } 678 | }, 679 | "node_modules/to-regex-range": { 680 | "version": "5.0.1", 681 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 682 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 683 | "dev": true, 684 | "dependencies": { 685 | "is-number": "^7.0.0" 686 | }, 687 | "engines": { 688 | "node": ">=8.0" 689 | } 690 | }, 691 | "node_modules/typescript": { 692 | "version": "5.1.6", 693 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 694 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 695 | "dev": true, 696 | "bin": { 697 | "tsc": "bin/tsc", 698 | "tsserver": "bin/tsserver" 699 | }, 700 | "engines": { 701 | "node": ">=14.17" 702 | } 703 | }, 704 | "node_modules/vite": { 705 | "version": "4.4.7", 706 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", 707 | "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", 708 | "dev": true, 709 | "dependencies": { 710 | "esbuild": "^0.18.10", 711 | "postcss": "^8.4.26", 712 | "rollup": "^3.25.2" 713 | }, 714 | "bin": { 715 | "vite": "bin/vite.js" 716 | }, 717 | "engines": { 718 | "node": "^14.18.0 || >=16.0.0" 719 | }, 720 | "funding": { 721 | "url": "https://github.com/vitejs/vite?sponsor=1" 722 | }, 723 | "optionalDependencies": { 724 | "fsevents": "~2.3.2" 725 | }, 726 | "peerDependencies": { 727 | "@types/node": ">= 14", 728 | "less": "*", 729 | "lightningcss": "^1.21.0", 730 | "sass": "*", 731 | "stylus": "*", 732 | "sugarss": "*", 733 | "terser": "^5.4.0" 734 | }, 735 | "peerDependenciesMeta": { 736 | "@types/node": { 737 | "optional": true 738 | }, 739 | "less": { 740 | "optional": true 741 | }, 742 | "lightningcss": { 743 | "optional": true 744 | }, 745 | "sass": { 746 | "optional": true 747 | }, 748 | "stylus": { 749 | "optional": true 750 | }, 751 | "sugarss": { 752 | "optional": true 753 | }, 754 | "terser": { 755 | "optional": true 756 | } 757 | } 758 | } 759 | } 760 | } 761 | --------------------------------------------------------------------------------