├── .github └── workflows │ ├── build-publish.yml │ └── release-please.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json └── pnpm-lock.yaml /.github/workflows/build-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Package to npmjs 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | # Setup .npmrc file to publish to npm 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: '18' 14 | registry-url: 'https://registry.npmjs.org' 15 | - run: npm i 16 | - run: npm run build 17 | - run: npm publish 18 | env: 19 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | name: release-please 11 | 12 | jobs: 13 | release-please: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: google-github-actions/release-please-action@v3 17 | with: 18 | token: ${{ secrets.RELEASE_TOKEN }} 19 | release-type: node 20 | package-name: '@linlin00/usbuild' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.local.* 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | lerna-debug.log* 10 | .pnpm-debug.log* 11 | 12 | # Diagnostic reports (https://nodejs.org/api/report.html) 13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | *.lcov 27 | 28 | # nyc test coverage 29 | .nyc_output 30 | 31 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 32 | .grunt 33 | 34 | # Bower dependency directory (https://bower.io/) 35 | bower_components 36 | 37 | # node-waf configuration 38 | .lock-wscript 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | 47 | # Snowpack dependency directory (https://snowpack.dev/) 48 | web_modules/ 49 | 50 | # TypeScript cache 51 | *.tsbuildinfo 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional stylelint cache 60 | .stylelintcache 61 | 62 | # Microbundle cache 63 | .rpt2_cache/ 64 | .rts2_cache_cjs/ 65 | .rts2_cache_es/ 66 | .rts2_cache_umd/ 67 | 68 | # Optional REPL history 69 | .node_repl_history 70 | 71 | # Output of 'npm pack' 72 | *.tgz 73 | 74 | # Yarn Integrity file 75 | .yarn-integrity 76 | 77 | # dotenv environment variable files 78 | .env 79 | .env.development.local 80 | .env.test.local 81 | .env.production.local 82 | .env.local 83 | 84 | # parcel-bundler cache (https://parceljs.org/) 85 | .cache 86 | .parcel-cache 87 | 88 | # Next.js build output 89 | .next 90 | out 91 | 92 | # Nuxt.js build / generate output 93 | .nuxt 94 | dist 95 | 96 | # Gatsby files 97 | .cache/ 98 | # Comment in the public line in if your project uses Gatsby and not Next.js 99 | # https://nextjs.org/blog/next-9-1#public-directory-support 100 | # public 101 | 102 | # vuepress build output 103 | .vuepress/dist 104 | 105 | # vuepress v2.x temp and cache directory 106 | .temp 107 | .cache 108 | 109 | # Docusaurus cache and generated files 110 | .docusaurus 111 | 112 | # Serverless directories 113 | .serverless/ 114 | 115 | # FuseBox cache 116 | .fusebox/ 117 | 118 | # DynamoDB Local files 119 | .dynamodb/ 120 | 121 | # TernJS port file 122 | .tern-port 123 | 124 | # Stores VSCode versions used for testing VSCode extensions 125 | .vscode-test 126 | 127 | # yarn v2 128 | .yarn/cache 129 | .yarn/unplugged 130 | .yarn/build-state.yml 131 | .yarn/install-state.gz 132 | .pnp.* 133 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.10.1](https://github.com/LinLin00000000/usbuild/compare/v1.10.0...v1.10.1) (2024-03-04) 4 | 5 | 6 | ### Bug Fixes 7 | 8 | * 修复 linux 下绝对路径匹配的问题 ([ed7a344](https://github.com/LinLin00000000/usbuild/commit/ed7a3448795bb1e857ef4c558a1255b52d3bc74d)), closes [#18](https://github.com/LinLin00000000/usbuild/issues/18) 9 | 10 | ## [1.10.0](https://github.com/LinLin00000000/usbuild/compare/v1.9.0...v1.10.0) (2024-01-15) 11 | 12 | 13 | ### Features 14 | 15 | * (移除 usbuild 库本身)插件部分使用回之前的力量代价版本以降低源码复杂度 ([cf64324](https://github.com/LinLin00000000/usbuild/commit/cf64324ab339a9f3d2b022a61598633750158866)) 16 | * 支持封装 build 函数 ([cf64324](https://github.com/LinLin00000000/usbuild/commit/cf64324ab339a9f3d2b022a61598633750158866)) 17 | 18 | ## [1.9.0](https://github.com/LinLin00000000/usbuild/compare/v1.8.0...v1.9.0) (2024-01-06) 19 | 20 | 21 | ### Features 22 | 23 | * 增加reload模式,原本为刷新网页,加一个重新安装脚本的方法 ([2e8710a](https://github.com/LinLin00000000/usbuild/commit/2e8710abc790c0bfca3e50918d0f18de5dfc2600)) 24 | 25 | ## [1.8.0](https://github.com/LinLin00000000/usbuild/compare/v1.7.2...v1.8.0) (2023-12-20) 26 | 27 | 28 | ### Features 29 | 30 | * 增加 autoReloadDelay 参数,以避免太过频繁刷新页面,默认值为 1000 ms ([0fb7af1](https://github.com/LinLin00000000/usbuild/commit/0fb7af1cc4bf807d470d34f50ad9445702a31311)) 31 | * 增加 enableLocalFileRequireInDev 参数 ([33b4b9a](https://github.com/LinLin00000000/usbuild/commit/33b4b9aa06e5cb409a68d5bc344d0fd123f2f2d3)) 32 | 33 | ## [1.7.2](https://github.com/LinLin00000000/usbuild/compare/v1.7.1...v1.7.2) (2023-12-07) 34 | 35 | 36 | ### Bug Fixes 37 | 38 | * 修复多层 outdir 下的文件夹不存在的问题 ([5193a7d](https://github.com/LinLin00000000/usbuild/commit/5193a7ddd4fe701ceeba4ea744c516bfc74eba14)) 39 | 40 | ## [1.7.1](https://github.com/LinLin00000000/usbuild/compare/v1.7.0...v1.7.1) (2023-12-06) 41 | 42 | 43 | ### Bug Fixes 44 | 45 | * 修复可能出现的 GM_API 未定义的问题 ([18d4bfe](https://github.com/LinLin00000000/usbuild/commit/18d4bfe5b40fe759506607febc78d24713f35567)) 46 | 47 | ## [1.7.0](https://github.com/LinLin00000000/usbuild/compare/v1.6.0...v1.7.0) (2023-12-06) 48 | 49 | 50 | ### Features 51 | 52 | * 支持顶层 await ([7310870](https://github.com/LinLin00000000/usbuild/commit/7310870ed41e8c4ceeb248cd37fea670e19bc103)) 53 | 54 | ## [1.6.0](https://github.com/LinLin00000000/usbuild/compare/v1.5.0...v1.6.0) (2023-12-04) 55 | 56 | 57 | ### Features 58 | 59 | * 支持 grant 属性自动生成 ([1f5d46e](https://github.com/LinLin00000000/usbuild/commit/1f5d46eae0013ec1963e5399569a61bc9332acfc)) 60 | 61 | 62 | ### Bug Fixes 63 | 64 | * 修复 dev 模式下 GM_API 无效的问题 ([1f5d46e](https://github.com/LinLin00000000/usbuild/commit/1f5d46eae0013ec1963e5399569a61bc9332acfc)) 65 | 66 | ## [1.5.0](https://github.com/LinLin00000000/usbuild/compare/v1.4.0...v1.5.0) (2023-12-04) 67 | 68 | 69 | ### Features 70 | 71 | * **removeImportUsbuildPlugin:** 优化 babel 移除 usbuild 相关语句的流程 ([02d54a0](https://github.com/LinLin00000000/usbuild/commit/02d54a0fe32a3613fff5d2155c8e0153e6a70e12)) 72 | 73 | ## [1.4.0](https://github.com/LinLin00000000/usbuild/compare/v1.3.0...v1.4.0) (2023-12-03) 74 | 75 | 76 | ### Features 77 | 78 | * 改用使用 babel 删除调用 usbuild 的语句 ([257dbb5](https://github.com/LinLin00000000/usbuild/commit/257dbb5f67e90ea6ab17a61c82139b39124a136e)) 79 | 80 | ## [1.3.0](https://github.com/LinLin00000000/usbuild/compare/v1.2.0...v1.3.0) (2023-12-02) 81 | 82 | 83 | ### Features 84 | 85 | * 改进引用脚本的方式, 可以免去 usbuild 标记的麻烦啦 ([e4392bf](https://github.com/LinLin00000000/usbuild/commit/e4392bfd3cc8839990977e42523581753fc47c23)) 86 | 87 | ## [1.2.0](https://github.com/LinLin00000000/usbuild/compare/v1.1.1...v1.2.0) (2023-12-02) 88 | 89 | 90 | ### Features 91 | 92 | * 增加实时热重载的功能 ([830a057](https://github.com/LinLin00000000/usbuild/commit/830a0572c1baa696c43c714616359144ed783ada)) 93 | 94 | ## [1.1.1](https://github.com/LinLin00000000/usbuild/compare/v1.1.0...v1.1.1) (2023-12-02) 95 | 96 | 97 | ### Bug Fixes 98 | 99 | * 修复 dev 模式下可能的 no such file or directory 问题 ([4f09a64](https://github.com/LinLin00000000/usbuild/commit/4f09a64d29b5815a930873d95c3f4ab8e3d93b72)) 100 | 101 | ## [1.1.0](https://github.com/LinLin00000000/usbuild/compare/v1.0.2...v1.1.0) (2023-12-01) 102 | 103 | 104 | ### Features 105 | 106 | * 优化安装脚本的过程, 使本地开发不用打开插件"访问本地文件"权限 ([04f078e](https://github.com/LinLin00000000/usbuild/commit/04f078ef01f6bf8806693563764c512b36c8ab18)) 107 | * 增加了对 ScriptCat 的本地开发支持 ([d4b0eed](https://github.com/LinLin00000000/usbuild/commit/d4b0eed08f8e51448b47b922b9e5e5f54a1a53b5)) 108 | 109 | 110 | ### Bug Fixes 111 | 112 | * 增加配置中 version 字段的默认值, 防止ScriptCat检测不出脚本 ([d8dce05](https://github.com/LinLin00000000/usbuild/commit/d8dce05b9ec6578299f7f8354ad5b945d9ca58ed)) 113 | 114 | ## [1.0.2](https://github.com/LinLin00000000/usbuild/compare/v1.0.1...v1.0.2) (2023-12-01) 115 | 116 | 117 | ### Bug Fixes 118 | 119 | * **bannerBuilder:** 修复在油猴编辑器中可能出现的bug ([f8bd895](https://github.com/LinLin00000000/usbuild/commit/f8bd895fee340f2495496e4a6b6bf5f11292f172)) 120 | 121 | ## [1.0.1](https://github.com/LinLin00000000/usbuild/compare/v1.0.0...v1.0.1) (2023-11-30) 122 | 123 | 124 | ### Bug Fixes 125 | 126 | * **package.json:** 增加main 字段以防止出现警告 ([92d2e79](https://github.com/LinLin00000000/usbuild/commit/92d2e79292c11b389447383eef721b2e11c4da21)) 127 | 128 | ## 1.0.0 (2023-11-29) 129 | 130 | 131 | ### ⚠ BREAKING CHANGES 132 | 133 | * 发布第一版 134 | 135 | ### Features 136 | 137 | * 发布第一版 ([efa55bb](https://github.com/LinLin00000000/usbuild/commit/efa55bb79eed98b75b6de375c89bc5494b54353c)) 138 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Lin 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 | # usbuild 2 | 3 | 🚀 一个基于 [esbuild](https://esbuild.github.io/) 的 [油猴](https://www.tampermonkey.net/) 脚本(UserScript)构建工具,让你的脚本开发像坐火箭一样快! 4 | 5 | ## 🪄 功能 6 | 7 | - 🧙‍♂️ **变戏法般的 UserScript 头部注释** - 你写代码,我变魔术!自动将你的配置变成闪亮的 [UserScript 头部注释](https://www.tampermonkey.net/documentation.php)。忘记繁琐的格式吧,让这个魔法帮你搞定一切! 8 | 9 | - 🔍 **侦探式的智能 GM_API 探测** - 我们的构建过程中有个侦探,它会悄悄检查你的代码,寻找那些GM_API的踪迹,并且像发现宝藏一样自动生成 [grant](https://www.tampermonkey.net/documentation.php#meta:grant) 属性。配置再也不是什么难题,全部交给这个侦探吧! 10 | 11 | - 🚀 **忍者般的热重载与开发服务器** - 开启 dev 模式,就像召唤了一位忍者,他不仅偷偷启动了开发服务器,还能在源文件一有风吹草动时,迅速做出反应,实现热重载。手动刷新?那是过去式! 12 | 13 | - 🌐 **本地文件的秘密通道(可选功能)** - 想绕过 CSP?没问题!启用 `enableLocalFileRequireInDev`,就像打开了一个秘密通道,让你在本地自由穿梭,不受束缚。但记住,这可是个双刃剑,虽然强大,但要小心使用,我们默认是关着的哦! 14 | 15 | ## 🛠️ 安装 16 | 17 | 🔮 在 01 世界里敲入这个神秘的咒语,神奇的工具就到手啦! 18 | 19 | ```shell 20 | npm i -D @linlin00/usbuild 21 | ``` 22 | 23 | ## 🚀 快速开始 24 | 25 | 想要成为 UserScript 的大师吗?来吧,跟着我一起开始这段奇妙之旅! 26 | 27 | 首先,创建一个神秘的文件,取名为 `MyUserScript.mjs`(当然,名字可以随你的心意变换哦)。 28 | 29 | 接着,用你那魔法般的双手在文件里施展这样的咒语: 30 | 31 | ```javascript 32 | import { build } from '@linlin00/usbuild' 33 | await build({ 34 | match: ['https://*.bilibili.com/*'] 35 | }) 36 | 37 | const 超大声 = alert 38 | 超大声('番茄炒蛋拳!') 39 | ``` 40 | 41 | 完成这一切后,只需轻轻一挥你的魔杖(直接使用 `node` 命令运行该文件),神奇的事情就会发生:脚本自动构建,并且浏览器会如同被施了魔法般自动打开安装! 42 | 43 | ## 🌟 参数详解 44 | 45 | 准备好深入探索 usbuild 的神秘力量了吗?让我们一起解锁这些魔法参数的秘密! 46 | 47 | `build` 函数是你施法的核心,它有两个神秘的参数:一个是 UserScript 配置的魔法盒子,另一个是可选的魔法选项。 48 | 49 | - [UserScript 配置](https://www.tampermonkey.net/) 50 | 51 | 一个对象,其中的🔑键名就像法术的名称,值则是充满魔力的字符串或字符串数组。 52 | - name 53 | 54 | 🎩 name 字段可以选择性消失,如果消失,它会像魔术师一样从文件名中变出来。 55 | 56 | - ~~grant~~ 57 | 58 | 不需要书写该咒语。 59 | 60 | 🕵️‍♂️ 在非 dev 模式下,grant 属性会像智能侦探一样自动进行检测并生成,免去了手动配置的繁琐。 61 | 62 | 🚀 而在 dev 模式下,为了让开发更加方便快捷,我们直接授予所有权限,就像给开发者提供了一把万能钥匙! 63 | 64 | - [...](https://www.tampermonkey.net/) 65 | 66 | - 构建选项 67 | 68 | 一个对象。这些是定制你的构建过程的小小工具。 69 | 70 | - `dev` 71 | 72 | 默认值 `false` 73 | 74 | 🌆 这个模式就像是间谍黄昏,会偷偷监听源文件的变动,实现神奇的热重载。 75 | 76 | - `outdir` 77 | 78 | 默认值 `'dist'` 79 | 80 | 🏠 outdir 会在指定目录下藏起构建后的文件。 81 | 82 | - `host` 83 | 84 | 默认值 `'127.0.0.1'` 85 | 86 | 🏡 host 设定了我们的服务地址,就像定下了我们神秘小屋的地点,确保它既安全又容易找到。 87 | 88 | - `port` 89 | 90 | 默认值 `7100` 91 | 92 | 🚪 port 就像是我们小屋的门牌号,指定了访客应该敲哪扇门来找到我们的宝藏。 93 | 94 | - `autoReload` 95 | 96 | 默认值 `true` 97 | 98 | 🔄 控制是否开启自动刷新的魔法开关(也就是实时热重载)。当源文件变化时,它就像灵巧的小精灵,自动更新网页,让变化瞬间呈现,免去了手动刷新的麻烦。 99 | 100 | - `autoReloadMode` 101 | 102 | 默认值 `refresh` 103 | 104 | 🧶 控制自动重载的模式,可选值为 `refresh` 和 `reinstall`。`refresh` 以刷新网页的方式自动重载,`reinstall` 以重新安装脚本的方式自动重载。 105 | 106 | - `autoReloadDelay` 107 | 108 | 默认值 `1000` 109 | 110 | ⏱️ autoReloadDelay 是自动重载的等待时间(毫秒),像是小精灵准备魔法的时间。 111 | 112 | - `enableLocalFileRequireInDev` 113 | 114 | 默认值 `false` 115 | 116 | 📂 控制在开发模式下是否启用加载本地文件来绕过内容安全策略(CSP)。启用这个功能时,你需要在浏览器的油猴扩展中设置允许访问本地文件。这就像是给你的脚本赋予了额外的力量,让它在本地环境中自由翱翔,但别忘了,这需要在你的浏览器扩展中额外开启相应的权限。 117 | 118 | ## 💬 社区 119 | 120 | 作者的闲聊吹水(QQ)群: 733165997 121 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | import esbuild from 'esbuild' 4 | import open, { apps } from 'open' 5 | import portfinder from 'portfinder' 6 | import babel from '@babel/core' 7 | 8 | /** 9 | * 🚀 构建函数,让你的油猴脚本起飞! 10 | * 11 | * @param {Object} userScriptConfig - 用户脚本配置对象。 12 | * @param {Object} options - 可选的配置参数对象。 13 | * @param {boolean} [options.dev=false] - 是否为开发模式,默认为 false。 14 | * @param {string} [options.outdir='dist'] - 输出目录,默认为 'dist'。 15 | * @param {string} [options.host='127.0.0.1'] - 服务器主机地址,默认为 '127.0.0.1'。 16 | * @param {number} [options.port=7100] - 服务器端口,默认为 7100。 17 | * @param {boolean} [options.autoReload=true] - 是否自动重载,默认为 true。 18 | * @param {string} [options.autoReloadMode='refresh'] - 自动重载模式,值为'refresh' 或 'reinstall'。默认为 'refresh'。 19 | * @param {number} [options.autoReloadDelay=1000] - 自动重载延迟时间(毫秒),默认为 1000。 20 | * @param {boolean} [options.enableLocalFileRequireInDev=false] - 在开发模式下是否启用加载本地文件来绕过 CSP,默认为 false。如果启用该功能,需在浏览器扩展中同时设置油猴允许访问本地文件。 21 | * @returns {Promise} 返回一个永不会产生结果的 Promise,以阻塞程序往下运行 22 | */ 23 | export async function build( 24 | userScriptConfig = {}, 25 | { 26 | dev = false, 27 | outdir = 'dist', 28 | host = '127.0.0.1', 29 | port = 7100, 30 | autoReload = true, 31 | autoReloadMode = 'refresh', 32 | autoReloadDelay = 1000, 33 | enableLocalFileRequireInDev = false, 34 | } = {} 35 | ) { 36 | // 🌟 获取调用这个函数的文件的路径,就像一名神秘的探险家寻找宝藏地图。 37 | const filePath = getCallerFilePath() 38 | 39 | // 🧭 分析文件路径,提取出文件名和目录,就像解开一个古老的谜题。 40 | const { name: fileName, dir: fileDir } = path.parse(filePath) 41 | 42 | // 📝 如果用户没有指定脚本名,我们就从文件名中获取,就像从石头中雕刻出雕像。 43 | userScriptConfig.name ??= fileName.replace(/[-_]/g, ' ') 44 | userScriptConfig.version ??= '0.1.0' 45 | 46 | // 🏠 确定最终的输出目录,给我们的脚本一个温馨的家。 47 | const finalOutdir = path.join(fileDir, outdir) 48 | 49 | if (!fs.existsSync(finalOutdir)) { 50 | fs.mkdirSync(finalOutdir, { 51 | recursive: true, 52 | }) 53 | } 54 | 55 | // 📦 配置 esbuild,让你的代码像魔法一样自动转化并打包。 56 | const esbuildOptions = { 57 | entryPoints: [filePath], 58 | bundle: true, 59 | outdir: finalOutdir, 60 | charset: 'utf8', 61 | outExtension: { '.js': '.user.js' }, 62 | dropLabels: ['usbuild'], // 因为历史原因暂时保留 63 | plugins: [ignoreSelfPlugin], 64 | format: 'esm', 65 | banner: { 66 | js: '\n;(async function () {', 67 | }, 68 | footer: { 69 | js: '\n})();', 70 | }, 71 | } 72 | 73 | // 🕵️‍♂️ 我们用 portfinder 来获取一个可用的端口,就像找到一个没有人使用的秘密通道。 74 | const finalPort = await portfinder.getPortPromise({ port }) 75 | 76 | const baseURL = `http://${host}:${finalPort}/` 77 | const targetFileName = fileName + '.user.js' 78 | const proxyFileName = fileName + '.proxy.user.js' 79 | 80 | const targetFileURL = baseURL + targetFileName 81 | const proxyFileURL = baseURL + proxyFileName 82 | const targetFilePath = path.join(finalOutdir, targetFileName) 83 | const proxyFilePath = path.join(finalOutdir, proxyFileName) 84 | 85 | let ctx 86 | 87 | // 🔍 如果是开发模式,我们会像侦探一样密切关注代码的每一个变化。 88 | if (dev) { 89 | /** 90 | * 📑 为了避免反复像洗衣机一样安装脚本,我们施展了一个小小的魔法:创建一个中间脚本。 91 | * 这个中间脚本就像是一个神奇的桥梁,它通过 js 动态插入指向真正脚本位置的 Script 元素,巧妙地连接到我们打包后的文件。 92 | * 这样的好处是显而易见的——你只需安装这个中间脚本一次,它就会永远忠诚地为你服务,同时保持轻巧,因为它只包含了必要的脚本元数据,而没有一丁点代码的负担。 93 | * 每当你的源文件有所变动,只需要让你的浏览器做个伸展操般的刷新,变化就会立刻展现在你眼前,就像变魔术一样神奇又有趣! 94 | */ 95 | 96 | ctx = await esbuild.context(esbuildOptions) 97 | await ctx.watch() 98 | 99 | // 开发模式下默认申请所有权限 100 | userScriptConfig.grant = unique( 101 | mergeArrays(userScriptConfig.grant, grantFunctions) 102 | ) 103 | 104 | if (enableLocalFileRequireInDev) { 105 | userScriptConfig.require = mergeArrays( 106 | userScriptConfig.require, 107 | `file://${targetFilePath}` 108 | ) 109 | } 110 | 111 | const codes = [bannerBuilder(userScriptConfig)] 112 | 113 | if (!enableLocalFileRequireInDev) { 114 | codes.push( 115 | createAndInsertScript(targetFileURL), 116 | grantAccessToUnsafeWindow() 117 | ) 118 | } 119 | 120 | if (autoReload) { 121 | // 自动刷新的来源, See https://esbuild.github.io/api/#live-reload 122 | codes.push( 123 | setupAutoReload( 124 | baseURL + 'esbuild', 125 | autoReloadMode, 126 | autoReloadDelay 127 | ) 128 | ) 129 | } 130 | 131 | const proxyScriptContent = codes.join('\n') 132 | 133 | // ✍️ 将这个精心准备的中间脚本写入文件,就像在一个神秘的卷轴上写下了古老的咒语。 134 | fs.writeFileSync(proxyFilePath, proxyScriptContent) 135 | 136 | console.log(`👀 Watching...`) 137 | } else { 138 | // 🚚 在非开发模式下,我们一举完成构建,一切都准备就绪! 139 | console.log('🚀 building...') 140 | ctx = await esbuild.context({ 141 | ...esbuildOptions, 142 | outExtension: {}, 143 | write: false, 144 | }) 145 | 146 | const result = await ctx.rebuild() 147 | const code = result.outputFiles[0].text 148 | const detectedGrant = detectGrantFunctions(code, grantFunctions) 149 | 150 | userScriptConfig.grant = unique( 151 | mergeArrays(userScriptConfig.grant, detectedGrant) 152 | ) 153 | 154 | const finalContent = bannerBuilder(userScriptConfig) + code 155 | 156 | fs.writeFileSync(targetFilePath, finalContent) 157 | 158 | console.log('🌈 build done!') 159 | } 160 | 161 | // 🌍 我们让 esbuild 服务启动起来,在这个新发现的端口上展开我们的小世界。 162 | await ctx.serve({ 163 | host, 164 | port: finalPort, 165 | servedir: finalOutdir, 166 | }) 167 | 168 | await installScript(dev ? proxyFileURL : targetFileURL) 169 | 170 | return new Promise(resolve => { 171 | setTimeout(async () => { 172 | // 💥 当我们不在开发模式下,就给系统来一个小小的“停机震撼”,优雅地退出进程。 173 | if (!dev) { 174 | // Mission completed! 175 | process.exit(0) 176 | } else { 177 | fs.unlinkSync(proxyFilePath) 178 | } 179 | }, 2000) 180 | }) 181 | } 182 | 183 | const grantFunctions = [ 184 | 'unsafeWindow', 185 | 'window.close', 186 | 'window.focus', 187 | 'window.onurlchange', 188 | 'GM_addStyle', 189 | 'GM_addElement', 190 | 'GM_deleteValue', 191 | 'GM_listValues', 192 | 'GM_addValueChangeListener', 193 | 'GM_removeValueChangeListener', 194 | 'GM_setValue', 195 | 'GM_getValue', 196 | 'GM_log', 197 | 'GM_getResourceText', 198 | 'GM_getResourceURL', 199 | 'GM_registerMenuCommand', 200 | 'GM_unregisterMenuCommand', 201 | 'GM_openInTab', 202 | 'GM_xmlhttpRequest', 203 | 'GM_download', 204 | 'GM_getTab', 205 | 'GM_saveTab', 206 | 'GM_getTabs', 207 | 'GM_notification', 208 | 'GM_setClipboard', 209 | 'GM_info', 210 | 'GM_cookie', 211 | 'GM_webRequest', 212 | ] 213 | 214 | // 🧙‍♂️ 使用一点黑魔法来获取调用者文件的路径,但别忘了,魔法总是神秘莫测哒! 215 | function getCallerFilePath() { 216 | // 🕵️‍♂️ 创建一个错误对象,它会揭示调用堆栈的秘密。 217 | const err = new Error() 218 | const stack = err.stack 219 | 220 | // 🧩 将堆栈信息切割成多行,从中找出我们需要的线索。 221 | const stackLines = stack.split('\n') 222 | 223 | let result 224 | for (let i = 2; i < stackLines.length; i++) { 225 | const match = stackLines[i].match( 226 | /(?:at file:\/+)((?:[a-zA-Z]:|\/)[^]+?):\d+:\d+/ 227 | ) 228 | if (match && match[1]) { 229 | result = match[1] 230 | } 231 | } 232 | 233 | if (result === undefined) { 234 | throw new Error('无法获取文件路径: ' + callerLine) 235 | } 236 | return result 237 | } 238 | 239 | // 🎨 构建 UserScript 头部注释的工具,就像一个艺术家在画布上绘制画作。 240 | function bannerBuilder(config) { 241 | const separator = '\n' 242 | const spaceNum = 2 243 | 244 | // 🛠️ 将 name 字段提前至配置对象的最前端。这不仅是礼貌,更是策略。 245 | // 它避免了在油猴编辑器中可能出现的那些小小的报错噩梦。 246 | const finalConfig = { name: config.name, ...config } 247 | 248 | // 📏 精心计算每个字段的长度,确保整齐对齐,就像是在进行一场精确的排列。 249 | const maxLen = Math.max(...Object.keys(finalConfig).map(s => s.length)) 250 | 251 | // 🖋️ 为每个配置项创建一个独特的注释行。就像是在画布上细心地勾勒出每一个重要的元素。 252 | const fields = Object.entries(finalConfig) 253 | .map(([key, value]) => { 254 | // 📐 为了美观,我们在每个键和值之间加上恰到好处的空格。就像是在文字和文字之间留下呼吸的空间。 255 | const space = ' '.repeat(maxLen - key.length + spaceNum) 256 | const keyString = `// @${key}${space}` 257 | 258 | // 🌈 如果值是数组,我们就为数组中的每个元素都创建一个注释行。这就像是在画布上添加多彩的细节。 259 | // 🖋️ 如果不是数组,那就简单地连接键和值,完成这一行的绘制。 260 | return Array.isArray(value) 261 | ? value.map(e => keyString + e).join(separator) 262 | : keyString + value 263 | }) 264 | .filter(Boolean) 265 | 266 | // 📜 组合头部和尾部注释,完成这部 UserScript 的序幕。 267 | const header = `// ==UserScript==` 268 | const footer = `// ==/UserScript==` 269 | return [header, ...fields, footer, separator].join(separator) 270 | } 271 | 272 | /** 273 | * 合并多个数组或单个元素。 274 | * @param {...(Array|Object)} xs - 任意数量的数组或单个元素。 275 | * @returns {Array} 合并后的数组。 276 | */ 277 | function mergeArrays(...xs) { 278 | return [].concat(...xs.map(x => (Array.isArray(x) ? x : x ? [x] : []))) 279 | } 280 | 281 | /** 282 | * 从任何可迭代对象中移除重复项并返回一个新的数组。 283 | * @template T - 可迭代对象中元素的类型。 284 | * @param {Iterable} iterable - 任何可迭代对象。 285 | * @returns {T[]} 去重后的数组。 286 | */ 287 | function unique(iterable) { 288 | return [...new Set(iterable)] 289 | } 290 | 291 | function grantAccessToUnsafeWindow() { 292 | return grantFunctions 293 | .filter(name => !name.includes('.')) 294 | .concat('GM') 295 | .map(f => `if(window.${f}) unsafeWindow.${f} = ${f};`) 296 | .join('\n') 297 | } 298 | 299 | function createAndInsertScript(src) { 300 | return ` 301 | function insertScript() { 302 | // 🎭 创建一个崭新的 script 元素,就像是在舞台上准备一个新的表演道具。 303 | const script = document.createElement('script'); 304 | 305 | // 🌐 设置 script 元素的源文件。这里我们将使用 '${src}' 作为我们神秘脚本的来源。 306 | script.src = '${src}'; 307 | 308 | // 🕵️‍♂️ 获取文档的 head 元素,就像是找到了控制整个页面的大脑。 309 | const head = document.head; 310 | 311 | // 🚀 将 script 元素插入到 head 的最前端,确保它是第一个被执行的脚本,就像是开场的第一幕。 312 | head.insertBefore(script, head.firstChild); 313 | 314 | return () => head.removeChild(script); 315 | } 316 | ` 317 | } 318 | 319 | function setupAutoReload(eventSourceURL, autoReloadMode, autoReloadDelay) { 320 | const autoReloadModeMap = { 321 | refresh: 'location.reload();', 322 | reinstall: 'remove(); remove = insertScript();', 323 | } 324 | 325 | return ` 326 | let remove = insertScript() 327 | let debounceTimer; 328 | new EventSource('${eventSourceURL}').addEventListener('change', () => { 329 | clearTimeout(debounceTimer); 330 | debounceTimer = setTimeout(() => {${autoReloadModeMap[autoReloadMode]}}, ${autoReloadDelay}); 331 | }) 332 | ` 333 | } 334 | 335 | function installScript(url) { 336 | const htmlContent = `` 337 | 338 | const base64Content = Buffer.from(htmlContent).toString('base64') 339 | 340 | const dataUrl = `data:text/html;base64,${base64Content}` 341 | 342 | return open(dataUrl, { 343 | app: { name: apps.browser }, 344 | }) 345 | } 346 | 347 | function detectGrantFunctions(code, functions) { 348 | const babelPluginDetectGrantFunctionsName = 'detect-grant-functions' 349 | const { metadata } = babel.transformSync(code, { 350 | plugins: [babelPluginDetectGrantFunctions(functions)], 351 | }) 352 | 353 | return metadata[babelPluginDetectGrantFunctionsName] 354 | 355 | function babelPluginDetectGrantFunctions(functionNamesArray) { 356 | const functionNamesSet = new Set(functionNamesArray) 357 | const detectedFunctions = new Set() 358 | function check(s) { 359 | if (functionNamesSet.has(s)) { 360 | detectedFunctions.add(s) 361 | } 362 | } 363 | 364 | return { 365 | name: babelPluginDetectGrantFunctionsName, 366 | visitor: { 367 | Identifier(path) { 368 | check(path.node.name) 369 | }, 370 | MemberExpression(path) { 371 | const memberName = `${path.node.object.name}.${path.node.property.name}` 372 | check(memberName) 373 | }, 374 | }, 375 | post(state) { 376 | state.metadata[babelPluginDetectGrantFunctionsName] = 377 | Array.from(detectedFunctions) 378 | }, 379 | } 380 | } 381 | } 382 | 383 | const ignoreSelfPlugin = { 384 | name: 'ignoreSelfPlugin', 385 | setup(build) { 386 | const tip = '这是力量的代价,不可避免 ' 387 | build.onResolve({ filter: /\/usbuild$/ }, args => { 388 | return { 389 | path: ')', 390 | namespace: tip, 391 | } 392 | }) 393 | 394 | build.onLoad({ filter: /^\)$/, namespace: tip }, () => { 395 | return { 396 | contents: `function __usbuild(){} export { __usbuild as build }`, 397 | loader: 'js', 398 | } 399 | }) 400 | }, 401 | } 402 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@linlin00/usbuild", 3 | "version": "1.10.1", 4 | "description": "Grease Monkey Script (UserScript) build tool based on esbuild", 5 | "homepage": "https://github.com/LinLin00000000/usbuild", 6 | "type": "module", 7 | "main": "index.js", 8 | "scripts": { 9 | "build": "" 10 | }, 11 | "files": [ 12 | "./index.js" 13 | ], 14 | "keywords": [ 15 | "userscript", 16 | "esbuild", 17 | "greasemonkey", 18 | "tampermonkey", 19 | "violentmonkey" 20 | ], 21 | "author": "Lin ", 22 | "license": "MIT", 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/LinLin00000000/usbuild.git" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/LinLin00000000/usbuild/issues" 29 | }, 30 | "dependencies": { 31 | "@babel/core": "^7.23.5", 32 | "esbuild": "^0.19.8", 33 | "open": "^9.1.0", 34 | "portfinder": "^1.0.32" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | '@babel/core': 9 | specifier: ^7.23.5 10 | version: 7.23.5 11 | esbuild: 12 | specifier: ^0.19.8 13 | version: 0.19.8 14 | open: 15 | specifier: ^9.1.0 16 | version: 9.1.0 17 | portfinder: 18 | specifier: ^1.0.32 19 | version: 1.0.32 20 | 21 | packages: 22 | 23 | /@ampproject/remapping@2.2.1: 24 | resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==, tarball: https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz} 25 | engines: {node: '>=6.0.0'} 26 | dependencies: 27 | '@jridgewell/gen-mapping': 0.3.3 28 | '@jridgewell/trace-mapping': 0.3.20 29 | dev: false 30 | 31 | /@babel/code-frame@7.23.5: 32 | resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==, tarball: https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.23.5.tgz} 33 | engines: {node: '>=6.9.0'} 34 | dependencies: 35 | '@babel/highlight': 7.23.4 36 | chalk: 2.4.2 37 | dev: false 38 | 39 | /@babel/compat-data@7.23.5: 40 | resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==, tarball: https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.23.5.tgz} 41 | engines: {node: '>=6.9.0'} 42 | dev: false 43 | 44 | /@babel/core@7.23.5: 45 | resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==, tarball: https://registry.npmmirror.com/@babel/core/-/core-7.23.5.tgz} 46 | engines: {node: '>=6.9.0'} 47 | dependencies: 48 | '@ampproject/remapping': 2.2.1 49 | '@babel/code-frame': 7.23.5 50 | '@babel/generator': 7.23.5 51 | '@babel/helper-compilation-targets': 7.22.15 52 | '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) 53 | '@babel/helpers': 7.23.5 54 | '@babel/parser': 7.23.5 55 | '@babel/template': 7.22.15 56 | '@babel/traverse': 7.23.5 57 | '@babel/types': 7.23.5 58 | convert-source-map: 2.0.0 59 | debug: 4.3.4 60 | gensync: 1.0.0-beta.2 61 | json5: 2.2.3 62 | semver: 6.3.1 63 | transitivePeerDependencies: 64 | - supports-color 65 | dev: false 66 | 67 | /@babel/generator@7.23.5: 68 | resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==, tarball: https://registry.npmmirror.com/@babel/generator/-/generator-7.23.5.tgz} 69 | engines: {node: '>=6.9.0'} 70 | dependencies: 71 | '@babel/types': 7.23.5 72 | '@jridgewell/gen-mapping': 0.3.3 73 | '@jridgewell/trace-mapping': 0.3.20 74 | jsesc: 2.5.2 75 | dev: false 76 | 77 | /@babel/helper-compilation-targets@7.22.15: 78 | resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==, tarball: https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz} 79 | engines: {node: '>=6.9.0'} 80 | dependencies: 81 | '@babel/compat-data': 7.23.5 82 | '@babel/helper-validator-option': 7.23.5 83 | browserslist: 4.22.2 84 | lru-cache: 5.1.1 85 | semver: 6.3.1 86 | dev: false 87 | 88 | /@babel/helper-environment-visitor@7.22.20: 89 | resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==, tarball: https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz} 90 | engines: {node: '>=6.9.0'} 91 | dev: false 92 | 93 | /@babel/helper-function-name@7.23.0: 94 | resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==, tarball: https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz} 95 | engines: {node: '>=6.9.0'} 96 | dependencies: 97 | '@babel/template': 7.22.15 98 | '@babel/types': 7.23.5 99 | dev: false 100 | 101 | /@babel/helper-hoist-variables@7.22.5: 102 | resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==, tarball: https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz} 103 | engines: {node: '>=6.9.0'} 104 | dependencies: 105 | '@babel/types': 7.23.5 106 | dev: false 107 | 108 | /@babel/helper-module-imports@7.22.15: 109 | resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==, tarball: https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz} 110 | engines: {node: '>=6.9.0'} 111 | dependencies: 112 | '@babel/types': 7.23.5 113 | dev: false 114 | 115 | /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.5): 116 | resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==, tarball: https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz} 117 | engines: {node: '>=6.9.0'} 118 | peerDependencies: 119 | '@babel/core': ^7.0.0 120 | dependencies: 121 | '@babel/core': 7.23.5 122 | '@babel/helper-environment-visitor': 7.22.20 123 | '@babel/helper-module-imports': 7.22.15 124 | '@babel/helper-simple-access': 7.22.5 125 | '@babel/helper-split-export-declaration': 7.22.6 126 | '@babel/helper-validator-identifier': 7.22.20 127 | dev: false 128 | 129 | /@babel/helper-simple-access@7.22.5: 130 | resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==, tarball: https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz} 131 | engines: {node: '>=6.9.0'} 132 | dependencies: 133 | '@babel/types': 7.23.5 134 | dev: false 135 | 136 | /@babel/helper-split-export-declaration@7.22.6: 137 | resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==, tarball: https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz} 138 | engines: {node: '>=6.9.0'} 139 | dependencies: 140 | '@babel/types': 7.23.5 141 | dev: false 142 | 143 | /@babel/helper-string-parser@7.23.4: 144 | resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz} 145 | engines: {node: '>=6.9.0'} 146 | dev: false 147 | 148 | /@babel/helper-validator-identifier@7.22.20: 149 | resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz} 150 | engines: {node: '>=6.9.0'} 151 | dev: false 152 | 153 | /@babel/helper-validator-option@7.23.5: 154 | resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==, tarball: https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz} 155 | engines: {node: '>=6.9.0'} 156 | dev: false 157 | 158 | /@babel/helpers@7.23.5: 159 | resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==, tarball: https://registry.npmmirror.com/@babel/helpers/-/helpers-7.23.5.tgz} 160 | engines: {node: '>=6.9.0'} 161 | dependencies: 162 | '@babel/template': 7.22.15 163 | '@babel/traverse': 7.23.5 164 | '@babel/types': 7.23.5 165 | transitivePeerDependencies: 166 | - supports-color 167 | dev: false 168 | 169 | /@babel/highlight@7.23.4: 170 | resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==, tarball: https://registry.npmmirror.com/@babel/highlight/-/highlight-7.23.4.tgz} 171 | engines: {node: '>=6.9.0'} 172 | dependencies: 173 | '@babel/helper-validator-identifier': 7.22.20 174 | chalk: 2.4.2 175 | js-tokens: 4.0.0 176 | dev: false 177 | 178 | /@babel/parser@7.23.5: 179 | resolution: {integrity: sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==, tarball: https://registry.npmmirror.com/@babel/parser/-/parser-7.23.5.tgz} 180 | engines: {node: '>=6.0.0'} 181 | hasBin: true 182 | dependencies: 183 | '@babel/types': 7.23.5 184 | dev: false 185 | 186 | /@babel/template@7.22.15: 187 | resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==, tarball: https://registry.npmmirror.com/@babel/template/-/template-7.22.15.tgz} 188 | engines: {node: '>=6.9.0'} 189 | dependencies: 190 | '@babel/code-frame': 7.23.5 191 | '@babel/parser': 7.23.5 192 | '@babel/types': 7.23.5 193 | dev: false 194 | 195 | /@babel/traverse@7.23.5: 196 | resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==, tarball: https://registry.npmmirror.com/@babel/traverse/-/traverse-7.23.5.tgz} 197 | engines: {node: '>=6.9.0'} 198 | dependencies: 199 | '@babel/code-frame': 7.23.5 200 | '@babel/generator': 7.23.5 201 | '@babel/helper-environment-visitor': 7.22.20 202 | '@babel/helper-function-name': 7.23.0 203 | '@babel/helper-hoist-variables': 7.22.5 204 | '@babel/helper-split-export-declaration': 7.22.6 205 | '@babel/parser': 7.23.5 206 | '@babel/types': 7.23.5 207 | debug: 4.3.4 208 | globals: 11.12.0 209 | transitivePeerDependencies: 210 | - supports-color 211 | dev: false 212 | 213 | /@babel/types@7.23.5: 214 | resolution: {integrity: sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.23.5.tgz} 215 | engines: {node: '>=6.9.0'} 216 | dependencies: 217 | '@babel/helper-string-parser': 7.23.4 218 | '@babel/helper-validator-identifier': 7.22.20 219 | to-fast-properties: 2.0.0 220 | dev: false 221 | 222 | /@esbuild/android-arm64@0.19.8: 223 | resolution: {integrity: sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==} 224 | engines: {node: '>=12'} 225 | cpu: [arm64] 226 | os: [android] 227 | requiresBuild: true 228 | dev: false 229 | optional: true 230 | 231 | /@esbuild/android-arm@0.19.8: 232 | resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==} 233 | engines: {node: '>=12'} 234 | cpu: [arm] 235 | os: [android] 236 | requiresBuild: true 237 | dev: false 238 | optional: true 239 | 240 | /@esbuild/android-x64@0.19.8: 241 | resolution: {integrity: sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==} 242 | engines: {node: '>=12'} 243 | cpu: [x64] 244 | os: [android] 245 | requiresBuild: true 246 | dev: false 247 | optional: true 248 | 249 | /@esbuild/darwin-arm64@0.19.8: 250 | resolution: {integrity: sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==} 251 | engines: {node: '>=12'} 252 | cpu: [arm64] 253 | os: [darwin] 254 | requiresBuild: true 255 | dev: false 256 | optional: true 257 | 258 | /@esbuild/darwin-x64@0.19.8: 259 | resolution: {integrity: sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==} 260 | engines: {node: '>=12'} 261 | cpu: [x64] 262 | os: [darwin] 263 | requiresBuild: true 264 | dev: false 265 | optional: true 266 | 267 | /@esbuild/freebsd-arm64@0.19.8: 268 | resolution: {integrity: sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==} 269 | engines: {node: '>=12'} 270 | cpu: [arm64] 271 | os: [freebsd] 272 | requiresBuild: true 273 | dev: false 274 | optional: true 275 | 276 | /@esbuild/freebsd-x64@0.19.8: 277 | resolution: {integrity: sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==} 278 | engines: {node: '>=12'} 279 | cpu: [x64] 280 | os: [freebsd] 281 | requiresBuild: true 282 | dev: false 283 | optional: true 284 | 285 | /@esbuild/linux-arm64@0.19.8: 286 | resolution: {integrity: sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==} 287 | engines: {node: '>=12'} 288 | cpu: [arm64] 289 | os: [linux] 290 | requiresBuild: true 291 | dev: false 292 | optional: true 293 | 294 | /@esbuild/linux-arm@0.19.8: 295 | resolution: {integrity: sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==} 296 | engines: {node: '>=12'} 297 | cpu: [arm] 298 | os: [linux] 299 | requiresBuild: true 300 | dev: false 301 | optional: true 302 | 303 | /@esbuild/linux-ia32@0.19.8: 304 | resolution: {integrity: sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==} 305 | engines: {node: '>=12'} 306 | cpu: [ia32] 307 | os: [linux] 308 | requiresBuild: true 309 | dev: false 310 | optional: true 311 | 312 | /@esbuild/linux-loong64@0.19.8: 313 | resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==} 314 | engines: {node: '>=12'} 315 | cpu: [loong64] 316 | os: [linux] 317 | requiresBuild: true 318 | dev: false 319 | optional: true 320 | 321 | /@esbuild/linux-mips64el@0.19.8: 322 | resolution: {integrity: sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==} 323 | engines: {node: '>=12'} 324 | cpu: [mips64el] 325 | os: [linux] 326 | requiresBuild: true 327 | dev: false 328 | optional: true 329 | 330 | /@esbuild/linux-ppc64@0.19.8: 331 | resolution: {integrity: sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==} 332 | engines: {node: '>=12'} 333 | cpu: [ppc64] 334 | os: [linux] 335 | requiresBuild: true 336 | dev: false 337 | optional: true 338 | 339 | /@esbuild/linux-riscv64@0.19.8: 340 | resolution: {integrity: sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==} 341 | engines: {node: '>=12'} 342 | cpu: [riscv64] 343 | os: [linux] 344 | requiresBuild: true 345 | dev: false 346 | optional: true 347 | 348 | /@esbuild/linux-s390x@0.19.8: 349 | resolution: {integrity: sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==} 350 | engines: {node: '>=12'} 351 | cpu: [s390x] 352 | os: [linux] 353 | requiresBuild: true 354 | dev: false 355 | optional: true 356 | 357 | /@esbuild/linux-x64@0.19.8: 358 | resolution: {integrity: sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==} 359 | engines: {node: '>=12'} 360 | cpu: [x64] 361 | os: [linux] 362 | requiresBuild: true 363 | dev: false 364 | optional: true 365 | 366 | /@esbuild/netbsd-x64@0.19.8: 367 | resolution: {integrity: sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==} 368 | engines: {node: '>=12'} 369 | cpu: [x64] 370 | os: [netbsd] 371 | requiresBuild: true 372 | dev: false 373 | optional: true 374 | 375 | /@esbuild/openbsd-x64@0.19.8: 376 | resolution: {integrity: sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==} 377 | engines: {node: '>=12'} 378 | cpu: [x64] 379 | os: [openbsd] 380 | requiresBuild: true 381 | dev: false 382 | optional: true 383 | 384 | /@esbuild/sunos-x64@0.19.8: 385 | resolution: {integrity: sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==} 386 | engines: {node: '>=12'} 387 | cpu: [x64] 388 | os: [sunos] 389 | requiresBuild: true 390 | dev: false 391 | optional: true 392 | 393 | /@esbuild/win32-arm64@0.19.8: 394 | resolution: {integrity: sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==} 395 | engines: {node: '>=12'} 396 | cpu: [arm64] 397 | os: [win32] 398 | requiresBuild: true 399 | dev: false 400 | optional: true 401 | 402 | /@esbuild/win32-ia32@0.19.8: 403 | resolution: {integrity: sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==} 404 | engines: {node: '>=12'} 405 | cpu: [ia32] 406 | os: [win32] 407 | requiresBuild: true 408 | dev: false 409 | optional: true 410 | 411 | /@esbuild/win32-x64@0.19.8: 412 | resolution: {integrity: sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==} 413 | engines: {node: '>=12'} 414 | cpu: [x64] 415 | os: [win32] 416 | requiresBuild: true 417 | dev: false 418 | optional: true 419 | 420 | /@jridgewell/gen-mapping@0.3.3: 421 | resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, tarball: https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz} 422 | engines: {node: '>=6.0.0'} 423 | dependencies: 424 | '@jridgewell/set-array': 1.1.2 425 | '@jridgewell/sourcemap-codec': 1.4.15 426 | '@jridgewell/trace-mapping': 0.3.20 427 | dev: false 428 | 429 | /@jridgewell/resolve-uri@3.1.1: 430 | resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==, tarball: https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz} 431 | engines: {node: '>=6.0.0'} 432 | dev: false 433 | 434 | /@jridgewell/set-array@1.1.2: 435 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, tarball: https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz} 436 | engines: {node: '>=6.0.0'} 437 | dev: false 438 | 439 | /@jridgewell/sourcemap-codec@1.4.15: 440 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==, tarball: https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz} 441 | dev: false 442 | 443 | /@jridgewell/trace-mapping@0.3.20: 444 | resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==, tarball: https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz} 445 | dependencies: 446 | '@jridgewell/resolve-uri': 3.1.1 447 | '@jridgewell/sourcemap-codec': 1.4.15 448 | dev: false 449 | 450 | /ansi-styles@3.2.1: 451 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz} 452 | engines: {node: '>=4'} 453 | dependencies: 454 | color-convert: 1.9.3 455 | dev: false 456 | 457 | /async@2.6.4: 458 | resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} 459 | dependencies: 460 | lodash: 4.17.21 461 | dev: false 462 | 463 | /big-integer@1.6.52: 464 | resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==, tarball: https://registry.npmmirror.com/big-integer/-/big-integer-1.6.52.tgz} 465 | engines: {node: '>=0.6'} 466 | dev: false 467 | 468 | /bplist-parser@0.2.0: 469 | resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==, tarball: https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz} 470 | engines: {node: '>= 5.10.0'} 471 | dependencies: 472 | big-integer: 1.6.52 473 | dev: false 474 | 475 | /browserslist@4.22.2: 476 | resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==, tarball: https://registry.npmmirror.com/browserslist/-/browserslist-4.22.2.tgz} 477 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 478 | hasBin: true 479 | dependencies: 480 | caniuse-lite: 1.0.30001565 481 | electron-to-chromium: 1.4.601 482 | node-releases: 2.0.14 483 | update-browserslist-db: 1.0.13(browserslist@4.22.2) 484 | dev: false 485 | 486 | /bundle-name@3.0.0: 487 | resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==, tarball: https://registry.npmmirror.com/bundle-name/-/bundle-name-3.0.0.tgz} 488 | engines: {node: '>=12'} 489 | dependencies: 490 | run-applescript: 5.0.0 491 | dev: false 492 | 493 | /caniuse-lite@1.0.30001565: 494 | resolution: {integrity: sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==, tarball: https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz} 495 | dev: false 496 | 497 | /chalk@2.4.2: 498 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, tarball: https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz} 499 | engines: {node: '>=4'} 500 | dependencies: 501 | ansi-styles: 3.2.1 502 | escape-string-regexp: 1.0.5 503 | supports-color: 5.5.0 504 | dev: false 505 | 506 | /color-convert@1.9.3: 507 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz} 508 | dependencies: 509 | color-name: 1.1.3 510 | dev: false 511 | 512 | /color-name@1.1.3: 513 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz} 514 | dev: false 515 | 516 | /convert-source-map@2.0.0: 517 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz} 518 | dev: false 519 | 520 | /cross-spawn@7.0.3: 521 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz} 522 | engines: {node: '>= 8'} 523 | dependencies: 524 | path-key: 3.1.1 525 | shebang-command: 2.0.0 526 | which: 2.0.2 527 | dev: false 528 | 529 | /debug@3.2.7: 530 | resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} 531 | peerDependencies: 532 | supports-color: '*' 533 | peerDependenciesMeta: 534 | supports-color: 535 | optional: true 536 | dependencies: 537 | ms: 2.1.2 538 | dev: false 539 | 540 | /debug@4.3.4: 541 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, tarball: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz} 542 | engines: {node: '>=6.0'} 543 | peerDependencies: 544 | supports-color: '*' 545 | peerDependenciesMeta: 546 | supports-color: 547 | optional: true 548 | dependencies: 549 | ms: 2.1.2 550 | dev: false 551 | 552 | /default-browser-id@3.0.0: 553 | resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==, tarball: https://registry.npmmirror.com/default-browser-id/-/default-browser-id-3.0.0.tgz} 554 | engines: {node: '>=12'} 555 | dependencies: 556 | bplist-parser: 0.2.0 557 | untildify: 4.0.0 558 | dev: false 559 | 560 | /default-browser@4.0.0: 561 | resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==, tarball: https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz} 562 | engines: {node: '>=14.16'} 563 | dependencies: 564 | bundle-name: 3.0.0 565 | default-browser-id: 3.0.0 566 | execa: 7.2.0 567 | titleize: 3.0.0 568 | dev: false 569 | 570 | /define-lazy-prop@3.0.0: 571 | resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, tarball: https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz} 572 | engines: {node: '>=12'} 573 | dev: false 574 | 575 | /electron-to-chromium@1.4.601: 576 | resolution: {integrity: sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==, tarball: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz} 577 | dev: false 578 | 579 | /esbuild@0.19.8: 580 | resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.19.8.tgz} 581 | engines: {node: '>=12'} 582 | hasBin: true 583 | requiresBuild: true 584 | optionalDependencies: 585 | '@esbuild/android-arm': 0.19.8 586 | '@esbuild/android-arm64': 0.19.8 587 | '@esbuild/android-x64': 0.19.8 588 | '@esbuild/darwin-arm64': 0.19.8 589 | '@esbuild/darwin-x64': 0.19.8 590 | '@esbuild/freebsd-arm64': 0.19.8 591 | '@esbuild/freebsd-x64': 0.19.8 592 | '@esbuild/linux-arm': 0.19.8 593 | '@esbuild/linux-arm64': 0.19.8 594 | '@esbuild/linux-ia32': 0.19.8 595 | '@esbuild/linux-loong64': 0.19.8 596 | '@esbuild/linux-mips64el': 0.19.8 597 | '@esbuild/linux-ppc64': 0.19.8 598 | '@esbuild/linux-riscv64': 0.19.8 599 | '@esbuild/linux-s390x': 0.19.8 600 | '@esbuild/linux-x64': 0.19.8 601 | '@esbuild/netbsd-x64': 0.19.8 602 | '@esbuild/openbsd-x64': 0.19.8 603 | '@esbuild/sunos-x64': 0.19.8 604 | '@esbuild/win32-arm64': 0.19.8 605 | '@esbuild/win32-ia32': 0.19.8 606 | '@esbuild/win32-x64': 0.19.8 607 | dev: false 608 | 609 | /escalade@3.1.1: 610 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, tarball: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz} 611 | engines: {node: '>=6'} 612 | dev: false 613 | 614 | /escape-string-regexp@1.0.5: 615 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz} 616 | engines: {node: '>=0.8.0'} 617 | dev: false 618 | 619 | /execa@5.1.1: 620 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, tarball: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz} 621 | engines: {node: '>=10'} 622 | dependencies: 623 | cross-spawn: 7.0.3 624 | get-stream: 6.0.1 625 | human-signals: 2.1.0 626 | is-stream: 2.0.1 627 | merge-stream: 2.0.0 628 | npm-run-path: 4.0.1 629 | onetime: 5.1.2 630 | signal-exit: 3.0.7 631 | strip-final-newline: 2.0.0 632 | dev: false 633 | 634 | /execa@7.2.0: 635 | resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==, tarball: https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz} 636 | engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} 637 | dependencies: 638 | cross-spawn: 7.0.3 639 | get-stream: 6.0.1 640 | human-signals: 4.3.1 641 | is-stream: 3.0.0 642 | merge-stream: 2.0.0 643 | npm-run-path: 5.1.0 644 | onetime: 6.0.0 645 | signal-exit: 3.0.7 646 | strip-final-newline: 3.0.0 647 | dev: false 648 | 649 | /gensync@1.0.0-beta.2: 650 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz} 651 | engines: {node: '>=6.9.0'} 652 | dev: false 653 | 654 | /get-stream@6.0.1: 655 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, tarball: https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz} 656 | engines: {node: '>=10'} 657 | dev: false 658 | 659 | /globals@11.12.0: 660 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, tarball: https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz} 661 | engines: {node: '>=4'} 662 | dev: false 663 | 664 | /has-flag@3.0.0: 665 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz} 666 | engines: {node: '>=4'} 667 | dev: false 668 | 669 | /human-signals@2.1.0: 670 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz} 671 | engines: {node: '>=10.17.0'} 672 | dev: false 673 | 674 | /human-signals@4.3.1: 675 | resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz} 676 | engines: {node: '>=14.18.0'} 677 | dev: false 678 | 679 | /is-docker@2.2.1: 680 | resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz} 681 | engines: {node: '>=8'} 682 | hasBin: true 683 | dev: false 684 | 685 | /is-docker@3.0.0: 686 | resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz} 687 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 688 | hasBin: true 689 | dev: false 690 | 691 | /is-inside-container@1.0.0: 692 | resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, tarball: https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz} 693 | engines: {node: '>=14.16'} 694 | hasBin: true 695 | dependencies: 696 | is-docker: 3.0.0 697 | dev: false 698 | 699 | /is-stream@2.0.1: 700 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz} 701 | engines: {node: '>=8'} 702 | dev: false 703 | 704 | /is-stream@3.0.0: 705 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz} 706 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 707 | dev: false 708 | 709 | /is-wsl@2.2.0: 710 | resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, tarball: https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz} 711 | engines: {node: '>=8'} 712 | dependencies: 713 | is-docker: 2.2.1 714 | dev: false 715 | 716 | /isexe@2.0.0: 717 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz} 718 | dev: false 719 | 720 | /js-tokens@4.0.0: 721 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, tarball: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz} 722 | dev: false 723 | 724 | /jsesc@2.5.2: 725 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, tarball: https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz} 726 | engines: {node: '>=4'} 727 | hasBin: true 728 | dev: false 729 | 730 | /json5@2.2.3: 731 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, tarball: https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz} 732 | engines: {node: '>=6'} 733 | hasBin: true 734 | dev: false 735 | 736 | /lodash@4.17.21: 737 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 738 | dev: false 739 | 740 | /lru-cache@5.1.1: 741 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz} 742 | dependencies: 743 | yallist: 3.1.1 744 | dev: false 745 | 746 | /merge-stream@2.0.0: 747 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, tarball: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz} 748 | dev: false 749 | 750 | /mimic-fn@2.1.0: 751 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz} 752 | engines: {node: '>=6'} 753 | dev: false 754 | 755 | /mimic-fn@4.0.0: 756 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz} 757 | engines: {node: '>=12'} 758 | dev: false 759 | 760 | /minimist@1.2.8: 761 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 762 | dev: false 763 | 764 | /mkdirp@0.5.6: 765 | resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} 766 | hasBin: true 767 | dependencies: 768 | minimist: 1.2.8 769 | dev: false 770 | 771 | /ms@2.1.2: 772 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz} 773 | dev: false 774 | 775 | /node-releases@2.0.14: 776 | resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==, tarball: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz} 777 | dev: false 778 | 779 | /npm-run-path@4.0.1: 780 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz} 781 | engines: {node: '>=8'} 782 | dependencies: 783 | path-key: 3.1.1 784 | dev: false 785 | 786 | /npm-run-path@5.1.0: 787 | resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz} 788 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 789 | dependencies: 790 | path-key: 4.0.0 791 | dev: false 792 | 793 | /onetime@5.1.2: 794 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, tarball: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz} 795 | engines: {node: '>=6'} 796 | dependencies: 797 | mimic-fn: 2.1.0 798 | dev: false 799 | 800 | /onetime@6.0.0: 801 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, tarball: https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz} 802 | engines: {node: '>=12'} 803 | dependencies: 804 | mimic-fn: 4.0.0 805 | dev: false 806 | 807 | /open@9.1.0: 808 | resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==, tarball: https://registry.npmmirror.com/open/-/open-9.1.0.tgz} 809 | engines: {node: '>=14.16'} 810 | dependencies: 811 | default-browser: 4.0.0 812 | define-lazy-prop: 3.0.0 813 | is-inside-container: 1.0.0 814 | is-wsl: 2.2.0 815 | dev: false 816 | 817 | /path-key@3.1.1: 818 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz} 819 | engines: {node: '>=8'} 820 | dev: false 821 | 822 | /path-key@4.0.0: 823 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, tarball: https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz} 824 | engines: {node: '>=12'} 825 | dev: false 826 | 827 | /picocolors@1.0.0: 828 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz} 829 | dev: false 830 | 831 | /portfinder@1.0.32: 832 | resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} 833 | engines: {node: '>= 0.12.0'} 834 | dependencies: 835 | async: 2.6.4 836 | debug: 3.2.7 837 | mkdirp: 0.5.6 838 | transitivePeerDependencies: 839 | - supports-color 840 | dev: false 841 | 842 | /run-applescript@5.0.0: 843 | resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==, tarball: https://registry.npmmirror.com/run-applescript/-/run-applescript-5.0.0.tgz} 844 | engines: {node: '>=12'} 845 | dependencies: 846 | execa: 5.1.1 847 | dev: false 848 | 849 | /semver@6.3.1: 850 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, tarball: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz} 851 | hasBin: true 852 | dev: false 853 | 854 | /shebang-command@2.0.0: 855 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz} 856 | engines: {node: '>=8'} 857 | dependencies: 858 | shebang-regex: 3.0.0 859 | dev: false 860 | 861 | /shebang-regex@3.0.0: 862 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz} 863 | engines: {node: '>=8'} 864 | dev: false 865 | 866 | /signal-exit@3.0.7: 867 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, tarball: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz} 868 | dev: false 869 | 870 | /strip-final-newline@2.0.0: 871 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz} 872 | engines: {node: '>=6'} 873 | dev: false 874 | 875 | /strip-final-newline@3.0.0: 876 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz} 877 | engines: {node: '>=12'} 878 | dev: false 879 | 880 | /supports-color@5.5.0: 881 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz} 882 | engines: {node: '>=4'} 883 | dependencies: 884 | has-flag: 3.0.0 885 | dev: false 886 | 887 | /titleize@3.0.0: 888 | resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==, tarball: https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz} 889 | engines: {node: '>=12'} 890 | dev: false 891 | 892 | /to-fast-properties@2.0.0: 893 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, tarball: https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz} 894 | engines: {node: '>=4'} 895 | dev: false 896 | 897 | /untildify@4.0.0: 898 | resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==, tarball: https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz} 899 | engines: {node: '>=8'} 900 | dev: false 901 | 902 | /update-browserslist-db@1.0.13(browserslist@4.22.2): 903 | resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==, tarball: https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz} 904 | hasBin: true 905 | peerDependencies: 906 | browserslist: '>= 4.21.0' 907 | dependencies: 908 | browserslist: 4.22.2 909 | escalade: 3.1.1 910 | picocolors: 1.0.0 911 | dev: false 912 | 913 | /which@2.0.2: 914 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmmirror.com/which/-/which-2.0.2.tgz} 915 | engines: {node: '>= 8'} 916 | hasBin: true 917 | dependencies: 918 | isexe: 2.0.0 919 | dev: false 920 | 921 | /yallist@3.1.1: 922 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, tarball: https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz} 923 | dev: false 924 | --------------------------------------------------------------------------------