├── .eslintrc.js
├── .github
├── dependabot.yml
└── workflows
│ └── publish.yml
├── .gitignore
├── .prettierrc
├── LICENSE
├── Logo.png
├── README.md
├── README_CN.md
├── bookmark
├── lib
│ └── fuse.js
├── logo.png
├── manifest.json
├── manifest_firefox.json
├── popup.html
├── popup.js
└── utils
│ ├── debounce.js
│ ├── element.js
│ ├── favicon.js
│ ├── i18n.js
│ └── notification.js
├── newtab
├── bg.json
├── logo.png
├── manifest.json
├── newtab.html
└── newtab.js
├── package.json
├── theme
└── manifest.json
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parserOptions: {
3 | ecmaVersion: 2020, // 改为ES2020
4 | sourceType: "module",
5 | },
6 | env: {
7 | browser: true,
8 | es6: true,
9 | node: true,
10 | },
11 | extends: ["eslint:recommended", "plugin:prettier/recommended", "plugin:import/errors", "plugin:import/warnings"],
12 | plugins: ["prettier", "import"],
13 | rules: {
14 | "prettier/prettier": "error",
15 | "no-useless-escape": "off",
16 | "no-undef": "off",
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "npm" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 | open-pull-requests-limit: 100
13 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: publish
2 |
3 | permissions:
4 | contents: write
5 |
6 | on:
7 | push:
8 | tags:
9 | - '*'
10 |
11 | jobs:
12 | publish:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v3
16 | with:
17 | submodules: recursive
18 |
19 | - uses: actions/setup-node@v3
20 | with:
21 | node-version: 20
22 |
23 | - name: Run install
24 | uses: borales/actions-yarn@v4
25 | with:
26 | cmd: install # will run `yarn install` command
27 |
28 | - name: Build
29 | uses: borales/actions-yarn@v4
30 | with:
31 | cmd: build
32 |
33 | - name: Create Release and Upload Release Asset
34 | uses: softprops/action-gh-release@v1
35 | with:
36 | name: Auto Release
37 | tag_name: ${{ github.ref }}
38 | body: Auto Release
39 | draft: false
40 | prerelease: false
41 | files: dist/*
42 |
43 | # - uses: wdzeng/chrome-extension@v1
44 | # with:
45 | # extension-id: lgncmpklmepncbjpiebhdoejhmbcnjad
46 | # zip-path: dist/Maple.zip
47 | # tester-only: false
48 | # client-id: ${{ secrets.CHROME_CLIENT_ID }}
49 | # client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
50 | # refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | /node_modules/
4 | /dist/
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": false,
3 | "trailingComma": "es5",
4 | "semi": true,
5 | "tabWidth": 2,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Tw93
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 |
--------------------------------------------------------------------------------
/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tw93/Maple/8e844afd83cfdccf52ae5cb83f97685838db4dd0/Logo.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
English | 中文
2 |
3 |
4 |
Maple Bookmarks
5 |
15 | Hide the bookmark bar, use Maple Bookmarks
to surf smoothly.
16 |
17 |
18 | ## Introduction
19 |
20 | The bookmarks bar can occupy the browsing window and affect concentration, so I often hide it. However, this makes accessing bookmarks inconvenient. Therefore, I developed the Maple Bookmarks extension. By just using the shortcut, you can quickly access your bookmarks, even input can be searched instantly, which is practical and convenient.
21 |
22 |
23 |
24 |
25 |
26 |
27 | 🏂 More effects can be expanded to view.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | ## Installation
42 |
43 | - Install [**Maple Bookmarks**](https://chrome.google.com/webstore/detail/maple-bookmarks/lgncmpklmepncbjpiebhdoejhmbcnjad) from the Chrome Web Store, If you are a Firefox user, please install and use [Firefox Addon](https://addons.mozilla.org/zh-CN/firefox/addon/maple-bookmarks/). If you find it useful, we'd appreciate your review.
44 | - If you're unable to access the Chrome Web Store, you can download [Maple.zip](https://github.com/tw93/Maple/releases/latest/download/Maple.zip). After unzipping, refer to [Loading an unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked) to use the local package.
45 |
46 | ## More
47 |
48 | 1. Due to Chrome's limitations, even if the bookmarks bar is hidden, it will still appear on the default tab page. At this time, you can use [Maple NewTab](https://chrome.google.com/webstore/detail/maple-newtab/fobmbldflolfooglijmbibmnhoflbjlb/related?hl=en&authuser=0) to replace the default tab page, thus completely hiding the bookmarks bar.
49 | 2. `Maple NewTab` currently supports four types of displays: `Blank pure page`,`Unsplash`,`Trendy weekly picture`, and `Bing image`. Place the cursor on the background image, wait for 2 seconds, and a switch box will appear. Click to switch.
50 | 3. If you prefer your current tab page, you can remove the `Maple NewTab` extension. This way, you can revert to the default tab page.
51 |
52 | ## White Theme
53 |
54 | Since the default new theme of Chrome is not very appealing to me, I prefer a simple and clean effect, so I developed a [Maple Theme](https://chromewebstore.google.com/detail/cghofkeabdkcdoanmjhkadklfdlelaao) on the side. It doesn't include any other messy colors, making your browser look very clean.
55 |
56 |
57 |
58 | ## Practice
59 |
60 | 1. First, organize your bookmarks. You can adjust the order of frequently used ones and delete those not often used to make it tidier.
61 | 2. Use `Command+Shift+B`(Mac)、`Ctrl+Shift+B`(Windows) or right-click on the bookmarks bar to hide it.
62 | 3. Click on the extension icon and pin `Maple Bookmarks` to the toolbar.
63 | 4. Try using `Command + E`(Mac)、`Ctrl+B`(Windows / Firefox) to quickly access your bookmarks.
64 | 5. Clicking on the folder name can collapse and expand it, making it more comfortable for users with many bookmarks to use.
65 | 6. If you have an extensive collection of bookmarks, you can conveniently search through them using keywords. The search feature supports Chinese, English, and domain names. By default, the search function is not activated. To enable it, use the `Ctrl + S` shortcut or click the small arrow located at the top of the interface to switch to search mode.
66 | 7. Each search will prioritize and display the top three most relevant results. You can easily navigate between these top results using the `←` and `→` keys on your keyboard. To swiftly access the highlighted bookmark, simply press the Enter key.
67 |
68 | ## Support
69 |
70 | 1. I have two cats, if you think Maple delights your life, you can feed them some canned food 🥩 .
71 | 2. If you like Maple, you can star it on GitHub. Also, welcome to recommend Maple to your friends.
72 | 3. You can follow my [Twitter](https://twitter.com/HiTw93) to get the latest news or join our [Telegram](https://t.me/+GclQS9ZnxyI2ODQ1) chat group.
73 |
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
枫叶书签
6 |
16 | 隐藏书签栏,使用 枫叶书签
让你行云流水。
17 |
18 |
19 | ## 介绍
20 |
21 | 书签栏会占据浏览窗口且影响专注力,我常将其隐藏。但这使得访问书签很不方便,因此我开发了枫叶书签扩展,只需使用快捷键 `Command + E`(Mac)、`Ctrl+B`(Windows) 就能快速访问书签,甚至可以输入即搜索,实用且方便。
22 |
23 |
24 |
25 |
26 |
27 |
28 | 🏂 更多效果可以展开查看
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ## 安装
43 |
44 | - 使用 Chrome Web Store 来安装 [**Maple Bookmarks**](https://chrome.google.com/webstore/detail/maple-bookmarks/lgncmpklmepncbjpiebhdoejhmbcnjad),假如你是火狐用户,请通过 [Firefox Addon](https://addons.mozilla.org/zh-CN/firefox/addon/maple-bookmarks/) 来安装使用,好用很欢迎评价。
45 | - 假如你不可访问,可以下载 [Maple.zip](https://github.com/tw93/Maple/releases/latest/download/Maple.zip),解压以后,参考 [Loading an unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked) 来使用本地包。
46 |
47 | ## 标签页
48 |
49 | 1. 由于 Chrome 的原因,即使隐藏掉书签栏,在默认标签页上还有,可以用 [Maple NewTab](https://chrome.google.com/webstore/detail/maple-newtab/fobmbldflolfooglijmbibmnhoflbjlb/related?hl=en&authuser=0) 扩展来替换掉,这样就可彻底隐藏掉书签栏了。
50 | 2. `Maple NewTab` 当前支持`空白纯净页`、`潮流周刊图`、`Bing 图`、`Unsplash` 4 种形式的效果,光标放置背景图上,等待 2s 会出现切换框,点击即可切换。
51 | 3. 假如你更喜欢现在自己的标签页,可以在扩展中移除掉 `Maple NewTab`,这样就能恢复到默认标签页了。
52 |
53 | ## 白色主题
54 |
55 | 由于Chrome的默认新主题不是很好看,我比较喜欢简单纯净的效果,就顺便开发了一个 [Maple Theme](https://chromewebstore.google.com/detail/cghofkeabdkcdoanmjhkadklfdlelaao),没有其他乱七八糟的颜色,让你的浏览器看着很干净。
56 |
57 |
58 |
59 | ## 实践
60 |
61 | 1. 先整理好书签,可以调整常用顺序以及删除不常使用的,有文件夹的放后面,让它更整齐。
62 | 2. 使用 `Command+Shift+B`(Mac)、`Ctrl+Shift+B`(Windows),或者在书签栏上右键隐藏掉书签栏。
63 | 3. 点击扩展图标,将 `Maple Bookmarks` 给固定到工具栏上。
64 | 4. 试试使用 `Command + E`(Mac)、`Ctrl+B`(Windows / Firefox) 来快速访问书签吧。
65 | 5. 点击文件夹的名称可以收起和展开,便于书签多的用户的更舒服的使用。
66 | 6. **假如你的书签很多,可以直接输入关键词来搜索,支持中文、英文、域名等**,默认不开启搜索,使用快捷键 `Ctrl + S` 或者点击界面上方小箭头打开搜索模式。
67 | 7. 每次搜索会在最上方保留最匹配的三个结果,通过键盘的 `←` 和 `→` 可以快速切换最匹配结果,`Entry` 快速打开高亮的选中书签。
68 |
69 | ## 支持
70 |
71 | 1. 我有两只猫,假如让你生活更美好,可以给猫 喂罐头 🥩 。
72 | 2. 如果你喜欢枫叶书签,可以在 Github Star 它,更欢迎推荐给你志同道合的朋友。
73 | 3. 可以关注我的 [Twitter](https://twitter.com/HiTw93) 获取到版本更新消息,也欢迎加入 [Telegram](https://t.me/+GclQS9ZnxyI2ODQ1) 聊天群。
74 |
--------------------------------------------------------------------------------
/bookmark/lib/fuse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io)
3 | *
4 | * Copyright (c) 2023 Kino Risk (http://kiro.me)
5 | * All Rights Reserved. Apache Software License 2.0
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | */
9 |
10 | function isArray(value) {
11 | return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
12 | }
13 |
14 | // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js
15 | const INFINITY = 1 / 0;
16 | function baseToString(value) {
17 | // Exit early for strings to avoid a performance hit in some environments.
18 | if (typeof value == "string") {
19 | return value;
20 | }
21 | let result = value + "";
22 | return result == "0" && 1 / value == -INFINITY ? "-0" : result;
23 | }
24 |
25 | function toString(value) {
26 | return value == null ? "" : baseToString(value);
27 | }
28 |
29 | function isString(value) {
30 | return typeof value === "string";
31 | }
32 |
33 | function isNumber(value) {
34 | return typeof value === "number";
35 | }
36 |
37 | // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js
38 | function isBoolean(value) {
39 | return value === true || value === false || (isObjectLike(value) && getTag(value) == "[object Boolean]");
40 | }
41 |
42 | function isObject(value) {
43 | return typeof value === "object";
44 | }
45 |
46 | // Checks if `value` is object-like.
47 | function isObjectLike(value) {
48 | return isObject(value) && value !== null;
49 | }
50 |
51 | function isDefined(value) {
52 | return value !== undefined && value !== null;
53 | }
54 |
55 | function isBlank(value) {
56 | return !value.trim().length;
57 | }
58 |
59 | // Gets the `toStringTag` of `value`.
60 | // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js
61 | function getTag(value) {
62 | return value == null
63 | ? value === undefined
64 | ? "[object Undefined]"
65 | : "[object Null]"
66 | : Object.prototype.toString.call(value);
67 | }
68 |
69 | const EXTENDED_SEARCH_UNAVAILABLE = "Extended search is not available";
70 |
71 | const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
72 |
73 | const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
74 |
75 | const PATTERN_LENGTH_TOO_LARGE = (max) => `Pattern length exceeds max of ${max}.`;
76 |
77 | const MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
78 |
79 | const INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
80 |
81 | const hasOwn = Object.prototype.hasOwnProperty;
82 |
83 | class KeyStore {
84 | constructor(keys) {
85 | this._keys = [];
86 | this._keyMap = {};
87 |
88 | let totalWeight = 0;
89 |
90 | keys.forEach((key) => {
91 | let obj = createKey(key);
92 |
93 | this._keys.push(obj);
94 | this._keyMap[obj.id] = obj;
95 |
96 | totalWeight += obj.weight;
97 | });
98 |
99 | // Normalize weights so that their sum is equal to 1
100 | this._keys.forEach((key) => {
101 | key.weight /= totalWeight;
102 | });
103 | }
104 | get(keyId) {
105 | return this._keyMap[keyId];
106 | }
107 | keys() {
108 | return this._keys;
109 | }
110 | toJSON() {
111 | return JSON.stringify(this._keys);
112 | }
113 | }
114 |
115 | function createKey(key) {
116 | let path = null;
117 | let id = null;
118 | let src = null;
119 | let weight = 1;
120 | let getFn = null;
121 |
122 | if (isString(key) || isArray(key)) {
123 | src = key;
124 | path = createKeyPath(key);
125 | id = createKeyId(key);
126 | } else {
127 | if (!hasOwn.call(key, "name")) {
128 | throw new Error(MISSING_KEY_PROPERTY("name"));
129 | }
130 |
131 | const name = key.name;
132 | src = name;
133 |
134 | if (hasOwn.call(key, "weight")) {
135 | weight = key.weight;
136 |
137 | if (weight <= 0) {
138 | throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
139 | }
140 | }
141 |
142 | path = createKeyPath(name);
143 | id = createKeyId(name);
144 | getFn = key.getFn;
145 | }
146 |
147 | return { path, id, weight, src, getFn };
148 | }
149 |
150 | function createKeyPath(key) {
151 | return isArray(key) ? key : key.split(".");
152 | }
153 |
154 | function createKeyId(key) {
155 | return isArray(key) ? key.join(".") : key;
156 | }
157 |
158 | function get(obj, path) {
159 | let list = [];
160 | let arr = false;
161 |
162 | const deepGet = (obj, path, index) => {
163 | if (!isDefined(obj)) {
164 | return;
165 | }
166 | if (!path[index]) {
167 | // If there's no path left, we've arrived at the object we care about.
168 | list.push(obj);
169 | } else {
170 | let key = path[index];
171 |
172 | const value = obj[key];
173 |
174 | if (!isDefined(value)) {
175 | return;
176 | }
177 |
178 | // If we're at the last value in the path, and if it's a string/number/bool,
179 | // add it to the list
180 | if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
181 | list.push(toString(value));
182 | } else if (isArray(value)) {
183 | arr = true;
184 | // Search each item in the array.
185 | for (let i = 0, len = value.length; i < len; i += 1) {
186 | deepGet(value[i], path, index + 1);
187 | }
188 | } else if (path.length) {
189 | // An object. Recurse further.
190 | deepGet(value, path, index + 1);
191 | }
192 | }
193 | };
194 |
195 | // Backwards compatibility (since path used to be a string)
196 | deepGet(obj, isString(path) ? path.split(".") : path, 0);
197 |
198 | return arr ? list : list[0];
199 | }
200 |
201 | const MatchOptions = {
202 | // Whether the matches should be included in the result set. When `true`, each record in the result
203 | // set will include the indices of the matched characters.
204 | // These can consequently be used for highlighting purposes.
205 | includeMatches: false,
206 | // When `true`, the matching function will continue to the end of a search pattern even if
207 | // a perfect match has already been located in the string.
208 | findAllMatches: false,
209 | // Minimum number of characters that must be matched before a result is considered a match
210 | minMatchCharLength: 1,
211 | };
212 |
213 | const BasicOptions = {
214 | // When `true`, the algorithm continues searching to the end of the input even if a perfect
215 | // match is found before the end of the same input.
216 | isCaseSensitive: false,
217 | // When true, the matching function will continue to the end of a search pattern even if
218 | includeScore: false,
219 | // List of properties that will be searched. This also supports nested properties.
220 | keys: [],
221 | // Whether to sort the result list, by score
222 | shouldSort: true,
223 | // Default sort function: sort by ascending score, ascending index
224 | sortFn: (a, b) => (a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1),
225 | };
226 |
227 | const FuzzyOptions = {
228 | // Approximately where in the text is the pattern expected to be found?
229 | location: 0,
230 | // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
231 | // (of both letters and location), a threshold of '1.0' would match anything.
232 | threshold: 0.6,
233 | // Determines how close the match must be to the fuzzy location (specified above).
234 | // An exact letter match which is 'distance' characters away from the fuzzy location
235 | // would score as a complete mismatch. A distance of '0' requires the match be at
236 | // the exact location specified, a threshold of '1000' would require a perfect match
237 | // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
238 | distance: 100,
239 | };
240 |
241 | const AdvancedOptions = {
242 | // When `true`, it enables the use of unix-like search commands
243 | useExtendedSearch: false,
244 | // The get function to use when fetching an object's properties.
245 | // The default will search nested paths *ie foo.bar.baz*
246 | getFn: get,
247 | // When `true`, search will ignore `location` and `distance`, so it won't matter
248 | // where in the string the pattern appears.
249 | // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score
250 | ignoreLocation: false,
251 | // When `true`, the calculation for the relevance score (used for sorting) will
252 | // ignore the field-length norm.
253 | // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm
254 | ignoreFieldNorm: false,
255 | // The weight to determine how much field length norm effects scoring.
256 | fieldNormWeight: 1,
257 | };
258 |
259 | var Config = {
260 | ...BasicOptions,
261 | ...MatchOptions,
262 | ...FuzzyOptions,
263 | ...AdvancedOptions,
264 | };
265 |
266 | const SPACE = /[^ ]+/g;
267 |
268 | // Field-length norm: the shorter the field, the higher the weight.
269 | // Set to 3 decimals to reduce index size.
270 | function norm(weight = 1, mantissa = 3) {
271 | const cache = new Map();
272 | const m = Math.pow(10, mantissa);
273 |
274 | return {
275 | get(value) {
276 | const numTokens = value.match(SPACE).length;
277 |
278 | if (cache.has(numTokens)) {
279 | return cache.get(numTokens);
280 | }
281 |
282 | // Default function is 1/sqrt(x), weight makes that variable
283 | const norm = 1 / Math.pow(numTokens, 0.5 * weight);
284 |
285 | // In place of `toFixed(mantissa)`, for faster computation
286 | const n = parseFloat(Math.round(norm * m) / m);
287 |
288 | cache.set(numTokens, n);
289 |
290 | return n;
291 | },
292 | clear() {
293 | cache.clear();
294 | },
295 | };
296 | }
297 |
298 | class FuseIndex {
299 | constructor({ getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
300 | this.norm = norm(fieldNormWeight, 3);
301 | this.getFn = getFn;
302 | this.isCreated = false;
303 |
304 | this.setIndexRecords();
305 | }
306 | setSources(docs = []) {
307 | this.docs = docs;
308 | }
309 | setIndexRecords(records = []) {
310 | this.records = records;
311 | }
312 | setKeys(keys = []) {
313 | this.keys = keys;
314 | this._keysMap = {};
315 | keys.forEach((key, idx) => {
316 | this._keysMap[key.id] = idx;
317 | });
318 | }
319 | create() {
320 | if (this.isCreated || !this.docs.length) {
321 | return;
322 | }
323 |
324 | this.isCreated = true;
325 |
326 | // List is Array
327 | if (isString(this.docs[0])) {
328 | this.docs.forEach((doc, docIndex) => {
329 | this._addString(doc, docIndex);
330 | });
331 | } else {
332 | // List is Array
333 | this.docs.forEach((doc, docIndex) => {
334 | this._addObject(doc, docIndex);
335 | });
336 | }
337 |
338 | this.norm.clear();
339 | }
340 | // Adds a doc to the end of the index
341 | add(doc) {
342 | const idx = this.size();
343 |
344 | if (isString(doc)) {
345 | this._addString(doc, idx);
346 | } else {
347 | this._addObject(doc, idx);
348 | }
349 | }
350 | // Removes the doc at the specified index of the index
351 | removeAt(idx) {
352 | this.records.splice(idx, 1);
353 |
354 | // Change ref index of every subsquent doc
355 | for (let i = idx, len = this.size(); i < len; i += 1) {
356 | this.records[i].i -= 1;
357 | }
358 | }
359 | getValueForItemAtKeyId(item, keyId) {
360 | return item[this._keysMap[keyId]];
361 | }
362 | size() {
363 | return this.records.length;
364 | }
365 | _addString(doc, docIndex) {
366 | if (!isDefined(doc) || isBlank(doc)) {
367 | return;
368 | }
369 |
370 | let record = {
371 | v: doc,
372 | i: docIndex,
373 | n: this.norm.get(doc),
374 | };
375 |
376 | this.records.push(record);
377 | }
378 | _addObject(doc, docIndex) {
379 | let record = { i: docIndex, $: {} };
380 |
381 | // Iterate over every key (i.e, path), and fetch the value at that key
382 | this.keys.forEach((key, keyIndex) => {
383 | let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
384 |
385 | if (!isDefined(value)) {
386 | return;
387 | }
388 |
389 | if (isArray(value)) {
390 | let subRecords = [];
391 | const stack = [{ nestedArrIndex: -1, value }];
392 |
393 | while (stack.length) {
394 | const { nestedArrIndex, value } = stack.pop();
395 |
396 | if (!isDefined(value)) {
397 | continue;
398 | }
399 |
400 | if (isString(value) && !isBlank(value)) {
401 | let subRecord = {
402 | v: value,
403 | i: nestedArrIndex,
404 | n: this.norm.get(value),
405 | };
406 |
407 | subRecords.push(subRecord);
408 | } else if (isArray(value)) {
409 | value.forEach((item, k) => {
410 | stack.push({
411 | nestedArrIndex: k,
412 | value: item,
413 | });
414 | });
415 | } else;
416 | }
417 | record.$[keyIndex] = subRecords;
418 | } else if (isString(value) && !isBlank(value)) {
419 | let subRecord = {
420 | v: value,
421 | n: this.norm.get(value),
422 | };
423 |
424 | record.$[keyIndex] = subRecord;
425 | }
426 | });
427 |
428 | this.records.push(record);
429 | }
430 | toJSON() {
431 | return {
432 | keys: this.keys,
433 | records: this.records,
434 | };
435 | }
436 | }
437 |
438 | function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
439 | const myIndex = new FuseIndex({ getFn, fieldNormWeight });
440 | myIndex.setKeys(keys.map(createKey));
441 | myIndex.setSources(docs);
442 | myIndex.create();
443 | return myIndex;
444 | }
445 |
446 | function parseIndex(data, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
447 | const { keys, records } = data;
448 | const myIndex = new FuseIndex({ getFn, fieldNormWeight });
449 | myIndex.setKeys(keys);
450 | myIndex.setIndexRecords(records);
451 | return myIndex;
452 | }
453 |
454 | function computeScore$1(
455 | pattern,
456 | {
457 | errors = 0,
458 | currentLocation = 0,
459 | expectedLocation = 0,
460 | distance = Config.distance,
461 | ignoreLocation = Config.ignoreLocation,
462 | } = {}
463 | ) {
464 | const accuracy = errors / pattern.length;
465 |
466 | if (ignoreLocation) {
467 | return accuracy;
468 | }
469 |
470 | const proximity = Math.abs(expectedLocation - currentLocation);
471 |
472 | if (!distance) {
473 | // Dodge divide by zero error.
474 | return proximity ? 1.0 : accuracy;
475 | }
476 |
477 | return accuracy + proximity / distance;
478 | }
479 |
480 | function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
481 | let indices = [];
482 | let start = -1;
483 | let end = -1;
484 | let i = 0;
485 |
486 | for (let len = matchmask.length; i < len; i += 1) {
487 | let match = matchmask[i];
488 | if (match && start === -1) {
489 | start = i;
490 | } else if (!match && start !== -1) {
491 | end = i - 1;
492 | if (end - start + 1 >= minMatchCharLength) {
493 | indices.push([start, end]);
494 | }
495 | start = -1;
496 | }
497 | }
498 |
499 | // (i-1 - start) + 1 => i - start
500 | if (matchmask[i - 1] && i - start >= minMatchCharLength) {
501 | indices.push([start, i - 1]);
502 | }
503 |
504 | return indices;
505 | }
506 |
507 | // Machine word size
508 | const MAX_BITS = 32;
509 |
510 | function search(
511 | text,
512 | pattern,
513 | patternAlphabet,
514 | {
515 | location = Config.location,
516 | distance = Config.distance,
517 | threshold = Config.threshold,
518 | findAllMatches = Config.findAllMatches,
519 | minMatchCharLength = Config.minMatchCharLength,
520 | includeMatches = Config.includeMatches,
521 | ignoreLocation = Config.ignoreLocation,
522 | } = {}
523 | ) {
524 | if (pattern.length > MAX_BITS) {
525 | throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
526 | }
527 |
528 | const patternLen = pattern.length;
529 | // Set starting location at beginning text and initialize the alphabet.
530 | const textLen = text.length;
531 | // Handle the case when location > text.length
532 | const expectedLocation = Math.max(0, Math.min(location, textLen));
533 | // Highest score beyond which we give up.
534 | let currentThreshold = threshold;
535 | // Is there a nearby exact match? (speedup)
536 | let bestLocation = expectedLocation;
537 |
538 | // Performance: only computer matches when the minMatchCharLength > 1
539 | // OR if `includeMatches` is true.
540 | const computeMatches = minMatchCharLength > 1 || includeMatches;
541 | // A mask of the matches, used for building the indices
542 | const matchMask = computeMatches ? Array(textLen) : [];
543 |
544 | let index;
545 |
546 | // Get all exact matches, here for speed up
547 | while ((index = text.indexOf(pattern, bestLocation)) > -1) {
548 | let score = computeScore$1(pattern, {
549 | currentLocation: index,
550 | expectedLocation,
551 | distance,
552 | ignoreLocation,
553 | });
554 |
555 | currentThreshold = Math.min(score, currentThreshold);
556 | bestLocation = index + patternLen;
557 |
558 | if (computeMatches) {
559 | let i = 0;
560 | while (i < patternLen) {
561 | matchMask[index + i] = 1;
562 | i += 1;
563 | }
564 | }
565 | }
566 |
567 | // Reset the best location
568 | bestLocation = -1;
569 |
570 | let lastBitArr = [];
571 | let finalScore = 1;
572 | let binMax = patternLen + textLen;
573 |
574 | const mask = 1 << (patternLen - 1);
575 |
576 | for (let i = 0; i < patternLen; i += 1) {
577 | // Scan for the best match; each iteration allows for one more error.
578 | // Run a binary search to determine how far from the match location we can stray
579 | // at this error level.
580 | let binMin = 0;
581 | let binMid = binMax;
582 |
583 | while (binMin < binMid) {
584 | const score = computeScore$1(pattern, {
585 | errors: i,
586 | currentLocation: expectedLocation + binMid,
587 | expectedLocation,
588 | distance,
589 | ignoreLocation,
590 | });
591 |
592 | if (score <= currentThreshold) {
593 | binMin = binMid;
594 | } else {
595 | binMax = binMid;
596 | }
597 |
598 | binMid = Math.floor((binMax - binMin) / 2 + binMin);
599 | }
600 |
601 | // Use the result from this iteration as the maximum for the next.
602 | binMax = binMid;
603 |
604 | let start = Math.max(1, expectedLocation - binMid + 1);
605 | let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
606 |
607 | // Initialize the bit array
608 | let bitArr = Array(finish + 2);
609 |
610 | bitArr[finish + 1] = (1 << i) - 1;
611 |
612 | for (let j = finish; j >= start; j -= 1) {
613 | let currentLocation = j - 1;
614 | let charMatch = patternAlphabet[text.charAt(currentLocation)];
615 |
616 | if (computeMatches) {
617 | // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)
618 | matchMask[currentLocation] = +!!charMatch;
619 | }
620 |
621 | // First pass: exact match
622 | bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch;
623 |
624 | // Subsequent passes: fuzzy match
625 | if (i) {
626 | bitArr[j] |= ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1];
627 | }
628 |
629 | if (bitArr[j] & mask) {
630 | finalScore = computeScore$1(pattern, {
631 | errors: i,
632 | currentLocation,
633 | expectedLocation,
634 | distance,
635 | ignoreLocation,
636 | });
637 |
638 | // This match will almost certainly be better than any existing match.
639 | // But check anyway.
640 | if (finalScore <= currentThreshold) {
641 | // Indeed it is
642 | currentThreshold = finalScore;
643 | bestLocation = currentLocation;
644 |
645 | // Already passed `loc`, downhill from here on in.
646 | if (bestLocation <= expectedLocation) {
647 | break;
648 | }
649 |
650 | // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.
651 | start = Math.max(1, 2 * expectedLocation - bestLocation);
652 | }
653 | }
654 | }
655 |
656 | // No hope for a (better) match at greater error levels.
657 | const score = computeScore$1(pattern, {
658 | errors: i + 1,
659 | currentLocation: expectedLocation,
660 | expectedLocation,
661 | distance,
662 | ignoreLocation,
663 | });
664 |
665 | if (score > currentThreshold) {
666 | break;
667 | }
668 |
669 | lastBitArr = bitArr;
670 | }
671 |
672 | const result = {
673 | isMatch: bestLocation >= 0,
674 | // Count exact matches (those with a score of 0) to be "almost" exact
675 | score: Math.max(0.001, finalScore),
676 | };
677 |
678 | if (computeMatches) {
679 | const indices = convertMaskToIndices(matchMask, minMatchCharLength);
680 | if (!indices.length) {
681 | result.isMatch = false;
682 | } else if (includeMatches) {
683 | result.indices = indices;
684 | }
685 | }
686 |
687 | return result;
688 | }
689 |
690 | function createPatternAlphabet(pattern) {
691 | let mask = {};
692 |
693 | for (let i = 0, len = pattern.length; i < len; i += 1) {
694 | const char = pattern.charAt(i);
695 | mask[char] = (mask[char] || 0) | (1 << (len - i - 1));
696 | }
697 |
698 | return mask;
699 | }
700 |
701 | class BitapSearch {
702 | constructor(
703 | pattern,
704 | {
705 | location = Config.location,
706 | threshold = Config.threshold,
707 | distance = Config.distance,
708 | includeMatches = Config.includeMatches,
709 | findAllMatches = Config.findAllMatches,
710 | minMatchCharLength = Config.minMatchCharLength,
711 | isCaseSensitive = Config.isCaseSensitive,
712 | ignoreLocation = Config.ignoreLocation,
713 | } = {}
714 | ) {
715 | this.options = {
716 | location,
717 | threshold,
718 | distance,
719 | includeMatches,
720 | findAllMatches,
721 | minMatchCharLength,
722 | isCaseSensitive,
723 | ignoreLocation,
724 | };
725 |
726 | this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
727 |
728 | this.chunks = [];
729 |
730 | if (!this.pattern.length) {
731 | return;
732 | }
733 |
734 | const addChunk = (pattern, startIndex) => {
735 | this.chunks.push({
736 | pattern,
737 | alphabet: createPatternAlphabet(pattern),
738 | startIndex,
739 | });
740 | };
741 |
742 | const len = this.pattern.length;
743 |
744 | if (len > MAX_BITS) {
745 | let i = 0;
746 | const remainder = len % MAX_BITS;
747 | const end = len - remainder;
748 |
749 | while (i < end) {
750 | addChunk(this.pattern.substr(i, MAX_BITS), i);
751 | i += MAX_BITS;
752 | }
753 |
754 | if (remainder) {
755 | const startIndex = len - MAX_BITS;
756 | addChunk(this.pattern.substr(startIndex), startIndex);
757 | }
758 | } else {
759 | addChunk(this.pattern, 0);
760 | }
761 | }
762 |
763 | searchIn(text) {
764 | const { isCaseSensitive, includeMatches } = this.options;
765 |
766 | if (!isCaseSensitive) {
767 | text = text.toLowerCase();
768 | }
769 |
770 | // Exact match
771 | if (this.pattern === text) {
772 | let result = {
773 | isMatch: true,
774 | score: 0,
775 | };
776 |
777 | if (includeMatches) {
778 | result.indices = [[0, text.length - 1]];
779 | }
780 |
781 | return result;
782 | }
783 |
784 | // Otherwise, use Bitap algorithm
785 | const { location, distance, threshold, findAllMatches, minMatchCharLength, ignoreLocation } = this.options;
786 |
787 | let allIndices = [];
788 | let totalScore = 0;
789 | let hasMatches = false;
790 |
791 | this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
792 | const { isMatch, score, indices } = search(text, pattern, alphabet, {
793 | location: location + startIndex,
794 | distance,
795 | threshold,
796 | findAllMatches,
797 | minMatchCharLength,
798 | includeMatches,
799 | ignoreLocation,
800 | });
801 |
802 | if (isMatch) {
803 | hasMatches = true;
804 | }
805 |
806 | totalScore += score;
807 |
808 | if (isMatch && indices) {
809 | allIndices = [...allIndices, ...indices];
810 | }
811 | });
812 |
813 | let result = {
814 | isMatch: hasMatches,
815 | score: hasMatches ? totalScore / this.chunks.length : 1,
816 | };
817 |
818 | if (hasMatches && includeMatches) {
819 | result.indices = allIndices;
820 | }
821 |
822 | return result;
823 | }
824 | }
825 |
826 | class BaseMatch {
827 | constructor(pattern) {
828 | this.pattern = pattern;
829 | }
830 | static isMultiMatch(pattern) {
831 | return getMatch(pattern, this.multiRegex);
832 | }
833 | static isSingleMatch(pattern) {
834 | return getMatch(pattern, this.singleRegex);
835 | }
836 | search(/*text*/) {}
837 | }
838 |
839 | function getMatch(pattern, exp) {
840 | const matches = pattern.match(exp);
841 | return matches ? matches[1] : null;
842 | }
843 |
844 | // Token: 'file
845 |
846 | class ExactMatch extends BaseMatch {
847 | constructor(pattern) {
848 | super(pattern);
849 | }
850 | static get type() {
851 | return "exact";
852 | }
853 | static get multiRegex() {
854 | return /^="(.*)"$/;
855 | }
856 | static get singleRegex() {
857 | return /^=(.*)$/;
858 | }
859 | search(text) {
860 | const isMatch = text === this.pattern;
861 |
862 | return {
863 | isMatch,
864 | score: isMatch ? 0 : 1,
865 | indices: [0, this.pattern.length - 1],
866 | };
867 | }
868 | }
869 |
870 | // Token: !fire
871 |
872 | class InverseExactMatch extends BaseMatch {
873 | constructor(pattern) {
874 | super(pattern);
875 | }
876 | static get type() {
877 | return "inverse-exact";
878 | }
879 | static get multiRegex() {
880 | return /^!"(.*)"$/;
881 | }
882 | static get singleRegex() {
883 | return /^!(.*)$/;
884 | }
885 | search(text) {
886 | const index = text.indexOf(this.pattern);
887 | const isMatch = index === -1;
888 |
889 | return {
890 | isMatch,
891 | score: isMatch ? 0 : 1,
892 | indices: [0, text.length - 1],
893 | };
894 | }
895 | }
896 |
897 | // Token: ^file
898 |
899 | class PrefixExactMatch extends BaseMatch {
900 | constructor(pattern) {
901 | super(pattern);
902 | }
903 | static get type() {
904 | return "prefix-exact";
905 | }
906 | static get multiRegex() {
907 | return /^\^"(.*)"$/;
908 | }
909 | static get singleRegex() {
910 | return /^\^(.*)$/;
911 | }
912 | search(text) {
913 | const isMatch = text.startsWith(this.pattern);
914 |
915 | return {
916 | isMatch,
917 | score: isMatch ? 0 : 1,
918 | indices: [0, this.pattern.length - 1],
919 | };
920 | }
921 | }
922 |
923 | // Token: !^fire
924 |
925 | class InversePrefixExactMatch extends BaseMatch {
926 | constructor(pattern) {
927 | super(pattern);
928 | }
929 | static get type() {
930 | return "inverse-prefix-exact";
931 | }
932 | static get multiRegex() {
933 | return /^!\^"(.*)"$/;
934 | }
935 | static get singleRegex() {
936 | return /^!\^(.*)$/;
937 | }
938 | search(text) {
939 | const isMatch = !text.startsWith(this.pattern);
940 |
941 | return {
942 | isMatch,
943 | score: isMatch ? 0 : 1,
944 | indices: [0, text.length - 1],
945 | };
946 | }
947 | }
948 |
949 | // Token: .file$
950 |
951 | class SuffixExactMatch extends BaseMatch {
952 | constructor(pattern) {
953 | super(pattern);
954 | }
955 | static get type() {
956 | return "suffix-exact";
957 | }
958 | static get multiRegex() {
959 | return /^"(.*)"\$$/;
960 | }
961 | static get singleRegex() {
962 | return /^(.*)\$$/;
963 | }
964 | search(text) {
965 | const isMatch = text.endsWith(this.pattern);
966 |
967 | return {
968 | isMatch,
969 | score: isMatch ? 0 : 1,
970 | indices: [text.length - this.pattern.length, text.length - 1],
971 | };
972 | }
973 | }
974 |
975 | // Token: !.file$
976 |
977 | class InverseSuffixExactMatch extends BaseMatch {
978 | constructor(pattern) {
979 | super(pattern);
980 | }
981 | static get type() {
982 | return "inverse-suffix-exact";
983 | }
984 | static get multiRegex() {
985 | return /^!"(.*)"\$$/;
986 | }
987 | static get singleRegex() {
988 | return /^!(.*)\$$/;
989 | }
990 | search(text) {
991 | const isMatch = !text.endsWith(this.pattern);
992 | return {
993 | isMatch,
994 | score: isMatch ? 0 : 1,
995 | indices: [0, text.length - 1],
996 | };
997 | }
998 | }
999 |
1000 | class FuzzyMatch extends BaseMatch {
1001 | constructor(
1002 | pattern,
1003 | {
1004 | location = Config.location,
1005 | threshold = Config.threshold,
1006 | distance = Config.distance,
1007 | includeMatches = Config.includeMatches,
1008 | findAllMatches = Config.findAllMatches,
1009 | minMatchCharLength = Config.minMatchCharLength,
1010 | isCaseSensitive = Config.isCaseSensitive,
1011 | ignoreLocation = Config.ignoreLocation,
1012 | } = {}
1013 | ) {
1014 | super(pattern);
1015 | this._bitapSearch = new BitapSearch(pattern, {
1016 | location,
1017 | threshold,
1018 | distance,
1019 | includeMatches,
1020 | findAllMatches,
1021 | minMatchCharLength,
1022 | isCaseSensitive,
1023 | ignoreLocation,
1024 | });
1025 | }
1026 | static get type() {
1027 | return "fuzzy";
1028 | }
1029 | static get multiRegex() {
1030 | return /^"(.*)"$/;
1031 | }
1032 | static get singleRegex() {
1033 | return /^(.*)$/;
1034 | }
1035 | search(text) {
1036 | return this._bitapSearch.searchIn(text);
1037 | }
1038 | }
1039 |
1040 | // Token: 'file
1041 |
1042 | class IncludeMatch extends BaseMatch {
1043 | constructor(pattern) {
1044 | super(pattern);
1045 | }
1046 | static get type() {
1047 | return "include";
1048 | }
1049 | static get multiRegex() {
1050 | return /^'"(.*)"$/;
1051 | }
1052 | static get singleRegex() {
1053 | return /^'(.*)$/;
1054 | }
1055 | search(text) {
1056 | let location = 0;
1057 | let index;
1058 |
1059 | const indices = [];
1060 | const patternLen = this.pattern.length;
1061 |
1062 | // Get all exact matches
1063 | while ((index = text.indexOf(this.pattern, location)) > -1) {
1064 | location = index + patternLen;
1065 | indices.push([index, location - 1]);
1066 | }
1067 |
1068 | const isMatch = !!indices.length;
1069 |
1070 | return {
1071 | isMatch,
1072 | score: isMatch ? 0 : 1,
1073 | indices,
1074 | };
1075 | }
1076 | }
1077 |
1078 | // ❗Order is important. DO NOT CHANGE.
1079 | const searchers = [
1080 | ExactMatch,
1081 | IncludeMatch,
1082 | PrefixExactMatch,
1083 | InversePrefixExactMatch,
1084 | InverseSuffixExactMatch,
1085 | SuffixExactMatch,
1086 | InverseExactMatch,
1087 | FuzzyMatch,
1088 | ];
1089 |
1090 | const searchersLen = searchers.length;
1091 |
1092 | // Regex to split by spaces, but keep anything in quotes together
1093 | const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
1094 | const OR_TOKEN = "|";
1095 |
1096 | // Return a 2D array representation of the query, for simpler parsing.
1097 | // Example:
1098 | // "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]]
1099 | function parseQuery(pattern, options = {}) {
1100 | return pattern.split(OR_TOKEN).map((item) => {
1101 | let query = item
1102 | .trim()
1103 | .split(SPACE_RE)
1104 | .filter((item) => item && !!item.trim());
1105 |
1106 | let results = [];
1107 | for (let i = 0, len = query.length; i < len; i += 1) {
1108 | const queryItem = query[i];
1109 |
1110 | // 1. Handle multiple query match (i.e, once that are quoted, like `"hello world"`)
1111 | let found = false;
1112 | let idx = -1;
1113 | while (!found && ++idx < searchersLen) {
1114 | const searcher = searchers[idx];
1115 | let token = searcher.isMultiMatch(queryItem);
1116 | if (token) {
1117 | results.push(new searcher(token, options));
1118 | found = true;
1119 | }
1120 | }
1121 |
1122 | if (found) {
1123 | continue;
1124 | }
1125 |
1126 | // 2. Handle single query matches (i.e, once that are *not* quoted)
1127 | idx = -1;
1128 | while (++idx < searchersLen) {
1129 | const searcher = searchers[idx];
1130 | let token = searcher.isSingleMatch(queryItem);
1131 | if (token) {
1132 | results.push(new searcher(token, options));
1133 | break;
1134 | }
1135 | }
1136 | }
1137 |
1138 | return results;
1139 | });
1140 | }
1141 |
1142 | // These extended matchers can return an array of matches, as opposed
1143 | // to a singl match
1144 | const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);
1145 |
1146 | /**
1147 | * Command-like searching
1148 | * ======================
1149 | *
1150 | * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,
1151 | * search in a given text.
1152 | *
1153 | * Search syntax:
1154 | *
1155 | * | Token | Match type | Description |
1156 | * | ----------- | -------------------------- | -------------------------------------- |
1157 | * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |
1158 | * | `=scheme` | exact-match | Items that are `scheme` |
1159 | * | `'python` | include-match | Items that include `python` |
1160 | * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |
1161 | * | `^java` | prefix-exact-match | Items that start with `java` |
1162 | * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |
1163 | * | `.js$` | suffix-exact-match | Items that end with `.js` |
1164 | * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |
1165 | *
1166 | * A single pipe character acts as an OR operator. For example, the following
1167 | * query matches entries that start with `core` and end with either`go`, `rb`,
1168 | * or`py`.
1169 | *
1170 | * ```
1171 | * ^core go$ | rb$ | py$
1172 | * ```
1173 | */
1174 | class ExtendedSearch {
1175 | constructor(
1176 | pattern,
1177 | {
1178 | isCaseSensitive = Config.isCaseSensitive,
1179 | includeMatches = Config.includeMatches,
1180 | minMatchCharLength = Config.minMatchCharLength,
1181 | ignoreLocation = Config.ignoreLocation,
1182 | findAllMatches = Config.findAllMatches,
1183 | location = Config.location,
1184 | threshold = Config.threshold,
1185 | distance = Config.distance,
1186 | } = {}
1187 | ) {
1188 | this.query = null;
1189 | this.options = {
1190 | isCaseSensitive,
1191 | includeMatches,
1192 | minMatchCharLength,
1193 | findAllMatches,
1194 | ignoreLocation,
1195 | location,
1196 | threshold,
1197 | distance,
1198 | };
1199 |
1200 | this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
1201 | this.query = parseQuery(this.pattern, this.options);
1202 | }
1203 |
1204 | static condition(_, options) {
1205 | return options.useExtendedSearch;
1206 | }
1207 |
1208 | searchIn(text) {
1209 | const query = this.query;
1210 |
1211 | if (!query) {
1212 | return {
1213 | isMatch: false,
1214 | score: 1,
1215 | };
1216 | }
1217 |
1218 | const { includeMatches, isCaseSensitive } = this.options;
1219 |
1220 | text = isCaseSensitive ? text : text.toLowerCase();
1221 |
1222 | let numMatches = 0;
1223 | let allIndices = [];
1224 | let totalScore = 0;
1225 |
1226 | // ORs
1227 | for (let i = 0, qLen = query.length; i < qLen; i += 1) {
1228 | const searchers = query[i];
1229 |
1230 | // Reset indices
1231 | allIndices.length = 0;
1232 | numMatches = 0;
1233 |
1234 | // ANDs
1235 | for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {
1236 | const searcher = searchers[j];
1237 | const { isMatch, indices, score } = searcher.search(text);
1238 |
1239 | if (isMatch) {
1240 | numMatches += 1;
1241 | totalScore += score;
1242 | if (includeMatches) {
1243 | const type = searcher.constructor.type;
1244 | if (MultiMatchSet.has(type)) {
1245 | allIndices = [...allIndices, ...indices];
1246 | } else {
1247 | allIndices.push(indices);
1248 | }
1249 | }
1250 | } else {
1251 | totalScore = 0;
1252 | numMatches = 0;
1253 | allIndices.length = 0;
1254 | break;
1255 | }
1256 | }
1257 |
1258 | // OR condition, so if TRUE, return
1259 | if (numMatches) {
1260 | let result = {
1261 | isMatch: true,
1262 | score: totalScore / numMatches,
1263 | };
1264 |
1265 | if (includeMatches) {
1266 | result.indices = allIndices;
1267 | }
1268 |
1269 | return result;
1270 | }
1271 | }
1272 |
1273 | // Nothing was matched
1274 | return {
1275 | isMatch: false,
1276 | score: 1,
1277 | };
1278 | }
1279 | }
1280 |
1281 | const registeredSearchers = [];
1282 |
1283 | function register(...args) {
1284 | registeredSearchers.push(...args);
1285 | }
1286 |
1287 | function createSearcher(pattern, options) {
1288 | for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
1289 | let searcherClass = registeredSearchers[i];
1290 | if (searcherClass.condition(pattern, options)) {
1291 | return new searcherClass(pattern, options);
1292 | }
1293 | }
1294 |
1295 | return new BitapSearch(pattern, options);
1296 | }
1297 |
1298 | const LogicalOperator = {
1299 | AND: "$and",
1300 | OR: "$or",
1301 | };
1302 |
1303 | const KeyType = {
1304 | PATH: "$path",
1305 | PATTERN: "$val",
1306 | };
1307 |
1308 | const isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
1309 |
1310 | const isPath = (query) => !!query[KeyType.PATH];
1311 |
1312 | const isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
1313 |
1314 | const convertToExplicit = (query) => ({
1315 | [LogicalOperator.AND]: Object.keys(query).map((key) => ({
1316 | [key]: query[key],
1317 | })),
1318 | });
1319 |
1320 | // When `auto` is `true`, the parse function will infer and initialize and add
1321 | // the appropriate `Searcher` instance
1322 | function parse(query, options, { auto = true } = {}) {
1323 | const next = (query) => {
1324 | let keys = Object.keys(query);
1325 |
1326 | const isQueryPath = isPath(query);
1327 |
1328 | if (!isQueryPath && keys.length > 1 && !isExpression(query)) {
1329 | return next(convertToExplicit(query));
1330 | }
1331 |
1332 | if (isLeaf(query)) {
1333 | const key = isQueryPath ? query[KeyType.PATH] : keys[0];
1334 |
1335 | const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key];
1336 |
1337 | if (!isString(pattern)) {
1338 | throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
1339 | }
1340 |
1341 | const obj = {
1342 | keyId: createKeyId(key),
1343 | pattern,
1344 | };
1345 |
1346 | if (auto) {
1347 | obj.searcher = createSearcher(pattern, options);
1348 | }
1349 |
1350 | return obj;
1351 | }
1352 |
1353 | let node = {
1354 | children: [],
1355 | operator: keys[0],
1356 | };
1357 |
1358 | keys.forEach((key) => {
1359 | const value = query[key];
1360 |
1361 | if (isArray(value)) {
1362 | value.forEach((item) => {
1363 | node.children.push(next(item));
1364 | });
1365 | }
1366 | });
1367 |
1368 | return node;
1369 | };
1370 |
1371 | if (!isExpression(query)) {
1372 | query = convertToExplicit(query);
1373 | }
1374 |
1375 | return next(query);
1376 | }
1377 |
1378 | // Practical scoring function
1379 | function computeScore(results, { ignoreFieldNorm = Config.ignoreFieldNorm }) {
1380 | results.forEach((result) => {
1381 | let totalScore = 1;
1382 |
1383 | result.matches.forEach(({ key, norm, score }) => {
1384 | const weight = key ? key.weight : null;
1385 |
1386 | totalScore *= Math.pow(
1387 | score === 0 && weight ? Number.EPSILON : score,
1388 | (weight || 1) * (ignoreFieldNorm ? 1 : norm)
1389 | );
1390 | });
1391 |
1392 | result.score = totalScore;
1393 | });
1394 | }
1395 |
1396 | function transformMatches(result, data) {
1397 | const matches = result.matches;
1398 | data.matches = [];
1399 |
1400 | if (!isDefined(matches)) {
1401 | return;
1402 | }
1403 |
1404 | matches.forEach((match) => {
1405 | if (!isDefined(match.indices) || !match.indices.length) {
1406 | return;
1407 | }
1408 |
1409 | const { indices, value } = match;
1410 |
1411 | let obj = {
1412 | indices,
1413 | value,
1414 | };
1415 |
1416 | if (match.key) {
1417 | obj.key = match.key.src;
1418 | }
1419 |
1420 | if (match.idx > -1) {
1421 | obj.refIndex = match.idx;
1422 | }
1423 |
1424 | data.matches.push(obj);
1425 | });
1426 | }
1427 |
1428 | function transformScore(result, data) {
1429 | data.score = result.score;
1430 | }
1431 |
1432 | function format(results, docs, { includeMatches = Config.includeMatches, includeScore = Config.includeScore } = {}) {
1433 | const transformers = [];
1434 |
1435 | if (includeMatches) transformers.push(transformMatches);
1436 | if (includeScore) transformers.push(transformScore);
1437 |
1438 | return results.map((result) => {
1439 | const { idx } = result;
1440 |
1441 | const data = {
1442 | item: docs[idx],
1443 | refIndex: idx,
1444 | };
1445 |
1446 | if (transformers.length) {
1447 | transformers.forEach((transformer) => {
1448 | transformer(result, data);
1449 | });
1450 | }
1451 |
1452 | return data;
1453 | });
1454 | }
1455 |
1456 | class Fuse {
1457 | constructor(docs, options = {}, index) {
1458 | this.options = { ...Config, ...options };
1459 |
1460 | if (this.options.useExtendedSearch && !true) {
1461 | throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
1462 | }
1463 |
1464 | this._keyStore = new KeyStore(this.options.keys);
1465 |
1466 | this.setCollection(docs, index);
1467 | }
1468 |
1469 | setCollection(docs, index) {
1470 | this._docs = docs;
1471 |
1472 | if (index && !(index instanceof FuseIndex)) {
1473 | throw new Error(INCORRECT_INDEX_TYPE);
1474 | }
1475 |
1476 | this._myIndex =
1477 | index ||
1478 | createIndex(this.options.keys, this._docs, {
1479 | getFn: this.options.getFn,
1480 | fieldNormWeight: this.options.fieldNormWeight,
1481 | });
1482 | }
1483 |
1484 | add(doc) {
1485 | if (!isDefined(doc)) {
1486 | return;
1487 | }
1488 |
1489 | this._docs.push(doc);
1490 | this._myIndex.add(doc);
1491 | }
1492 |
1493 | remove(predicate = (/* doc, idx */) => false) {
1494 | const results = [];
1495 |
1496 | for (let i = 0, len = this._docs.length; i < len; i += 1) {
1497 | const doc = this._docs[i];
1498 | if (predicate(doc, i)) {
1499 | this.removeAt(i);
1500 | i -= 1;
1501 | len -= 1;
1502 |
1503 | results.push(doc);
1504 | }
1505 | }
1506 |
1507 | return results;
1508 | }
1509 |
1510 | removeAt(idx) {
1511 | this._docs.splice(idx, 1);
1512 | this._myIndex.removeAt(idx);
1513 | }
1514 |
1515 | getIndex() {
1516 | return this._myIndex;
1517 | }
1518 |
1519 | search(query, { limit = -1 } = {}) {
1520 | const { includeMatches, includeScore, shouldSort, sortFn, ignoreFieldNorm } = this.options;
1521 |
1522 | let results = isString(query)
1523 | ? isString(this._docs[0])
1524 | ? this._searchStringList(query)
1525 | : this._searchObjectList(query)
1526 | : this._searchLogical(query);
1527 |
1528 | computeScore(results, { ignoreFieldNorm });
1529 |
1530 | if (shouldSort) {
1531 | results.sort(sortFn);
1532 | }
1533 |
1534 | if (isNumber(limit) && limit > -1) {
1535 | results = results.slice(0, limit);
1536 | }
1537 |
1538 | return format(results, this._docs, {
1539 | includeMatches,
1540 | includeScore,
1541 | });
1542 | }
1543 |
1544 | _searchStringList(query) {
1545 | const searcher = createSearcher(query, this.options);
1546 | const { records } = this._myIndex;
1547 | const results = [];
1548 |
1549 | // Iterate over every string in the index
1550 | records.forEach(({ v: text, i: idx, n: norm }) => {
1551 | if (!isDefined(text)) {
1552 | return;
1553 | }
1554 |
1555 | const { isMatch, score, indices } = searcher.searchIn(text);
1556 |
1557 | if (isMatch) {
1558 | results.push({
1559 | item: text,
1560 | idx,
1561 | matches: [{ score, value: text, norm, indices }],
1562 | });
1563 | }
1564 | });
1565 |
1566 | return results;
1567 | }
1568 |
1569 | _searchLogical(query) {
1570 | const expression = parse(query, this.options);
1571 |
1572 | const evaluate = (node, item, idx) => {
1573 | if (!node.children) {
1574 | const { keyId, searcher } = node;
1575 |
1576 | const matches = this._findMatches({
1577 | key: this._keyStore.get(keyId),
1578 | value: this._myIndex.getValueForItemAtKeyId(item, keyId),
1579 | searcher,
1580 | });
1581 |
1582 | if (matches && matches.length) {
1583 | return [
1584 | {
1585 | idx,
1586 | item,
1587 | matches,
1588 | },
1589 | ];
1590 | }
1591 |
1592 | return [];
1593 | }
1594 |
1595 | const res = [];
1596 | for (let i = 0, len = node.children.length; i < len; i += 1) {
1597 | const child = node.children[i];
1598 | const result = evaluate(child, item, idx);
1599 | if (result.length) {
1600 | res.push(...result);
1601 | } else if (node.operator === LogicalOperator.AND) {
1602 | return [];
1603 | }
1604 | }
1605 | return res;
1606 | };
1607 |
1608 | const records = this._myIndex.records;
1609 | const resultMap = {};
1610 | const results = [];
1611 |
1612 | records.forEach(({ $: item, i: idx }) => {
1613 | if (isDefined(item)) {
1614 | let expResults = evaluate(expression, item, idx);
1615 |
1616 | if (expResults.length) {
1617 | // Dedupe when adding
1618 | if (!resultMap[idx]) {
1619 | resultMap[idx] = { idx, item, matches: [] };
1620 | results.push(resultMap[idx]);
1621 | }
1622 | expResults.forEach(({ matches }) => {
1623 | resultMap[idx].matches.push(...matches);
1624 | });
1625 | }
1626 | }
1627 | });
1628 |
1629 | return results;
1630 | }
1631 |
1632 | _searchObjectList(query) {
1633 | const searcher = createSearcher(query, this.options);
1634 | const { keys, records } = this._myIndex;
1635 | const results = [];
1636 |
1637 | // List is Array
1638 | records.forEach(({ $: item, i: idx }) => {
1639 | if (!isDefined(item)) {
1640 | return;
1641 | }
1642 |
1643 | let matches = [];
1644 |
1645 | // Iterate over every key (i.e, path), and fetch the value at that key
1646 | keys.forEach((key, keyIndex) => {
1647 | matches.push(
1648 | ...this._findMatches({
1649 | key,
1650 | value: item[keyIndex],
1651 | searcher,
1652 | })
1653 | );
1654 | });
1655 |
1656 | if (matches.length) {
1657 | results.push({
1658 | idx,
1659 | item,
1660 | matches,
1661 | });
1662 | }
1663 | });
1664 |
1665 | return results;
1666 | }
1667 | _findMatches({ key, value, searcher }) {
1668 | if (!isDefined(value)) {
1669 | return [];
1670 | }
1671 |
1672 | let matches = [];
1673 |
1674 | if (isArray(value)) {
1675 | value.forEach(({ v: text, i: idx, n: norm }) => {
1676 | if (!isDefined(text)) {
1677 | return;
1678 | }
1679 |
1680 | const { isMatch, score, indices } = searcher.searchIn(text);
1681 |
1682 | if (isMatch) {
1683 | matches.push({
1684 | score,
1685 | key,
1686 | value: text,
1687 | idx,
1688 | norm,
1689 | indices,
1690 | });
1691 | }
1692 | });
1693 | } else {
1694 | const { v: text, n: norm } = value;
1695 |
1696 | const { isMatch, score, indices } = searcher.searchIn(text);
1697 |
1698 | if (isMatch) {
1699 | matches.push({ score, key, value: text, norm, indices });
1700 | }
1701 | }
1702 |
1703 | return matches;
1704 | }
1705 | }
1706 |
1707 | Fuse.version = "6.6.2";
1708 | Fuse.createIndex = createIndex;
1709 | Fuse.parseIndex = parseIndex;
1710 | Fuse.config = Config;
1711 |
1712 | {
1713 | Fuse.parseQuery = parse;
1714 | }
1715 |
1716 | {
1717 | register(ExtendedSearch);
1718 | }
1719 |
1720 | export { Fuse as default };
1721 |
--------------------------------------------------------------------------------
/bookmark/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tw93/Maple/8e844afd83cfdccf52ae5cb83f97685838db4dd0/bookmark/logo.png
--------------------------------------------------------------------------------
/bookmark/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Maple Bookmarks",
4 | "description": "Let you navigate smoothly while hiding the bookmark bar.",
5 | "version": "1.10",
6 | "action": {
7 | "default_popup": "popup.html"
8 | },
9 | "commands": {
10 | "_execute_action": {
11 | "suggested_key": {
12 | "default": "Ctrl+E",
13 | "mac": "Command+E"
14 | }
15 | }
16 | },
17 | "optional_host_permissions": ["*://*/*"],
18 | "permissions": ["bookmarks", "favicon"],
19 | "icons": {
20 | "16": "logo.png",
21 | "48": "logo.png",
22 | "128": "logo.png"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/bookmark/manifest_firefox.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Maple Bookmarks",
4 | "description": "Let you navigate smoothly while hiding the bookmark bar.",
5 | "version": "1.10",
6 | "action": {
7 | "default_popup": "popup.html"
8 | },
9 | "commands": {
10 | "_execute_action": {
11 | "suggested_key": {
12 | "default": "Ctrl+E"
13 | }
14 | }
15 | },
16 | "browser_specific_settings": {
17 | "gecko": {
18 | "id": "tw93@qq.com"
19 | }
20 | },
21 | "optional_host_permissions": ["*://*/*"],
22 | "permissions": ["bookmarks", "favicon"],
23 | "icons": {
24 | "16": "logo.png",
25 | "48": "logo.png",
26 | "128": "logo.png"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/bookmark/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Maple Bookmarks
6 |
240 |
241 |
242 |
243 |
244 |
245 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
--------------------------------------------------------------------------------
/bookmark/popup.js:
--------------------------------------------------------------------------------
1 | import Fuse from "./lib/fuse.js";
2 | import { debounce } from "./utils/debounce.js";
3 | import {
4 | keyText,
5 | BestMatchTitle,
6 | LastBestMatch,
7 | BestMatch,
8 | EmptyBookmarkMessage,
9 | ShowSearchWrapper,
10 | HideSearchWrapper,
11 | } from "./utils/i18n.js";
12 | import { Notification } from "./utils/notification.js";
13 | import { createElement } from "./utils/element.js";
14 | import { getFavicon } from "./utils/favicon.js";
15 |
16 | const CLASS_NAMES = {
17 | bookmark: "bookmark",
18 | favicon: "favicon",
19 | folder: "folder",
20 | childContainer: "childContainer",
21 | Notification: "Notification",
22 | folderTitle: "folderTitle",
23 | };
24 |
25 | let folderCount;
26 |
27 | let searchInput = document.getElementById("searchInput");
28 | let hideArrow = document.querySelector(".search-action");
29 | let hideArrowIcon = document.querySelector(".search-action i");
30 | let hotArea = document.querySelector("#hot-area");
31 |
32 | let activeBestMatchIndex = 0;
33 | let hideTimeout = null;
34 | let searchIsHide = !(localStorage.getItem("SHOW_SEARCH_BAR") === "true");
35 |
36 | let bestMatches = [];
37 | // 恢复 header 元素
38 | updateHeader(JSON.parse(localStorage.getItem("persistedHeader")), true);
39 | updateActiveBestMatch(activeBestMatchIndex);
40 |
41 | /**
42 | * @description 使用 Fuse 进行模糊匹配,返回最佳匹配项或false
43 | * @param searchTerm {string} 查询的字符串
44 | * @param data {{ title: string, url: string, favicon: string }[]} 要匹配的 对象数组,包含 title 和 url 属性
45 | * @returns {{ title: string, url: string, favicon: string }[]|null} 返回最佳匹配项的 对象数组 或 null
46 | */
47 | function FuseStrMatch(searchTerm, data) {
48 | const options = {
49 | keys: ["title", "url"],
50 | ignoreLocation: false, // 全搜索
51 | includeScore: true, // 包含相似度评分
52 | threshold: 0.5, // 相似度阈值
53 | shouldSort: true, // 是否排序
54 | };
55 | const fuse = new Fuse(data, options);
56 | const results = fuse.search(searchTerm);
57 | const cache = new Map();
58 | const noRepeatResult = results.reduce((acc, bookmark) => {
59 | if (cache.has(bookmark.item.url)) {
60 | return acc;
61 | } else {
62 | cache.set(bookmark.item.url, true);
63 | return [...acc, bookmark];
64 | }
65 | }, []);
66 |
67 | return results.length > 0 ? noRepeatResult.slice(0, 3).map(({ item }) => item) : null;
68 | }
69 |
70 | /**
71 | * 切换 searchBar 显示状态
72 | */
73 | function switchSearchBarShowStatus() {
74 | searchIsHide = !searchIsHide;
75 | localStorage.setItem("SHOW_SEARCH_BAR", searchIsHide ? "false" : "true");
76 | const extraClass = searchIsHide ? "" : "show";
77 | const container = document.querySelector("#search-wrapper");
78 | // 有一个8px的间距,所以减去8
79 | const containerHeight = container.clientHeight - 8;
80 | const bookmarksContainer = document.querySelector("#bookmarks");
81 | if (container) {
82 | container.classList.remove("show");
83 | if (extraClass) {
84 | container.classList.add(extraClass);
85 | bookmarksContainer.style.transform = `translateY(0)`;
86 | searchInput.focus();
87 | hotArea.style.display = "none";
88 | } else {
89 | bookmarksContainer.style.transform = `translateY(-${containerHeight}px)`;
90 | hotArea.style.display = "block";
91 | }
92 | }
93 | }
94 |
95 | /**
96 | * @description 快速切换默认选中的最佳结果
97 | * @param index {number} 要选中的索引
98 | */
99 | function updateActiveBestMatch(index) {
100 | const bestMatch = Array.from(document.querySelectorAll("#best-match .bookmark"));
101 | if (bestMatch.length === 0) {
102 | return;
103 | }
104 | bestMatch.forEach((item) => item.classList.remove("active"));
105 | // 循环切换
106 | activeBestMatchIndex = index % bestMatch.length < 0 ? bestMatch.length - 1 : index % bestMatch.length;
107 | bestMatch[activeBestMatchIndex].classList.add("active");
108 | }
109 |
110 | /**
111 | * 获取当前选中的最佳匹配项
112 | * @returns {HTMLElement} 当前选中的最佳匹配项
113 | */
114 | function getActiveBestMatch() {
115 | const bestMatch = Array.from(document.querySelectorAll("#best-match .bookmark"));
116 | return bestMatch[activeBestMatchIndex];
117 | }
118 |
119 | function showBestMatchTips() {
120 | const curBestMathEle = getActiveBestMatch();
121 | const tipsCon = curBestMathEle.querySelector("p");
122 | if (checkOverflow(tipsCon)) {
123 | Notification.show(bestMatches[activeBestMatchIndex].title, 1500);
124 | }
125 | }
126 |
127 | /**
128 | * @description 更新 header 的内容,如果匹配失败则不更新
129 | * @param headerFuzeMatch {{ title: string, url: string, favicon: string }[]|null} 匹配到的 对象数组 或 null
130 | * @param init {boolean} 是否是初始化
131 | */
132 | function updateHeader(headerFuzeMatch, init = false) {
133 | if (!headerFuzeMatch) {
134 | return;
135 | }
136 | // 兼容旧版本,上一个版本 headerFuzeMatch 为单个对象
137 | if (!Array.isArray(headerFuzeMatch)) {
138 | headerFuzeMatch = Array.from(headerFuzeMatch);
139 | }
140 | const matchedBookmark = document.querySelector("#best-match .folder");
141 | if (matchedBookmark) {
142 | matchedBookmark.parentElement.removeChild(matchedBookmark);
143 | }
144 | const bestMatchFolder = createElement("div", CLASS_NAMES.folder);
145 | const childContainer = createElement("div", CLASS_NAMES.childContainer);
146 | const title = createElement("h2", "", init ? LastBestMatch : BestMatch);
147 | title.title = BestMatchTitle;
148 | headerFuzeMatch.map((matchedBookmark) => {
149 | createBookmarkItem(matchedBookmark, childContainer);
150 | });
151 | bestMatchFolder.appendChild(title);
152 | bestMatchFolder.appendChild(childContainer);
153 | bestMatches = headerFuzeMatch;
154 |
155 | localStorage.setItem("persistedHeader", JSON.stringify(headerFuzeMatch));
156 | document.querySelector("#best-match").appendChild(bestMatchFolder);
157 | updateActiveBestMatch(0);
158 | }
159 |
160 | /**
161 | * 检测文本是否溢出
162 | * @param {HTMLElement} el 检测溢出的元素
163 | * @returns
164 | */
165 | function checkOverflow(el) {
166 | const curOverflow = el.style.overflow;
167 |
168 | if (!curOverflow || curOverflow === "visible") el.style.overflow = "hidden";
169 |
170 | const isOverflowing = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;
171 |
172 | el.style.overflow = curOverflow;
173 |
174 | return isOverflowing;
175 | }
176 |
177 | searchInput.addEventListener(
178 | "input",
179 | debounce(function () {
180 | let searchTerm = searchInput.value.toLowerCase();
181 | let folders = document.getElementsByClassName(CLASS_NAMES.folder);
182 |
183 | const headerData = [];
184 |
185 | for (let folder of folders) {
186 | let bookmarks = folder.getElementsByClassName(CLASS_NAMES.bookmark);
187 | let hasVisibleBookmark = false;
188 |
189 | for (let bookmark of bookmarks) {
190 | // push 查询数据
191 | headerData.push({
192 | title: bookmark.textContent,
193 | url: bookmark.href,
194 | favicon: bookmark.querySelector(".favicon")?.src,
195 | });
196 |
197 | let title = bookmark.textContent.toLowerCase();
198 | let url = bookmark.href.toLowerCase();
199 |
200 | // 当直接匹配失败时,使用模糊匹配
201 | if (
202 | title.includes(searchTerm) ||
203 | url.includes(searchTerm) ||
204 | FuseStrMatch(searchTerm, [
205 | {
206 | title: title,
207 | url: url,
208 | favicon: "",
209 | },
210 | ])
211 | ) {
212 | bookmark.style.display = "flex";
213 | hasVisibleBookmark = true;
214 | } else {
215 | bookmark.style.display = "none";
216 | }
217 | }
218 |
219 | folder.style.display = hasVisibleBookmark ? "block" : "none";
220 | }
221 |
222 | updateHeader(FuseStrMatch(searchTerm, headerData));
223 | }, 30)
224 | );
225 |
226 | // fix under mask click
227 | document.addEventListener("click", function (e) {
228 | const underMaskEle = [...document.elementsFromPoint(e.clientX, e.clientY)].find(
229 | (el) =>
230 | (el.classList.contains("search-action") || el.classList.contains(CLASS_NAMES.folderTitle)) &&
231 | e.target.id === "hot-area"
232 | );
233 | if (underMaskEle) {
234 | const clickEvent = new CustomEvent("click", {
235 | detail: {},
236 | });
237 | underMaskEle.dispatchEvent(clickEvent);
238 | }
239 | });
240 |
241 | hideArrow.addEventListener("click", function () {
242 | switchSearchBarShowStatus();
243 | if (!searchIsHide) {
244 | searchInput.focus();
245 | }
246 | });
247 |
248 | hideArrowIcon.addEventListener("mouseover", function () {
249 | const tips = searchIsHide ? ShowSearchWrapper : HideSearchWrapper;
250 | Notification.show(tips);
251 | });
252 |
253 | hideArrowIcon.addEventListener("mouseleave", function () {
254 | Notification.hide();
255 | });
256 |
257 | window.addEventListener("keydown", function (event) {
258 | if (event.key === "Escape") {
259 | event.preventDefault();
260 | searchInput.value = "";
261 |
262 | let bookmarks = document.getElementsByClassName(CLASS_NAMES.bookmark);
263 | let folders = document.getElementsByClassName(CLASS_NAMES.folder);
264 |
265 | for (let bookmark of bookmarks) {
266 | bookmark.style.display = "flex";
267 | }
268 |
269 | for (let folder of folders) {
270 | folder.style.display = "block";
271 | }
272 | }
273 |
274 | if (event.key === "ArrowLeft") {
275 | if (searchIsHide) return;
276 | updateActiveBestMatch(activeBestMatchIndex - 1);
277 | showBestMatchTips();
278 | }
279 |
280 | if (event.key === "ArrowRight") {
281 | if (searchIsHide) return;
282 | updateActiveBestMatch(activeBestMatchIndex + 1);
283 | showBestMatchTips();
284 | }
285 |
286 | if (event.key === "Enter") {
287 | event.preventDefault();
288 | if (bestMatches.length !== 0) {
289 | chrome.tabs.create({ url: bestMatches[activeBestMatchIndex].url });
290 | }
291 | }
292 |
293 | if (event.ctrlKey && event.key === "s") {
294 | event.preventDefault();
295 | switchSearchBarShowStatus();
296 | }
297 | });
298 |
299 | window.onload = async function () {
300 | setBodyHeightFromStorage();
301 |
302 | const bookmarkTreeNodes = await chrome.bookmarks.getTree();
303 | folderCount = countFolders(bookmarkTreeNodes[0].children);
304 | const container = document.querySelector("#search-wrapper");
305 | const bookmarksContainer = document.querySelector("#bookmarks");
306 |
307 | createBookmarks(bookmarkTreeNodes);
308 | setTimeout(saveCurrentHeight, 600);
309 |
310 | if (searchIsHide) {
311 | // -8 是因为有 8px 的 margin
312 | const searchBarContainerHeight = container.clientHeight - 8;
313 | bookmarksContainer.style.transform = `translateY(-${searchBarContainerHeight}px)`;
314 | hotArea.style.display = "block";
315 | } else {
316 | container.classList.add("show");
317 | bookmarksContainer.style.transform = `translateY(-8)`;
318 | searchInput.focus();
319 | hotArea.style.display = "none";
320 | }
321 | // delay to add transition animation to stop initial animation
322 | setTimeout(() => {
323 | container.style.transition = "all .3s ease";
324 | bookmarksContainer.style.transition = "all .3s ease";
325 | }, 100);
326 | };
327 |
328 | function setBodyHeightFromStorage() {
329 | let savedHeight = localStorage.getItem("savedHeight");
330 | if (savedHeight && savedHeight > 30) {
331 | document.body.style.height = `${savedHeight}px`;
332 | if (savedHeight > 618) {
333 | document.body.style.height = "618px";
334 | }
335 | }
336 | }
337 |
338 | function saveCurrentHeight() {
339 | let currentHeight = document.getElementById("bookmarks").clientHeight;
340 | localStorage.setItem("savedHeight", (currentHeight - 8).toString());
341 | }
342 |
343 | function createBookmarks(bookmarkTreeNodes) {
344 | const bookmarksContainer = document.getElementById("bookmarks");
345 |
346 | if (folderCount === 0) {
347 | showEmptyBookmarkMessage();
348 | } else {
349 | showBookmarks(bookmarkTreeNodes, bookmarksContainer);
350 | }
351 | bindSwitchModeToFirstFolder();
352 | }
353 |
354 | function bindSwitchModeToFirstFolder() {
355 | const hotArea = document.querySelector("#hot-area");
356 | const searchWrapper = document.querySelector("#search-wrapper");
357 | const arrow = document.querySelector(".arrow");
358 | hotArea.addEventListener("mouseover", () => {
359 | arrow.style.opacity = 1;
360 | searchWrapper.style.marginTop = 0;
361 | });
362 |
363 | hotArea.addEventListener("mouseleave", () => {
364 | arrow.style.opacity = 0;
365 | searchWrapper.style.marginTop = "-30px";
366 | });
367 | }
368 |
369 | function showEmptyBookmarkMessage() {
370 | const bookmarksContainer = document.getElementById("bookmarks");
371 | const messageElement = createElement("p", "message", EmptyBookmarkMessage);
372 |
373 | bookmarksContainer.appendChild(messageElement);
374 | }
375 |
376 | function showBookmarks(bookmarkNodes, parent, parentTitle = []) {
377 | if (!bookmarkNodes || !bookmarkNodes.length) {
378 | return;
379 | }
380 | // 优先显示书签,再显示文件夹
381 | const bookmarkItems = bookmarkNodes.filter((node) => node.url);
382 | bookmarkItems.forEach((bookmarkNode) => {
383 | createBookmarkItem(bookmarkNode, parent);
384 | });
385 |
386 | const bookmarkFolders = bookmarkNodes.filter((node) => node.children && node.children.length > 0);
387 | bookmarkFolders.forEach((bookmarkNode) => {
388 | createFolderForBookmarks(bookmarkNode, parent, parentTitle);
389 | });
390 | }
391 |
392 | function createBookmarkItem(bookmarkNode, parent) {
393 | let favicon = createElement("img", CLASS_NAMES.favicon);
394 | favicon.src = getFavicon(bookmarkNode.url);
395 |
396 | let bookItem = createElement("a", CLASS_NAMES.bookmark);
397 | bookItem.href = bookmarkNode.url;
398 | bookItem.target = "_blank";
399 | bookItem.appendChild(favicon);
400 |
401 | bookItem.addEventListener("click", function (event) {
402 | if (bookmarkNode.url.startsWith("chrome://") || bookmarkNode.url.startsWith("edge://")) {
403 | event.preventDefault();
404 | if (typeof browser !== "undefined") {
405 | // Firefox
406 | browser.tabs.create({ url: bookmarkNode.url });
407 | } else {
408 | // Chrome
409 | chrome.tabs.create({ url: bookmarkNode.url });
410 | }
411 | }
412 | });
413 |
414 | let linkTitle = createElement("p", "", bookmarkNode.title ? bookmarkNode.title : getTitleFromUrl(bookmarkNode.url));
415 | bookItem.appendChild(linkTitle);
416 |
417 | let mouseleaveHandler = function () {
418 | if (hideTimeout) {
419 | clearTimeout(hideTimeout);
420 | hideTimeout = null;
421 | }
422 | // 在mouseleave事件中,设置一个延时,然后隐藏Notification
423 | hideTimeout = setTimeout(() => {
424 | Notification.hide();
425 | }, 500);
426 | };
427 |
428 | bookItem.addEventListener("mouseover", function () {
429 | // 只有在文本溢出的时候才做处理
430 | if (checkOverflow(linkTitle)) {
431 | // 如果已经计划了隐藏通知的操作,取消它
432 | if (hideTimeout) {
433 | clearTimeout(hideTimeout);
434 | hideTimeout = null;
435 | }
436 | Notification.show(bookmarkNode.title);
437 | }
438 | });
439 |
440 | bookItem.addEventListener("mouseleave", mouseleaveHandler);
441 |
442 | parent.appendChild(bookItem);
443 | }
444 |
445 | function createFolderForBookmarks(bookmarkNode, parent, parentTitle = []) {
446 | let folder = createElement("div", CLASS_NAMES.folder);
447 | let childContainer = createElement("div", CLASS_NAMES.childContainer);
448 | // 递归传递父级的 title
449 | const title = [...parentTitle];
450 | title.push(bookmarkNode.title);
451 | // 如果文件夹下有书签,则显示标题,否则如全是文件夹则不显示
452 | if (bookmarkNode.children?.filter((node) => node.url).length > 0) {
453 | if (folderCount > 1 && bookmarkNode.title) {
454 | let folderName = bookmarkNode.title;
455 | // 如果是多级目录,则在标题前面加上父级目录
456 | if (title.length > 2) {
457 | for (let i = title.length - 2; i > 1; i--) {
458 | folderName = title[i] + " / " + folderName;
459 | }
460 | }
461 |
462 | let folderTitle = createElement("h2", CLASS_NAMES.folderTitle, folderName);
463 |
464 | if (bookmarkNode.title !== "Favorites Bar" && bookmarkNode.title !== "收藏夹栏") {
465 | folderTitle.title = keyText;
466 | folderTitle.style.cursor = "pointer";
467 |
468 | // 判断是否在之前被收起来了
469 | if (localStorage.getItem(bookmarkNode.title) === "collapsed") {
470 | childContainer.style.display = "none";
471 | }
472 |
473 | folderTitle.addEventListener("click", function (event) {
474 | // 为展开/收起添加事件
475 | if (childContainer.style.display === "none") {
476 | childContainer.style.display = "flex";
477 | localStorage.setItem(bookmarkNode.title, "expanded");
478 | } else {
479 | childContainer.style.display = "none";
480 | localStorage.setItem(bookmarkNode.title, "collapsed");
481 | }
482 |
483 | // 如果按住 ctrl 或 meta 键(Mac上的command键)则批量打开书签
484 | if (event.ctrlKey || event.metaKey) {
485 | for (let childNode of bookmarkNode.children) {
486 | if (childNode.url) {
487 | chrome.tabs.create({ url: childNode.url });
488 | }
489 | }
490 | event.preventDefault();
491 | }
492 | });
493 | }
494 |
495 | folder.appendChild(folderTitle);
496 | } else {
497 | folder.style.marginTop = "8px";
498 | }
499 | }
500 |
501 | showBookmarks(bookmarkNode.children, childContainer, title);
502 |
503 | folder.appendChild(childContainer);
504 | parent.appendChild(folder);
505 | }
506 |
507 | function countFolders(bookmarkNodes) {
508 | let count = 0;
509 | for (let i = 0; i < bookmarkNodes.length; i++) {
510 | if (bookmarkNodes[i].children && bookmarkNodes[i].children.length > 0) {
511 | count += 1 + countFolders(bookmarkNodes[i].children);
512 | }
513 | }
514 | return count;
515 | }
516 |
517 | function getTitleFromUrl(url) {
518 | if (url.startsWith("chrome://") || url.startsWith("edge://") || url.startsWith("about:")) {
519 | return url.split("//")[1].split("/")[0].charAt(0).toUpperCase() + url.split("//")[1].split("/")[0].slice(1);
520 | }
521 |
522 | let host = new URL(url).host;
523 | let parts = host.startsWith("www.") ? host.split(".")[1] : host.split(".")[0];
524 |
525 | return parts.charAt(0).toUpperCase() + parts.slice(1);
526 | }
527 |
--------------------------------------------------------------------------------
/bookmark/utils/debounce.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @description: 防抖函数装饰器
3 | * @param func {function} 要防抖的函数
4 | * @param wait {number} 延迟执行毫秒数
5 | * @param immediate {boolean} true 表立即执行,false 表非立即执行
6 | * @returns {function} 返回一个防抖函数
7 | */
8 | function debounce(func, wait, immediate = false) {
9 | let timeout, args, context, timestamp, result;
10 | if (null == wait) wait = 100;
11 |
12 | function later() {
13 | const last = Date.now() - timestamp;
14 |
15 | if (last < wait && last >= 0) {
16 | timeout = setTimeout(later, wait - last);
17 | } else {
18 | timeout = null;
19 | if (!immediate) {
20 | result = func.apply(context, args);
21 | context = args = null;
22 | }
23 | }
24 | }
25 |
26 | const debounced = function () {
27 | context = this;
28 | args = arguments;
29 | timestamp = Date.now();
30 | const callNow = immediate && !timeout;
31 | if (!timeout) timeout = setTimeout(later, wait);
32 | if (callNow) {
33 | result = func.apply(context, args);
34 | context = args = null;
35 | }
36 |
37 | return result;
38 | };
39 |
40 | debounced.clear = function () {
41 | if (timeout) {
42 | clearTimeout(timeout);
43 | timeout = null;
44 | }
45 | };
46 |
47 | debounced.flush = function () {
48 | if (timeout) {
49 | result = func.apply(context, args);
50 | context = args = null;
51 |
52 | clearTimeout(timeout);
53 | timeout = null;
54 | }
55 | };
56 |
57 | return debounced;
58 | }
59 |
60 | export { debounce };
61 |
--------------------------------------------------------------------------------
/bookmark/utils/element.js:
--------------------------------------------------------------------------------
1 | export function createElement(type, className, textContent = "") {
2 | let element = document.createElement(type);
3 | element.className = className;
4 | element.textContent = textContent;
5 | return element;
6 | }
7 |
--------------------------------------------------------------------------------
/bookmark/utils/favicon.js:
--------------------------------------------------------------------------------
1 | export function getFavicon(url) {
2 | const isFirefox = navigator.userAgent.includes("Firefox");
3 | if (isFirefox) {
4 | return `http://www.google.com/s2/favicons?domain_url=${url}`;
5 | }
6 | return `${chrome.runtime.getURL("/_favicon?")}pageUrl=${encodeURIComponent(url)}&size=32`;
7 | }
8 |
--------------------------------------------------------------------------------
/bookmark/utils/i18n.js:
--------------------------------------------------------------------------------
1 | const browserLanguage = navigator.language.startsWith("zh") ? "zh" : "en";
2 | const isZh = browserLanguage === "zh";
3 |
4 | document.getElementById("searchInput").placeholder = isZh ? "搜索书签..." : "Search Bookmarks...";
5 |
6 | const isMac = navigator.platform.indexOf("Mac") !== -1;
7 |
8 | const keyHint = isMac ? "Command" : "Ctrl";
9 | const keyText = isZh
10 | ? `按住 ${keyHint} 可批量打开,点击可收起`
11 | : `Hold ${keyHint} and click to open all, Click to collapse.`;
12 |
13 | const BestMatchTitle = isZh ? "按 Enter 打开选中项" : "Press Enter to open the selected item";
14 |
15 | const LastBestMatch = isZh ? "上次最佳匹配" : "Last Best Match";
16 | const BestMatch = isZh ? "最佳匹配" : "Best Match";
17 |
18 | const EmptyBookmarkMessage = isZh ? "🍁 没有找到书签" : "🍁 No bookmarks in the current browser";
19 |
20 | const ShowSearchWrapper = isZh ? "显示搜索框,试试 Ctrl + S" : "Show Search Box, Try Ctrl + S";
21 | const HideSearchWrapper = isZh ? "隐藏搜索框,试试 Ctrl + S" : "Hide Search Box, Try Ctrl + S";
22 |
23 | export {
24 | keyText,
25 | BestMatchTitle,
26 | LastBestMatch,
27 | BestMatch,
28 | EmptyBookmarkMessage,
29 | ShowSearchWrapper,
30 | HideSearchWrapper,
31 | };
32 |
--------------------------------------------------------------------------------
/bookmark/utils/notification.js:
--------------------------------------------------------------------------------
1 | export const Notification = {
2 | timer: null,
3 | /**
4 | * 展示 notification
5 | * @param {string} message notification message
6 | * @param {boolean} hideTime auto hide time
7 | */
8 | show(message, hideTime = 0) {
9 | const container = document.querySelector("#notification-container");
10 | container.style.transform = `translateX(-105%)`;
11 | container.textContent = message;
12 | container.style.transform = `translateX(0)`;
13 | if (hideTime > 0) {
14 | if (this.timer) {
15 | clearTimeout(this.timer);
16 | }
17 | this.timer = setTimeout(() => {
18 | clearTimeout(this.timer);
19 | this.hide();
20 | }, hideTime);
21 | }
22 | },
23 | /**
24 | * 移除 notification
25 | *
26 | */
27 | hide() {
28 | const container = document.querySelector("#notification-container");
29 | container.style.transform = `translateX(-105%)`;
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/newtab/bg.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "不天黑的乌鲁木齐",
4 | "url": "https://weekly.tw93.fun/posts/30-不天黑的乌鲁木齐",
5 | "date": "2021/06/07",
6 | "pic": "https://gw.alipayobjects.com/zos/k/c1/IMG_4854.jpeg"
7 | },
8 | {
9 | "title": "西湖音乐节",
10 | "url": "https://weekly.tw93.fun/posts/105-西湖音乐节",
11 | "date": "2023/07/28",
12 | "pic": "https://gw.alipayobjects.com/zos/k/7i/IMG_1730.jpg"
13 | },
14 | {
15 | "title": "飞檐走壁的人",
16 | "url": "https://weekly.tw93.fun/posts/25-飞檐走壁的人",
17 | "date": "2021/05/03",
18 | "pic": "https://gw.alipayobjects.com/zos/k/29/ZoRs7B.jpg"
19 | },
20 | {
21 | "title": "一群笔直的树",
22 | "url": "https://weekly.tw93.fun/posts/41-一群笔直的树",
23 | "date": "2021/08/23",
24 | "pic": "https://gw.alipayobjects.com/zos/k/66/qsyH2T.jpg"
25 | },
26 | {
27 | "title": "无争的灵隐寺",
28 | "url": "https://weekly.tw93.fun/posts/42-无争的灵隐寺",
29 | "date": "2021/08/30",
30 | "pic": "https://gw.alipayobjects.com/zos/k/10/MRNoEz.jpg"
31 | },
32 | {
33 | "title": "2022蜡梅",
34 | "url": "https://weekly.tw93.fun/posts/62-2022蜡梅",
35 | "date": "2022/01/17",
36 | "pic": "https://gw.alipayobjects.com/zos/k/px/Ty4WR3.jpg"
37 | },
38 | {
39 | "title": "太湖湾音乐节",
40 | "url": "https://weekly.tw93.fun/posts/87-太湖湾音乐节",
41 | "date": "2022/07/11",
42 | "pic": "https://gw.alipayobjects.com/zos/k/ha/87.jpg"
43 | },
44 | {
45 | "title": "东海音乐节",
46 | "url": "https://weekly.tw93.fun/posts/04-东海音乐节",
47 | "date": "2020/12/07",
48 | "pic": "https://gw.alipayobjects.com/zos/k/t9/xOtN9c.jpg"
49 | },
50 | {
51 | "title": "万石植物园",
52 | "url": "https://weekly.tw93.fun/posts/03-万石植物园",
53 | "date": "2020/11/30",
54 | "pic": "https://gw.alipayobjects.com/zos/k/vt/QzwRSt.png"
55 | },
56 | {
57 | "title": "白云滑雪场",
58 | "url": "https://weekly.tw93.fun/posts/06-白云滑雪场",
59 | "date": "2020/12/21",
60 | "pic": "https://gw.alipayobjects.com/zos/k/o3/ZebwPr.jpg"
61 | },
62 | {
63 | "title": "重庆洪崖洞",
64 | "url": "https://weekly.tw93.fun/posts/07-重庆洪崖洞",
65 | "date": "2020/12/28",
66 | "pic": "https://gw.alipayobjects.com/zos/k/26/INUqPy.jpg"
67 | },
68 | {
69 | "title": "新疆的雪山",
70 | "url": "https://weekly.tw93.fun/posts/10-新疆的雪山",
71 | "date": "2021/01/18",
72 | "pic": "https://gw.alipayobjects.com/zos/k/fk/frrlJj.png"
73 | },
74 | {
75 | "title": "茶山的树",
76 | "url": "https://weekly.tw93.fun/posts/103-茶山的树",
77 | "date": "2023/07/28",
78 | "pic": "https://gw.alipayobjects.com/zos/k/app/IMG_1385.jpg"
79 | },
80 | {
81 | "title": "可爱松鼠",
82 | "url": "https://weekly.tw93.fun/posts/104-可爱松鼠",
83 | "date": "2023/07/28",
84 | "pic": "https://gw.alipayobjects.com/zos/k/zn/yPL9km.jpg"
85 | },
86 | {
87 | "title": "海南度假",
88 | "url": "https://weekly.tw93.fun/posts/106-海南度假",
89 | "date": "2023/07/28",
90 | "pic": "https://gw.alipayobjects.com/zos/k/cz/IMG_2262.JPG"
91 | },
92 | {
93 | "title": "沙巴理发",
94 | "url": "https://weekly.tw93.fun/posts/108-沙巴理发",
95 | "date": "2023/07/28",
96 | "pic": "https://gw.alipayobjects.com/zos/k/j8/ORG_DSC01420.jpg"
97 | },
98 | {
99 | "title": "大阪夜景",
100 | "url": "https://weekly.tw93.fun/posts/110-大阪夜景",
101 | "date": "2023/07/28",
102 | "pic": "https://gw.alipayobjects.com/zos/k/pr/110.JPG"
103 | },
104 | {
105 | "title": "新年追日",
106 | "url": "https://weekly.tw93.fun/posts/111-新年追日",
107 | "date": "2023/07/28",
108 | "pic": "https://gw.alipayobjects.com/zos/k/b4/111.jpg"
109 | },
110 | {
111 | "title": "咖啡店猫",
112 | "url": "https://weekly.tw93.fun/posts/112-咖啡店猫",
113 | "date": "2023/07/28",
114 | "pic": "https://gw.alipayobjects.com/zos/k/gx/112.jpg"
115 | },
116 | {
117 | "title": "猫的克隆",
118 | "url": "https://weekly.tw93.fun/posts/113-猫的克隆",
119 | "date": "2023/07/28",
120 | "pic": "https://gw.alipayobjects.com/zos/k/1o/113.jpg"
121 | },
122 | {
123 | "title": "冬季新疆",
124 | "url": "https://weekly.tw93.fun/posts/114-冬季新疆",
125 | "date": "2023/07/28",
126 | "pic": "https://gw.alipayobjects.com/zos/k/14/114.jpg"
127 | },
128 | {
129 | "title": "一江两岸",
130 | "url": "https://weekly.tw93.fun/posts/115-一江两岸",
131 | "date": "2023/07/28",
132 | "pic": "https://gw.alipayobjects.com/zos/k/9v/115.jpg"
133 | },
134 | {
135 | "title": "赤道夜景",
136 | "url": "https://weekly.tw93.fun/posts/122-赤道夜景",
137 | "date": "2023/07/28",
138 | "pic": "https://gw.alipayobjects.com/zos/k/g7s5ul/122.jpg"
139 | },
140 | {
141 | "title": "杭州新绿",
142 | "url": "https://weekly.tw93.fun/posts/123-杭州新绿",
143 | "date": "2023/07/28",
144 | "pic": "https://gw.alipayobjects.com/zos/k/q4/123.jpg"
145 | },
146 | {
147 | "title": "忆泸沽湖",
148 | "url": "https://weekly.tw93.fun/posts/124-忆泸沽湖",
149 | "date": "2023/07/28",
150 | "pic": "https://gw.alipayobjects.com/zos/k/w4/DSC06324.jpg"
151 | },
152 | {
153 | "title": "零点西湖",
154 | "url": "https://weekly.tw93.fun/posts/127-零点西湖",
155 | "date": "2023/07/28",
156 | "pic": "https://gw.alipayobjects.com/zos/k/9e/127.jpg"
157 | },
158 | {
159 | "title": "良渚的树",
160 | "url": "https://weekly.tw93.fun/posts/128-良渚的树",
161 | "date": "2023/07/28",
162 | "pic": "https://gw.alipayobjects.com/zos/k/ib/128.jpg"
163 | },
164 | {
165 | "title": "大道芸人",
166 | "url": "https://weekly.tw93.fun/posts/131-大道芸人",
167 | "date": "2023/07/28",
168 | "pic": "https://gw.alipayobjects.com/zos/k/fliggy/132.jpg"
169 | },
170 | {
171 | "title": "可爱雕塑",
172 | "url": "https://weekly.tw93.fun/posts/132-可爱雕塑",
173 | "date": "2023/07/28",
174 | "pic": "https://gw.alipayobjects.com/zos/k/o6/132.jpg"
175 | },
176 | {
177 | "title": "香港不错",
178 | "url": "https://weekly.tw93.fun/posts/135-香港不错",
179 | "date": "2023/07/28",
180 | "pic": "https://gw.alipayobjects.com/zos/k/1w/135.jpg"
181 | },
182 | {
183 | "title": "九龙公园",
184 | "url": "https://weekly.tw93.fun/posts/137-九龙公园",
185 | "date": "2023/07/28",
186 | "pic": "https://gw.alipayobjects.com/zos/k/60/137.jpg"
187 | },
188 | {
189 | "title": "下班蓝天",
190 | "url": "https://weekly.tw93.fun/posts/138-下班蓝天",
191 | "date": "2023/07/28",
192 | "pic": "https://gw.alipayobjects.com/zos/k/05/138.jpg"
193 | },
194 | {
195 | "title": "亚庇清真寺",
196 | "url": "https://weekly.tw93.fun/posts/16-亚庇清真寺",
197 | "date": "2021/03/01",
198 | "pic": "https://gw.alipayobjects.com/zos/k/md/16.jpg"
199 | },
200 | {
201 | "title": "烤肉配薯条",
202 | "url": "https://weekly.tw93.fun/posts/66-烤肉配薯条",
203 | "date": "2022/02/14",
204 | "pic": "https://gw.alipayobjects.com/zos/k/65/IMG_7912.jpg"
205 | },
206 | {
207 | "title": "笼子里的鸟",
208 | "url": "https://weekly.tw93.fun/posts/79-笼子里的鸟",
209 | "date": "2022/05/16",
210 | "pic": "https://gw.alipayobjects.com/zos/k/iq/VeZ7Jj.jpg"
211 | },
212 | {
213 | "title": "良渚的🦌",
214 | "url": "https://weekly.tw93.fun/posts/81-良渚的🦌",
215 | "date": "2022/05/30",
216 | "pic": "https://gw.alipayobjects.com/zos/k/fq/IMG_9201.jpg"
217 | },
218 | {
219 | "title": "安吉黄昏",
220 | "url": "https://weekly.tw93.fun/posts/01-安吉黄昏",
221 | "date": "2020/11/16",
222 | "pic": "https://gw.alipayobjects.com/zos/k/h5/hzL4LG.jpg"
223 | },
224 | {
225 | "title": "大理稻田",
226 | "url": "https://weekly.tw93.fun/posts/12-大理稻田",
227 | "date": "2021/02/01",
228 | "pic": "https://gw.alipayobjects.com/zos/k/75/MSg3n1.jpg"
229 | },
230 | {
231 | "title": "冬天三亚",
232 | "url": "https://weekly.tw93.fun/posts/22-冬天三亚",
233 | "date": "2021/04/12",
234 | "pic": "https://gw.alipayobjects.com/zos/k/5u/H2lAp3.jpeg"
235 | },
236 | {
237 | "title": "橘子洲头",
238 | "url": "https://weekly.tw93.fun/posts/28-橘子洲头",
239 | "date": "2021/05/24",
240 | "pic": "https://gw.alipayobjects.com/zos/k/um/IMG_4524.jpeg"
241 | },
242 | {
243 | "title": "大阪夜景",
244 | "url": "https://weekly.tw93.fun/posts/46-大阪夜景",
245 | "date": "2021/09/27",
246 | "pic": "https://gw.alipayobjects.com/zos/k/7q/dPhcAh.jpg"
247 | },
248 | {
249 | "title": "漂亮的树",
250 | "url": "https://weekly.tw93.fun/posts/63-漂亮的树",
251 | "date": "2022/01/24",
252 | "pic": "https://gw.alipayobjects.com/zos/k/pt/AKRZvA.jpeg"
253 | },
254 | {
255 | "title": "发光的树",
256 | "url": "https://weekly.tw93.fun/posts/74-发光的树",
257 | "date": "2022/04/11",
258 | "pic": "https://gw.alipayobjects.com/zos/k/5m/37.jpeg"
259 | },
260 | {
261 | "title": "咖啡标语",
262 | "url": "https://weekly.tw93.fun/posts/76-咖啡标语",
263 | "date": "2022/04/25",
264 | "pic": "https://gw.alipayobjects.com/zos/k/qs/1.jpg"
265 | },
266 | {
267 | "title": "落日风帆",
268 | "url": "https://weekly.tw93.fun/posts/84-落日风帆",
269 | "date": "2022/06/20",
270 | "pic": "https://gw.alipayobjects.com/zos/k/cr/IMG_8103.jpeg"
271 | },
272 | {
273 | "title": "去避暑吧",
274 | "url": "https://weekly.tw93.fun/posts/89-去避暑吧",
275 | "date": "2022/07/25",
276 | "pic": "https://gw.alipayobjects.com/zos/k/eg/2268.jpg"
277 | },
278 | {
279 | "title": "由在茶溪",
280 | "url": "https://weekly.tw93.fun/posts/95-由在茶溪",
281 | "date": "2022/09/05",
282 | "pic": "https://gw.alipayobjects.com/zos/k/gf/qdMqaU.jpg"
283 | },
284 | {
285 | "title": "杭州乐园",
286 | "url": "https://weekly.tw93.fun/posts/96-杭州乐园",
287 | "date": "2022/09/12",
288 | "pic": "https://gw.alipayobjects.com/zos/k/app2/shui.jpg"
289 | },
290 | {
291 | "title": "水上森林",
292 | "url": "https://weekly.tw93.fun/posts/97-水上森林",
293 | "date": "2022/09/19",
294 | "pic": "https://gw.alipayobjects.com/zos/k/wn/W4ZBF3.jpg"
295 | },
296 | {
297 | "title": "潮流建筑",
298 | "url": "https://weekly.tw93.fun/posts/98-潮流建筑",
299 | "date": "2022/09/26",
300 | "pic": "https://gw.alipayobjects.com/zos/k/br/IMG_0652.jpg"
301 | },
302 | {
303 | "title": "太子湾",
304 | "url": "https://weekly.tw93.fun/posts/02-太子湾",
305 | "date": "2020/11/23",
306 | "pic": "https://gw.alipayobjects.com/zos/k/yt/ck1Y1K.png"
307 | },
308 | {
309 | "title": "泸沽湖",
310 | "url": "https://weekly.tw93.fun/posts/05-泸沽湖",
311 | "date": "2020/12/14",
312 | "pic": "https://gw.alipayobjects.com/zos/k/bn/g7b1Xc.jpg"
313 | },
314 | {
315 | "title": "热河路",
316 | "url": "https://weekly.tw93.fun/posts/27-热河路",
317 | "date": "2021/05/17",
318 | "pic": "https://gw.alipayobjects.com/zos/k/44/DSC06704.jpeg"
319 | },
320 | {
321 | "title": "莫吉托",
322 | "url": "https://weekly.tw93.fun/posts/83-莫吉托",
323 | "date": "2022/06/13",
324 | "pic": "https://gw.alipayobjects.com/zos/k/em/IMG_9399.jpg"
325 | },
326 | {
327 | "title": "天目里",
328 | "url": "https://weekly.tw93.fun/posts/91-天目里",
329 | "date": "2022/08/08",
330 | "pic": "https://gw.alipayobjects.com/zos/k/l8/IMG_0065.jpg"
331 | },
332 | {
333 | "title": "华山",
334 | "url": "https://weekly.tw93.fun/posts/09-华山",
335 | "date": "2021/01/11",
336 | "pic": "https://gw.alipayobjects.com/zos/k/bb/12121221mmm.jpg"
337 | },
338 | {
339 | "title": "养猫",
340 | "url": "https://weekly.tw93.fun/posts/15-养猫",
341 | "date": "2021/02/22",
342 | "pic": "https://gw.alipayobjects.com/zos/k/zz/ujvV0v.png"
343 | },
344 | {
345 | "title": "草海",
346 | "url": "https://weekly.tw93.fun/posts/20-草海",
347 | "date": "2021/03/29",
348 | "pic": "https://gw.alipayobjects.com/zos/k/9w/S5tqsz.jpeg"
349 | },
350 | {
351 | "title": "汤圆",
352 | "url": "https://weekly.tw93.fun/posts/21-汤圆",
353 | "date": "2021/04/05",
354 | "pic": "https://gw.alipayobjects.com/zos/k/84/kKRZeF.jpeg"
355 | },
356 | {
357 | "title": "南京",
358 | "url": "https://weekly.tw93.fun/posts/32-南京",
359 | "date": "2021/06/21",
360 | "pic": "https://gw.alipayobjects.com/zos/k/e2/o4FeLQ.jpeg"
361 | },
362 | {
363 | "title": "西安",
364 | "url": "https://weekly.tw93.fun/posts/57-西安",
365 | "date": "2021/12/13",
366 | "pic": "https://gw.alipayobjects.com/zos/k/3x/pCP92Q.jpg"
367 | },
368 | {
369 | "title": "佛头",
370 | "url": "https://weekly.tw93.fun/posts/78-佛头",
371 | "date": "2022/05/09",
372 | "pic": "https://gw.alipayobjects.com/zos/k/appo/IMG_8952.jpg"
373 | },
374 | {
375 | "title": "爱王小波",
376 | "url": "https://weekly.tw93.fun/posts/140-爱王小波",
377 | "date": "2023/08/07",
378 | "pic": "https://gw.alipayobjects.com/zos/k/1/140.jpg"
379 | }
380 | ]
381 |
--------------------------------------------------------------------------------
/newtab/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tw93/Maple/8e844afd83cfdccf52ae5cb83f97685838db4dd0/newtab/logo.png
--------------------------------------------------------------------------------
/newtab/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Maple NewTab",
4 | "description": "Enhance your new tab experience with a comfortable and refreshing design.",
5 | "version": "1.10",
6 | "chrome_url_overrides": {
7 | "newtab": "newtab.html"
8 | },
9 | "optional_host_permissions": ["*://*/*"],
10 | "icons": {
11 | "16": "logo.png",
12 | "48": "logo.png",
13 | "128": "logo.png"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/newtab/newtab.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
84 |
85 |
86 |
87 |
88 | 必应图
89 | Unsplash
90 | 空白页
91 | 随机图
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/newtab/newtab.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 | const body = document.body;
3 | const bgDescription = document.getElementById("bg-description");
4 | const title = document.getElementById("title");
5 | const bgSelector = document.getElementById("bg-selector");
6 | const userAgent = window.navigator.userAgent;
7 | const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
8 | let isDarkMode = darkModeMediaQuery.matches;
9 | const userLanguage = window.navigator.language;
10 |
11 | // 用于映射的对象
12 | const languageMappings = {
13 | zh: {
14 | title: "新标签页",
15 | blank: "空白页",
16 | random: "随机图",
17 | bing: "必应图",
18 | unsplash: "Unsplash",
19 | },
20 | en: {
21 | title: "New Tab",
22 | blank: "Blank",
23 | random: "Image",
24 | bing: "Bing",
25 | unsplash: "Unsplash",
26 | },
27 | };
28 |
29 | // 检测用户语言并设置相应的语言映射
30 | const lang = userLanguage.startsWith("zh") ? "zh" : "en";
31 | const mapping = languageMappings[lang];
32 |
33 | // 使用映射更新文本
34 | title.textContent = mapping.title;
35 | document.querySelector('#bg-selector option[value="blank"]').textContent = mapping.blank;
36 | document.querySelector('#bg-selector option[value="random"]').textContent = mapping.random;
37 | document.querySelector('#bg-selector option[value="bing"]').textContent = mapping.bing;
38 | document.querySelector('#bg-selector option[value="unsplash"]').textContent = mapping.unsplash;
39 |
40 | // 根据浏览器类型和颜色模式设置背景色
41 | function setBackgroundColor() {
42 | if (userAgent.indexOf("Edg") > -1) {
43 | body.style.backgroundColor = isDarkMode ? "#2B2B2B" : "#F7F7F7";
44 | } else if (userAgent.indexOf("Chrome") > -1) {
45 | body.style.backgroundColor = isDarkMode ? "#202124" : "#F1F3F4";
46 | }
47 | }
48 |
49 | function convertToLinkElement(data) {
50 | if (data.title && data.date) {
51 | bgDescription.textContent = `${data.title} · ${data.date}`;
52 | bgDescription.href = "#";
53 | bgDescription.onclick = function (e) {
54 | e.preventDefault();
55 | chrome.tabs.create({ url: data.url });
56 | };
57 | }
58 | }
59 |
60 | // 随机设置背景图片
61 | function setRandomBackgroundImage() {
62 | fetch(chrome.runtime.getURL("/bg.json"))
63 | .then((response) => response.json())
64 | .then((json) => {
65 | const randomIndex = Math.floor(Math.random() * json.length);
66 | const randomItem = json[randomIndex];
67 | body.style.backgroundImage = `url(${randomItem.pic})`;
68 | convertToLinkElement(randomItem);
69 | localStorage.setItem("bgImageUrl", randomItem.pic);
70 | localStorage.setItem("bgImageDate", new Date().toISOString().slice(0, 10));
71 | localStorage.setItem("bgImageInfo", JSON.stringify(randomItem));
72 | })
73 | .catch((error) => {
74 | console.error("Error:", error);
75 | });
76 | }
77 |
78 | /**
79 | * @description 设置必应背景图片,使用了第三方 API
80 | */
81 | function setBingBackgroundImage() {
82 | const apiBaseUrl = "https://bing.biturl.top/?resolution=3840&format=json&index=0";
83 | const apiLang = lang === "zh" ? "zh-CN" : "en-US";
84 | const apiUrl = apiBaseUrl + "&mkt=" + apiLang;
85 |
86 | fetch(apiUrl)
87 | .then((response) => response.json())
88 | .then((r) => {
89 | const title = r.copyright;
90 | const imageUrl = r.url;
91 | const today = new Date();
92 | const date = today.getFullYear() + "/" + (today.getMonth() + 1) + "/" + today.getDate();
93 |
94 | const Info = {
95 | title: title,
96 | url: imageUrl,
97 | date: date,
98 | pic: imageUrl,
99 | };
100 | convertToLinkElement(Info);
101 |
102 | body.style.backgroundImage = `url(${imageUrl})`;
103 | localStorage.setItem("bgBingUrl", imageUrl);
104 | localStorage.setItem("bgBingDate", new Date().toISOString().slice(0, 10));
105 | localStorage.setItem("bgBingInfo", JSON.stringify(Info));
106 | })
107 | .catch((error) => {
108 | console.error("Error:", error);
109 | });
110 | }
111 |
112 | /**
113 | * @description 设置Unsplash背景图片,用了下代理
114 | */
115 | function setUnsplashBackgroundImage() {
116 | const apiBaseUrl = "https://picsum.photos/3200/1800";
117 |
118 | fetch(apiBaseUrl)
119 | .then((r) => {
120 | const imageUrl = r.url;
121 | body.style.backgroundImage = `url(${imageUrl})`;
122 | bgDescription.textContent = "";
123 | localStorage.setItem("bgUnsplashUrl", imageUrl);
124 | localStorage.setItem("bgUnsplashDate", new Date().toISOString().slice(0, 10));
125 | // 由于没有其他的信息获取
126 | localStorage.setItem("bgUnsplashInfo", JSON.stringify({ title: "" }));
127 | })
128 | .catch((error) => {
129 | console.error("Error:", error);
130 | });
131 | }
132 |
133 | /**
134 | * @description 处理选择非空白背景时的逻辑
135 | * @param type 选择的背景类型,random 或 bing
136 | * @param urlKey 本地存储中图片 url 的 key
137 | * @param dateKey 本地存储中图片 日期 的 key
138 | * @param infoKey 本地存储中图片 信息 的 key
139 | */
140 | function handleSetBackground(type, urlKey, dateKey, infoKey) {
141 | body.classList.remove("blank");
142 | const imageUrl = localStorage.getItem(urlKey);
143 | const imageDate = localStorage.getItem(dateKey);
144 | const imageInfo = localStorage.getItem(infoKey);
145 | const currentDate = new Date().toISOString().slice(0, 10);
146 |
147 | if (imageUrl && imageDate === currentDate) {
148 | body.style.backgroundImage = `url(${imageUrl})`;
149 | try {
150 | convertToLinkElement(JSON.parse(imageInfo));
151 | } catch (error) {
152 | console.log(error);
153 | }
154 | } else {
155 | if (type === "random") {
156 | setRandomBackgroundImage();
157 | } else if (type === "bing") {
158 | setBingBackgroundImage();
159 | } else if (type === "unsplash") {
160 | setUnsplashBackgroundImage();
161 | }
162 | }
163 | }
164 |
165 | // 根据用户选择设置背景
166 | function setBackground() {
167 | const bgType = bgSelector.value;
168 | localStorage.setItem("bgType", bgType);
169 |
170 | if (bgType === "blank") {
171 | body.style.backgroundImage = "";
172 | body.classList.add("blank");
173 | bgDescription.textContent = "";
174 | setBackgroundColor();
175 | } else if (bgType === "random") {
176 | handleSetBackground(bgType, "bgImageUrl", "bgImageDate", "bgImageInfo");
177 | } else if (bgType === "bing") {
178 | handleSetBackground(bgType, "bgBingUrl", "bgBingDate", "bgBingInfo");
179 | } else if (bgType === "unsplash") {
180 | handleSetBackground(bgType, "bgUnsplashUrl", "bgUnsplashDate", "bgUnsplashInfo");
181 | }
182 | }
183 |
184 | // 监听用户选择变化
185 | bgSelector.addEventListener("change", function () {
186 | setBackground();
187 | if (bgSelector.value === "random" && localStorage.getItem("bgImageUrl")) {
188 | setRandomBackgroundImage();
189 | }
190 | });
191 |
192 | // 初始设置背景
193 | bgSelector.value = localStorage.getItem("bgType") || "bing";
194 | setBackground();
195 |
196 | // 监听颜色方案变化
197 | if (darkModeMediaQuery.addEventListener) {
198 | darkModeMediaQuery.addEventListener("change", function (e) {
199 | isDarkMode = e.matches;
200 | setBackgroundColor();
201 | });
202 | } else if (darkModeMediaQuery.addListener) {
203 | darkModeMediaQuery.addListener(function (e) {
204 | isDarkMode = e.matches;
205 | setBackgroundColor();
206 | });
207 | }
208 |
209 | let timeout;
210 |
211 | // 当鼠标移动时,2秒后显示元素
212 | document.body.addEventListener("mousemove", function () {
213 | clearTimeout(timeout);
214 |
215 | timeout = setTimeout(function () {
216 | const selectorContainer = document.querySelector(".selector-container");
217 | const bgDescription = document.getElementById("bg-description");
218 |
219 | selectorContainer.style.visibility = "visible";
220 | selectorContainer.style.opacity = "1";
221 |
222 | bgDescription.style.visibility = "visible";
223 | bgDescription.style.opacity = "1";
224 | }, 1200);
225 | });
226 |
227 | // 当鼠标离开body时立即隐藏元素
228 | document.body.addEventListener("mouseleave", function () {
229 | clearTimeout(timeout);
230 | const selectorContainer = document.querySelector(".selector-container");
231 | const bgDescription = document.getElementById("bg-description");
232 |
233 | selectorContainer.style.visibility = "hidden";
234 | selectorContainer.style.opacity = "0";
235 |
236 | bgDescription.style.visibility = "hidden";
237 | bgDescription.style.opacity = "0";
238 | });
239 | };
240 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "maple-bookmarks",
3 | "description": "Let you navigate smoothly while hiding the bookmark bar.",
4 | "main": "bookmark/popup.js",
5 | "scripts": {
6 | "bookmark": "zip -r ./dist/Maple.zip ./bookmark",
7 | "bookmark-firefox": "cp -R ./bookmark ./bookmark-firefox && cp ./bookmark/manifest_firefox.json ./bookmark-firefox/manifest.json && cd ./bookmark-firefox && zip -r ../dist/FirefoxMaple.zip . && cd .. && rm -rf ./bookmark-firefox",
8 | "newtab": "zip -r ./dist/NewTab.zip ./newtab",
9 | "theme":"zip -r ./dist/Theme.zip ./theme",
10 | "build": "mkdir -p ./dist && yarn lint && yarn bookmark && yarn bookmark-firefox && yarn newtab && yarn theme",
11 | "lint": "eslint . --ext .js --fix"
12 | },
13 | "keywords": [
14 | "bookmarks",
15 | "bookmark",
16 | "chrome",
17 | "browser-extension"
18 | ],
19 | "author": "Tw93",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "eslint": "^8.53.0",
23 | "eslint-config-prettier": "^9.0.0",
24 | "eslint-plugin-import": "^2.29.0",
25 | "eslint-plugin-prettier": "^5.0.1",
26 | "prettier": "^3.0.3"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/theme/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "Maple Theme",
4 | "description": "A super simple and clean theme",
5 | "version": "1.0",
6 | "theme": {
7 | "colors": {
8 | "frame": [
9 | 255,
10 | 255,
11 | 255
12 | ],
13 | "frame_inactive": [
14 | 255,
15 | 255,
16 | 255
17 | ],
18 | "frame_incognito": [
19 | 32,
20 | 33,
21 | 36
22 | ],
23 | "frame_incognito_inactive": [
24 | 60,
25 | 64,
26 | 67
27 | ],
28 | "background_tab": [
29 | 255,
30 | 255,
31 | 255
32 | ],
33 | "background_tab_inactive": [
34 | 255,
35 | 255,
36 | 255
37 | ],
38 | "background_tab_incognito": [
39 | 32,
40 | 33,
41 | 36
42 | ],
43 | "background_tab_incognito_inactive": [
44 | 60,
45 | 64,
46 | 67
47 | ],
48 | "bookmark_text": [
49 | 51,
50 | 51,
51 | 51
52 | ],
53 | "tab_background_text": [
54 | 85,
55 | 85,
56 | 85
57 | ],
58 | "tab_background_text_inactive": [
59 | 119,
60 | 119,
61 | 119
62 | ],
63 | "tab_background_text_incognito": [
64 | 189,
65 | 193,
66 | 198
67 | ],
68 | "tab_background_text_incognito_inactive": [
69 | 167,
70 | 171,
71 | 174
72 | ],
73 | "tab_text": [
74 | 0,
75 | 0,
76 | 0
77 | ],
78 | "toolbar": [
79 | 255,
80 | 255,
81 | 255
82 | ],
83 | "toolbar_button_icon": [
84 | 85,
85 | 85,
86 | 85
87 | ],
88 | "omnibox_text": [
89 | 51,
90 | 51,
91 | 51
92 | ],
93 | "omnibox_background": [
94 | 245,
95 | 245,
96 | 245
97 | ]
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@aashutoshrathi/word-wrap@^1.2.3":
6 | version "1.2.6"
7 | resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz"
8 | integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
9 |
10 | "@eslint-community/eslint-utils@^4.2.0":
11 | version "4.4.0"
12 | resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
13 | integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
14 | dependencies:
15 | eslint-visitor-keys "^3.3.0"
16 |
17 | "@eslint-community/regexpp@^4.6.1":
18 | version "4.6.2"
19 | resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz"
20 | integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==
21 |
22 | "@eslint/eslintrc@^2.1.3":
23 | version "2.1.3"
24 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d"
25 | integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==
26 | dependencies:
27 | ajv "^6.12.4"
28 | debug "^4.3.2"
29 | espree "^9.6.0"
30 | globals "^13.19.0"
31 | ignore "^5.2.0"
32 | import-fresh "^3.2.1"
33 | js-yaml "^4.1.0"
34 | minimatch "^3.1.2"
35 | strip-json-comments "^3.1.1"
36 |
37 | "@eslint/js@8.53.0":
38 | version "8.53.0"
39 | resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d"
40 | integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==
41 |
42 | "@humanwhocodes/config-array@^0.11.13":
43 | version "0.11.13"
44 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
45 | integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==
46 | dependencies:
47 | "@humanwhocodes/object-schema" "^2.0.1"
48 | debug "^4.1.1"
49 | minimatch "^3.0.5"
50 |
51 | "@humanwhocodes/module-importer@^1.0.1":
52 | version "1.0.1"
53 | resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz"
54 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
55 |
56 | "@humanwhocodes/object-schema@^2.0.1":
57 | version "2.0.1"
58 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044"
59 | integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==
60 |
61 | "@nodelib/fs.scandir@2.1.5":
62 | version "2.1.5"
63 | resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
64 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
65 | dependencies:
66 | "@nodelib/fs.stat" "2.0.5"
67 | run-parallel "^1.1.9"
68 |
69 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
70 | version "2.0.5"
71 | resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
72 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
73 |
74 | "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
75 | version "1.2.8"
76 | resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"
77 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
78 | dependencies:
79 | "@nodelib/fs.scandir" "2.1.5"
80 | fastq "^1.6.0"
81 |
82 | "@pkgr/utils@^2.3.1":
83 | version "2.4.2"
84 | resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz"
85 | integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==
86 | dependencies:
87 | cross-spawn "^7.0.3"
88 | fast-glob "^3.3.0"
89 | is-glob "^4.0.3"
90 | open "^9.1.0"
91 | picocolors "^1.0.0"
92 | tslib "^2.6.0"
93 |
94 | "@types/json5@^0.0.29":
95 | version "0.0.29"
96 | resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
97 | integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
98 |
99 | "@ungap/structured-clone@^1.2.0":
100 | version "1.2.0"
101 | resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
102 | integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
103 |
104 | acorn-jsx@^5.3.2:
105 | version "5.3.2"
106 | resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
107 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
108 |
109 | acorn@^8.9.0:
110 | version "8.10.0"
111 | resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
112 | integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
113 |
114 | ajv@^6.12.4:
115 | version "6.12.6"
116 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
117 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
118 | dependencies:
119 | fast-deep-equal "^3.1.1"
120 | fast-json-stable-stringify "^2.0.0"
121 | json-schema-traverse "^0.4.1"
122 | uri-js "^4.2.2"
123 |
124 | ansi-regex@^5.0.1:
125 | version "5.0.1"
126 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
127 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
128 |
129 | ansi-styles@^4.1.0:
130 | version "4.3.0"
131 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
132 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
133 | dependencies:
134 | color-convert "^2.0.1"
135 |
136 | argparse@^2.0.1:
137 | version "2.0.1"
138 | resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
139 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
140 |
141 | array-buffer-byte-length@^1.0.0:
142 | version "1.0.0"
143 | resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz"
144 | integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==
145 | dependencies:
146 | call-bind "^1.0.2"
147 | is-array-buffer "^3.0.1"
148 |
149 | array-includes@^3.1.7:
150 | version "3.1.7"
151 | resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda"
152 | integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==
153 | dependencies:
154 | call-bind "^1.0.2"
155 | define-properties "^1.2.0"
156 | es-abstract "^1.22.1"
157 | get-intrinsic "^1.2.1"
158 | is-string "^1.0.7"
159 |
160 | array.prototype.findlastindex@^1.2.3:
161 | version "1.2.3"
162 | resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207"
163 | integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==
164 | dependencies:
165 | call-bind "^1.0.2"
166 | define-properties "^1.2.0"
167 | es-abstract "^1.22.1"
168 | es-shim-unscopables "^1.0.0"
169 | get-intrinsic "^1.2.1"
170 |
171 | array.prototype.flat@^1.3.2:
172 | version "1.3.2"
173 | resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18"
174 | integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==
175 | dependencies:
176 | call-bind "^1.0.2"
177 | define-properties "^1.2.0"
178 | es-abstract "^1.22.1"
179 | es-shim-unscopables "^1.0.0"
180 |
181 | array.prototype.flatmap@^1.3.2:
182 | version "1.3.2"
183 | resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527"
184 | integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==
185 | dependencies:
186 | call-bind "^1.0.2"
187 | define-properties "^1.2.0"
188 | es-abstract "^1.22.1"
189 | es-shim-unscopables "^1.0.0"
190 |
191 | arraybuffer.prototype.slice@^1.0.2:
192 | version "1.0.2"
193 | resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12"
194 | integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==
195 | dependencies:
196 | array-buffer-byte-length "^1.0.0"
197 | call-bind "^1.0.2"
198 | define-properties "^1.2.0"
199 | es-abstract "^1.22.1"
200 | get-intrinsic "^1.2.1"
201 | is-array-buffer "^3.0.2"
202 | is-shared-array-buffer "^1.0.2"
203 |
204 | available-typed-arrays@^1.0.5:
205 | version "1.0.5"
206 | resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz"
207 | integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
208 |
209 | balanced-match@^1.0.0:
210 | version "1.0.2"
211 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
212 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
213 |
214 | big-integer@^1.6.44:
215 | version "1.6.51"
216 | resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz"
217 | integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==
218 |
219 | bplist-parser@^0.2.0:
220 | version "0.2.0"
221 | resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz"
222 | integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==
223 | dependencies:
224 | big-integer "^1.6.44"
225 |
226 | brace-expansion@^1.1.7:
227 | version "1.1.11"
228 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
229 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
230 | dependencies:
231 | balanced-match "^1.0.0"
232 | concat-map "0.0.1"
233 |
234 | braces@^3.0.2:
235 | version "3.0.2"
236 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
237 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
238 | dependencies:
239 | fill-range "^7.0.1"
240 |
241 | bundle-name@^3.0.0:
242 | version "3.0.0"
243 | resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz"
244 | integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==
245 | dependencies:
246 | run-applescript "^5.0.0"
247 |
248 | call-bind@^1.0.0, call-bind@^1.0.2:
249 | version "1.0.2"
250 | resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
251 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
252 | dependencies:
253 | function-bind "^1.1.1"
254 | get-intrinsic "^1.0.2"
255 |
256 | call-bind@^1.0.4, call-bind@^1.0.5:
257 | version "1.0.5"
258 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513"
259 | integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==
260 | dependencies:
261 | function-bind "^1.1.2"
262 | get-intrinsic "^1.2.1"
263 | set-function-length "^1.1.1"
264 |
265 | callsites@^3.0.0:
266 | version "3.1.0"
267 | resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
268 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
269 |
270 | chalk@^4.0.0:
271 | version "4.1.2"
272 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
273 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
274 | dependencies:
275 | ansi-styles "^4.1.0"
276 | supports-color "^7.1.0"
277 |
278 | color-convert@^2.0.1:
279 | version "2.0.1"
280 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
281 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
282 | dependencies:
283 | color-name "~1.1.4"
284 |
285 | color-name@~1.1.4:
286 | version "1.1.4"
287 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
288 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
289 |
290 | concat-map@0.0.1:
291 | version "0.0.1"
292 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
293 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
294 |
295 | cross-spawn@^7.0.2, cross-spawn@^7.0.3:
296 | version "7.0.3"
297 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
298 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
299 | dependencies:
300 | path-key "^3.1.0"
301 | shebang-command "^2.0.0"
302 | which "^2.0.1"
303 |
304 | debug@^3.2.7:
305 | version "3.2.7"
306 | resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
307 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
308 | dependencies:
309 | ms "^2.1.1"
310 |
311 | debug@^4.1.1, debug@^4.3.2:
312 | version "4.3.4"
313 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
314 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
315 | dependencies:
316 | ms "2.1.2"
317 |
318 | deep-is@^0.1.3:
319 | version "0.1.4"
320 | resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
321 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
322 |
323 | default-browser-id@^3.0.0:
324 | version "3.0.0"
325 | resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz"
326 | integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==
327 | dependencies:
328 | bplist-parser "^0.2.0"
329 | untildify "^4.0.0"
330 |
331 | default-browser@^4.0.0:
332 | version "4.0.0"
333 | resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz"
334 | integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==
335 | dependencies:
336 | bundle-name "^3.0.0"
337 | default-browser-id "^3.0.0"
338 | execa "^7.1.1"
339 | titleize "^3.0.0"
340 |
341 | define-data-property@^1.0.1, define-data-property@^1.1.1:
342 | version "1.1.1"
343 | resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
344 | integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==
345 | dependencies:
346 | get-intrinsic "^1.2.1"
347 | gopd "^1.0.1"
348 | has-property-descriptors "^1.0.0"
349 |
350 | define-lazy-prop@^3.0.0:
351 | version "3.0.0"
352 | resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz"
353 | integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
354 |
355 | define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0:
356 | version "1.2.0"
357 | resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz"
358 | integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==
359 | dependencies:
360 | has-property-descriptors "^1.0.0"
361 | object-keys "^1.1.1"
362 |
363 | doctrine@^2.1.0:
364 | version "2.1.0"
365 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
366 | integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
367 | dependencies:
368 | esutils "^2.0.2"
369 |
370 | doctrine@^3.0.0:
371 | version "3.0.0"
372 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
373 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
374 | dependencies:
375 | esutils "^2.0.2"
376 |
377 | es-abstract@^1.22.1:
378 | version "1.22.3"
379 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32"
380 | integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==
381 | dependencies:
382 | array-buffer-byte-length "^1.0.0"
383 | arraybuffer.prototype.slice "^1.0.2"
384 | available-typed-arrays "^1.0.5"
385 | call-bind "^1.0.5"
386 | es-set-tostringtag "^2.0.1"
387 | es-to-primitive "^1.2.1"
388 | function.prototype.name "^1.1.6"
389 | get-intrinsic "^1.2.2"
390 | get-symbol-description "^1.0.0"
391 | globalthis "^1.0.3"
392 | gopd "^1.0.1"
393 | has-property-descriptors "^1.0.0"
394 | has-proto "^1.0.1"
395 | has-symbols "^1.0.3"
396 | hasown "^2.0.0"
397 | internal-slot "^1.0.5"
398 | is-array-buffer "^3.0.2"
399 | is-callable "^1.2.7"
400 | is-negative-zero "^2.0.2"
401 | is-regex "^1.1.4"
402 | is-shared-array-buffer "^1.0.2"
403 | is-string "^1.0.7"
404 | is-typed-array "^1.1.12"
405 | is-weakref "^1.0.2"
406 | object-inspect "^1.13.1"
407 | object-keys "^1.1.1"
408 | object.assign "^4.1.4"
409 | regexp.prototype.flags "^1.5.1"
410 | safe-array-concat "^1.0.1"
411 | safe-regex-test "^1.0.0"
412 | string.prototype.trim "^1.2.8"
413 | string.prototype.trimend "^1.0.7"
414 | string.prototype.trimstart "^1.0.7"
415 | typed-array-buffer "^1.0.0"
416 | typed-array-byte-length "^1.0.0"
417 | typed-array-byte-offset "^1.0.0"
418 | typed-array-length "^1.0.4"
419 | unbox-primitive "^1.0.2"
420 | which-typed-array "^1.1.13"
421 |
422 | es-set-tostringtag@^2.0.1:
423 | version "2.0.1"
424 | resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz"
425 | integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==
426 | dependencies:
427 | get-intrinsic "^1.1.3"
428 | has "^1.0.3"
429 | has-tostringtag "^1.0.0"
430 |
431 | es-shim-unscopables@^1.0.0:
432 | version "1.0.0"
433 | resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz"
434 | integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
435 | dependencies:
436 | has "^1.0.3"
437 |
438 | es-to-primitive@^1.2.1:
439 | version "1.2.1"
440 | resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz"
441 | integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
442 | dependencies:
443 | is-callable "^1.1.4"
444 | is-date-object "^1.0.1"
445 | is-symbol "^1.0.2"
446 |
447 | escape-string-regexp@^4.0.0:
448 | version "4.0.0"
449 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
450 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
451 |
452 | eslint-config-prettier@^9.0.0:
453 | version "9.0.0"
454 | resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz"
455 | integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==
456 |
457 | eslint-import-resolver-node@^0.3.9:
458 | version "0.3.9"
459 | resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac"
460 | integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==
461 | dependencies:
462 | debug "^3.2.7"
463 | is-core-module "^2.13.0"
464 | resolve "^1.22.4"
465 |
466 | eslint-module-utils@^2.8.0:
467 | version "2.8.0"
468 | resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz"
469 | integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==
470 | dependencies:
471 | debug "^3.2.7"
472 |
473 | eslint-plugin-import@^2.29.0:
474 | version "2.29.0"
475 | resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155"
476 | integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==
477 | dependencies:
478 | array-includes "^3.1.7"
479 | array.prototype.findlastindex "^1.2.3"
480 | array.prototype.flat "^1.3.2"
481 | array.prototype.flatmap "^1.3.2"
482 | debug "^3.2.7"
483 | doctrine "^2.1.0"
484 | eslint-import-resolver-node "^0.3.9"
485 | eslint-module-utils "^2.8.0"
486 | hasown "^2.0.0"
487 | is-core-module "^2.13.1"
488 | is-glob "^4.0.3"
489 | minimatch "^3.1.2"
490 | object.fromentries "^2.0.7"
491 | object.groupby "^1.0.1"
492 | object.values "^1.1.7"
493 | semver "^6.3.1"
494 | tsconfig-paths "^3.14.2"
495 |
496 | eslint-plugin-prettier@^5.0.1:
497 | version "5.0.1"
498 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515"
499 | integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==
500 | dependencies:
501 | prettier-linter-helpers "^1.0.0"
502 | synckit "^0.8.5"
503 |
504 | eslint-scope@^7.2.2:
505 | version "7.2.2"
506 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz"
507 | integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==
508 | dependencies:
509 | esrecurse "^4.3.0"
510 | estraverse "^5.2.0"
511 |
512 | eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
513 | version "3.4.3"
514 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
515 | integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
516 |
517 | eslint@^8.53.0:
518 | version "8.53.0"
519 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce"
520 | integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==
521 | dependencies:
522 | "@eslint-community/eslint-utils" "^4.2.0"
523 | "@eslint-community/regexpp" "^4.6.1"
524 | "@eslint/eslintrc" "^2.1.3"
525 | "@eslint/js" "8.53.0"
526 | "@humanwhocodes/config-array" "^0.11.13"
527 | "@humanwhocodes/module-importer" "^1.0.1"
528 | "@nodelib/fs.walk" "^1.2.8"
529 | "@ungap/structured-clone" "^1.2.0"
530 | ajv "^6.12.4"
531 | chalk "^4.0.0"
532 | cross-spawn "^7.0.2"
533 | debug "^4.3.2"
534 | doctrine "^3.0.0"
535 | escape-string-regexp "^4.0.0"
536 | eslint-scope "^7.2.2"
537 | eslint-visitor-keys "^3.4.3"
538 | espree "^9.6.1"
539 | esquery "^1.4.2"
540 | esutils "^2.0.2"
541 | fast-deep-equal "^3.1.3"
542 | file-entry-cache "^6.0.1"
543 | find-up "^5.0.0"
544 | glob-parent "^6.0.2"
545 | globals "^13.19.0"
546 | graphemer "^1.4.0"
547 | ignore "^5.2.0"
548 | imurmurhash "^0.1.4"
549 | is-glob "^4.0.0"
550 | is-path-inside "^3.0.3"
551 | js-yaml "^4.1.0"
552 | json-stable-stringify-without-jsonify "^1.0.1"
553 | levn "^0.4.1"
554 | lodash.merge "^4.6.2"
555 | minimatch "^3.1.2"
556 | natural-compare "^1.4.0"
557 | optionator "^0.9.3"
558 | strip-ansi "^6.0.1"
559 | text-table "^0.2.0"
560 |
561 | espree@^9.6.0, espree@^9.6.1:
562 | version "9.6.1"
563 | resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz"
564 | integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
565 | dependencies:
566 | acorn "^8.9.0"
567 | acorn-jsx "^5.3.2"
568 | eslint-visitor-keys "^3.4.1"
569 |
570 | esquery@^1.4.2:
571 | version "1.5.0"
572 | resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz"
573 | integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
574 | dependencies:
575 | estraverse "^5.1.0"
576 |
577 | esrecurse@^4.3.0:
578 | version "4.3.0"
579 | resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
580 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
581 | dependencies:
582 | estraverse "^5.2.0"
583 |
584 | estraverse@^5.1.0, estraverse@^5.2.0:
585 | version "5.3.0"
586 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
587 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
588 |
589 | esutils@^2.0.2:
590 | version "2.0.3"
591 | resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
592 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
593 |
594 | execa@^5.0.0:
595 | version "5.1.1"
596 | resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
597 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
598 | dependencies:
599 | cross-spawn "^7.0.3"
600 | get-stream "^6.0.0"
601 | human-signals "^2.1.0"
602 | is-stream "^2.0.0"
603 | merge-stream "^2.0.0"
604 | npm-run-path "^4.0.1"
605 | onetime "^5.1.2"
606 | signal-exit "^3.0.3"
607 | strip-final-newline "^2.0.0"
608 |
609 | execa@^7.1.1:
610 | version "7.2.0"
611 | resolved "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz"
612 | integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==
613 | dependencies:
614 | cross-spawn "^7.0.3"
615 | get-stream "^6.0.1"
616 | human-signals "^4.3.0"
617 | is-stream "^3.0.0"
618 | merge-stream "^2.0.0"
619 | npm-run-path "^5.1.0"
620 | onetime "^6.0.0"
621 | signal-exit "^3.0.7"
622 | strip-final-newline "^3.0.0"
623 |
624 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
625 | version "3.1.3"
626 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
627 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
628 |
629 | fast-diff@^1.1.2:
630 | version "1.3.0"
631 | resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz"
632 | integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
633 |
634 | fast-glob@^3.3.0:
635 | version "3.3.1"
636 | resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz"
637 | integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==
638 | dependencies:
639 | "@nodelib/fs.stat" "^2.0.2"
640 | "@nodelib/fs.walk" "^1.2.3"
641 | glob-parent "^5.1.2"
642 | merge2 "^1.3.0"
643 | micromatch "^4.0.4"
644 |
645 | fast-json-stable-stringify@^2.0.0:
646 | version "2.1.0"
647 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
648 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
649 |
650 | fast-levenshtein@^2.0.6:
651 | version "2.0.6"
652 | resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
653 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
654 |
655 | fastq@^1.6.0:
656 | version "1.15.0"
657 | resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
658 | integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
659 | dependencies:
660 | reusify "^1.0.4"
661 |
662 | file-entry-cache@^6.0.1:
663 | version "6.0.1"
664 | resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
665 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
666 | dependencies:
667 | flat-cache "^3.0.4"
668 |
669 | fill-range@^7.0.1:
670 | version "7.0.1"
671 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
672 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
673 | dependencies:
674 | to-regex-range "^5.0.1"
675 |
676 | find-up@^5.0.0:
677 | version "5.0.0"
678 | resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
679 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
680 | dependencies:
681 | locate-path "^6.0.0"
682 | path-exists "^4.0.0"
683 |
684 | flat-cache@^3.0.4:
685 | version "3.0.4"
686 | resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
687 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
688 | dependencies:
689 | flatted "^3.1.0"
690 | rimraf "^3.0.2"
691 |
692 | flatted@^3.1.0:
693 | version "3.2.7"
694 | resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz"
695 | integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
696 |
697 | for-each@^0.3.3:
698 | version "0.3.3"
699 | resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz"
700 | integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
701 | dependencies:
702 | is-callable "^1.1.3"
703 |
704 | fs.realpath@^1.0.0:
705 | version "1.0.0"
706 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
707 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
708 |
709 | function-bind@^1.1.1:
710 | version "1.1.1"
711 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
712 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
713 |
714 | function-bind@^1.1.2:
715 | version "1.1.2"
716 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
717 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
718 |
719 | function.prototype.name@^1.1.6:
720 | version "1.1.6"
721 | resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd"
722 | integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==
723 | dependencies:
724 | call-bind "^1.0.2"
725 | define-properties "^1.2.0"
726 | es-abstract "^1.22.1"
727 | functions-have-names "^1.2.3"
728 |
729 | functions-have-names@^1.2.3:
730 | version "1.2.3"
731 | resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz"
732 | integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
733 |
734 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1:
735 | version "1.2.1"
736 | resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz"
737 | integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==
738 | dependencies:
739 | function-bind "^1.1.1"
740 | has "^1.0.3"
741 | has-proto "^1.0.1"
742 | has-symbols "^1.0.3"
743 |
744 | get-intrinsic@^1.2.2:
745 | version "1.2.2"
746 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b"
747 | integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==
748 | dependencies:
749 | function-bind "^1.1.2"
750 | has-proto "^1.0.1"
751 | has-symbols "^1.0.3"
752 | hasown "^2.0.0"
753 |
754 | get-stream@^6.0.0, get-stream@^6.0.1:
755 | version "6.0.1"
756 | resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
757 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
758 |
759 | get-symbol-description@^1.0.0:
760 | version "1.0.0"
761 | resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz"
762 | integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==
763 | dependencies:
764 | call-bind "^1.0.2"
765 | get-intrinsic "^1.1.1"
766 |
767 | glob-parent@^5.1.2:
768 | version "5.1.2"
769 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
770 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
771 | dependencies:
772 | is-glob "^4.0.1"
773 |
774 | glob-parent@^6.0.2:
775 | version "6.0.2"
776 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"
777 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
778 | dependencies:
779 | is-glob "^4.0.3"
780 |
781 | glob@^7.1.3:
782 | version "7.2.3"
783 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
784 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
785 | dependencies:
786 | fs.realpath "^1.0.0"
787 | inflight "^1.0.4"
788 | inherits "2"
789 | minimatch "^3.1.1"
790 | once "^1.3.0"
791 | path-is-absolute "^1.0.0"
792 |
793 | globals@^13.19.0:
794 | version "13.21.0"
795 | resolved "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz"
796 | integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==
797 | dependencies:
798 | type-fest "^0.20.2"
799 |
800 | globalthis@^1.0.3:
801 | version "1.0.3"
802 | resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz"
803 | integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
804 | dependencies:
805 | define-properties "^1.1.3"
806 |
807 | gopd@^1.0.1:
808 | version "1.0.1"
809 | resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
810 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
811 | dependencies:
812 | get-intrinsic "^1.1.3"
813 |
814 | graphemer@^1.4.0:
815 | version "1.4.0"
816 | resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz"
817 | integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
818 |
819 | has-bigints@^1.0.1, has-bigints@^1.0.2:
820 | version "1.0.2"
821 | resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz"
822 | integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
823 |
824 | has-flag@^4.0.0:
825 | version "4.0.0"
826 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
827 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
828 |
829 | has-property-descriptors@^1.0.0:
830 | version "1.0.0"
831 | resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz"
832 | integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
833 | dependencies:
834 | get-intrinsic "^1.1.1"
835 |
836 | has-proto@^1.0.1:
837 | version "1.0.1"
838 | resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz"
839 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
840 |
841 | has-symbols@^1.0.2, has-symbols@^1.0.3:
842 | version "1.0.3"
843 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
844 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
845 |
846 | has-tostringtag@^1.0.0:
847 | version "1.0.0"
848 | resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz"
849 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
850 | dependencies:
851 | has-symbols "^1.0.2"
852 |
853 | has@^1.0.3:
854 | version "1.0.3"
855 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
856 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
857 | dependencies:
858 | function-bind "^1.1.1"
859 |
860 | hasown@^2.0.0:
861 | version "2.0.0"
862 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
863 | integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
864 | dependencies:
865 | function-bind "^1.1.2"
866 |
867 | human-signals@^2.1.0:
868 | version "2.1.0"
869 | resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
870 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
871 |
872 | human-signals@^4.3.0:
873 | version "4.3.1"
874 | resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz"
875 | integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
876 |
877 | ignore@^5.2.0:
878 | version "5.2.4"
879 | resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
880 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
881 |
882 | import-fresh@^3.2.1:
883 | version "3.3.0"
884 | resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
885 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
886 | dependencies:
887 | parent-module "^1.0.0"
888 | resolve-from "^4.0.0"
889 |
890 | imurmurhash@^0.1.4:
891 | version "0.1.4"
892 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
893 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
894 |
895 | inflight@^1.0.4:
896 | version "1.0.6"
897 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
898 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
899 | dependencies:
900 | once "^1.3.0"
901 | wrappy "1"
902 |
903 | inherits@2:
904 | version "2.0.4"
905 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
906 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
907 |
908 | internal-slot@^1.0.5:
909 | version "1.0.5"
910 | resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz"
911 | integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==
912 | dependencies:
913 | get-intrinsic "^1.2.0"
914 | has "^1.0.3"
915 | side-channel "^1.0.4"
916 |
917 | is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
918 | version "3.0.2"
919 | resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz"
920 | integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==
921 | dependencies:
922 | call-bind "^1.0.2"
923 | get-intrinsic "^1.2.0"
924 | is-typed-array "^1.1.10"
925 |
926 | is-bigint@^1.0.1:
927 | version "1.0.4"
928 | resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz"
929 | integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
930 | dependencies:
931 | has-bigints "^1.0.1"
932 |
933 | is-boolean-object@^1.1.0:
934 | version "1.1.2"
935 | resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz"
936 | integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
937 | dependencies:
938 | call-bind "^1.0.2"
939 | has-tostringtag "^1.0.0"
940 |
941 | is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
942 | version "1.2.7"
943 | resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
944 | integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
945 |
946 | is-core-module@^2.13.0, is-core-module@^2.13.1:
947 | version "2.13.1"
948 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
949 | integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
950 | dependencies:
951 | hasown "^2.0.0"
952 |
953 | is-date-object@^1.0.1:
954 | version "1.0.5"
955 | resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz"
956 | integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
957 | dependencies:
958 | has-tostringtag "^1.0.0"
959 |
960 | is-docker@^2.0.0:
961 | version "2.2.1"
962 | resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
963 | integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
964 |
965 | is-docker@^3.0.0:
966 | version "3.0.0"
967 | resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz"
968 | integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==
969 |
970 | is-extglob@^2.1.1:
971 | version "2.1.1"
972 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
973 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
974 |
975 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
976 | version "4.0.3"
977 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
978 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
979 | dependencies:
980 | is-extglob "^2.1.1"
981 |
982 | is-inside-container@^1.0.0:
983 | version "1.0.0"
984 | resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz"
985 | integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==
986 | dependencies:
987 | is-docker "^3.0.0"
988 |
989 | is-negative-zero@^2.0.2:
990 | version "2.0.2"
991 | resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz"
992 | integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
993 |
994 | is-number-object@^1.0.4:
995 | version "1.0.7"
996 | resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz"
997 | integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
998 | dependencies:
999 | has-tostringtag "^1.0.0"
1000 |
1001 | is-number@^7.0.0:
1002 | version "7.0.0"
1003 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
1004 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
1005 |
1006 | is-path-inside@^3.0.3:
1007 | version "3.0.3"
1008 | resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
1009 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
1010 |
1011 | is-regex@^1.1.4:
1012 | version "1.1.4"
1013 | resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz"
1014 | integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
1015 | dependencies:
1016 | call-bind "^1.0.2"
1017 | has-tostringtag "^1.0.0"
1018 |
1019 | is-shared-array-buffer@^1.0.2:
1020 | version "1.0.2"
1021 | resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz"
1022 | integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
1023 | dependencies:
1024 | call-bind "^1.0.2"
1025 |
1026 | is-stream@^2.0.0:
1027 | version "2.0.1"
1028 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz"
1029 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
1030 |
1031 | is-stream@^3.0.0:
1032 | version "3.0.0"
1033 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz"
1034 | integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
1035 |
1036 | is-string@^1.0.5, is-string@^1.0.7:
1037 | version "1.0.7"
1038 | resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz"
1039 | integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
1040 | dependencies:
1041 | has-tostringtag "^1.0.0"
1042 |
1043 | is-symbol@^1.0.2, is-symbol@^1.0.3:
1044 | version "1.0.4"
1045 | resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz"
1046 | integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
1047 | dependencies:
1048 | has-symbols "^1.0.2"
1049 |
1050 | is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9:
1051 | version "1.1.12"
1052 | resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz"
1053 | integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==
1054 | dependencies:
1055 | which-typed-array "^1.1.11"
1056 |
1057 | is-weakref@^1.0.2:
1058 | version "1.0.2"
1059 | resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz"
1060 | integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
1061 | dependencies:
1062 | call-bind "^1.0.2"
1063 |
1064 | is-wsl@^2.2.0:
1065 | version "2.2.0"
1066 | resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
1067 | integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
1068 | dependencies:
1069 | is-docker "^2.0.0"
1070 |
1071 | isarray@^2.0.5:
1072 | version "2.0.5"
1073 | resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz"
1074 | integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
1075 |
1076 | isexe@^2.0.0:
1077 | version "2.0.0"
1078 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
1079 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
1080 |
1081 | js-yaml@^4.1.0:
1082 | version "4.1.0"
1083 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
1084 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
1085 | dependencies:
1086 | argparse "^2.0.1"
1087 |
1088 | json-schema-traverse@^0.4.1:
1089 | version "0.4.1"
1090 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
1091 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
1092 |
1093 | json-stable-stringify-without-jsonify@^1.0.1:
1094 | version "1.0.1"
1095 | resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
1096 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
1097 |
1098 | json5@^1.0.2:
1099 | version "1.0.2"
1100 | resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz"
1101 | integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
1102 | dependencies:
1103 | minimist "^1.2.0"
1104 |
1105 | levn@^0.4.1:
1106 | version "0.4.1"
1107 | resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
1108 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
1109 | dependencies:
1110 | prelude-ls "^1.2.1"
1111 | type-check "~0.4.0"
1112 |
1113 | locate-path@^6.0.0:
1114 | version "6.0.0"
1115 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
1116 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
1117 | dependencies:
1118 | p-locate "^5.0.0"
1119 |
1120 | lodash.merge@^4.6.2:
1121 | version "4.6.2"
1122 | resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
1123 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
1124 |
1125 | merge-stream@^2.0.0:
1126 | version "2.0.0"
1127 | resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
1128 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
1129 |
1130 | merge2@^1.3.0:
1131 | version "1.4.1"
1132 | resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
1133 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
1134 |
1135 | micromatch@^4.0.4:
1136 | version "4.0.5"
1137 | resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
1138 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
1139 | dependencies:
1140 | braces "^3.0.2"
1141 | picomatch "^2.3.1"
1142 |
1143 | mimic-fn@^2.1.0:
1144 | version "2.1.0"
1145 | resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
1146 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
1147 |
1148 | mimic-fn@^4.0.0:
1149 | version "4.0.0"
1150 | resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz"
1151 | integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
1152 |
1153 | minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
1154 | version "3.1.2"
1155 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
1156 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
1157 | dependencies:
1158 | brace-expansion "^1.1.7"
1159 |
1160 | minimist@^1.2.0, minimist@^1.2.6:
1161 | version "1.2.8"
1162 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
1163 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
1164 |
1165 | ms@2.1.2, ms@^2.1.1:
1166 | version "2.1.2"
1167 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
1168 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
1169 |
1170 | natural-compare@^1.4.0:
1171 | version "1.4.0"
1172 | resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
1173 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
1174 |
1175 | npm-run-path@^4.0.1:
1176 | version "4.0.1"
1177 | resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz"
1178 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
1179 | dependencies:
1180 | path-key "^3.0.0"
1181 |
1182 | npm-run-path@^5.1.0:
1183 | version "5.1.0"
1184 | resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz"
1185 | integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
1186 | dependencies:
1187 | path-key "^4.0.0"
1188 |
1189 | object-inspect@^1.13.1:
1190 | version "1.13.1"
1191 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
1192 | integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
1193 |
1194 | object-inspect@^1.9.0:
1195 | version "1.12.3"
1196 | resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz"
1197 | integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
1198 |
1199 | object-keys@^1.1.1:
1200 | version "1.1.1"
1201 | resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
1202 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
1203 |
1204 | object.assign@^4.1.4:
1205 | version "4.1.4"
1206 | resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz"
1207 | integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
1208 | dependencies:
1209 | call-bind "^1.0.2"
1210 | define-properties "^1.1.4"
1211 | has-symbols "^1.0.3"
1212 | object-keys "^1.1.1"
1213 |
1214 | object.fromentries@^2.0.7:
1215 | version "2.0.7"
1216 | resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616"
1217 | integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==
1218 | dependencies:
1219 | call-bind "^1.0.2"
1220 | define-properties "^1.2.0"
1221 | es-abstract "^1.22.1"
1222 |
1223 | object.groupby@^1.0.1:
1224 | version "1.0.1"
1225 | resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee"
1226 | integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==
1227 | dependencies:
1228 | call-bind "^1.0.2"
1229 | define-properties "^1.2.0"
1230 | es-abstract "^1.22.1"
1231 | get-intrinsic "^1.2.1"
1232 |
1233 | object.values@^1.1.7:
1234 | version "1.1.7"
1235 | resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a"
1236 | integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==
1237 | dependencies:
1238 | call-bind "^1.0.2"
1239 | define-properties "^1.2.0"
1240 | es-abstract "^1.22.1"
1241 |
1242 | once@^1.3.0:
1243 | version "1.4.0"
1244 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
1245 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
1246 | dependencies:
1247 | wrappy "1"
1248 |
1249 | onetime@^5.1.2:
1250 | version "5.1.2"
1251 | resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
1252 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
1253 | dependencies:
1254 | mimic-fn "^2.1.0"
1255 |
1256 | onetime@^6.0.0:
1257 | version "6.0.0"
1258 | resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz"
1259 | integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
1260 | dependencies:
1261 | mimic-fn "^4.0.0"
1262 |
1263 | open@^9.1.0:
1264 | version "9.1.0"
1265 | resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz"
1266 | integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==
1267 | dependencies:
1268 | default-browser "^4.0.0"
1269 | define-lazy-prop "^3.0.0"
1270 | is-inside-container "^1.0.0"
1271 | is-wsl "^2.2.0"
1272 |
1273 | optionator@^0.9.3:
1274 | version "0.9.3"
1275 | resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz"
1276 | integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==
1277 | dependencies:
1278 | "@aashutoshrathi/word-wrap" "^1.2.3"
1279 | deep-is "^0.1.3"
1280 | fast-levenshtein "^2.0.6"
1281 | levn "^0.4.1"
1282 | prelude-ls "^1.2.1"
1283 | type-check "^0.4.0"
1284 |
1285 | p-limit@^3.0.2:
1286 | version "3.1.0"
1287 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz"
1288 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
1289 | dependencies:
1290 | yocto-queue "^0.1.0"
1291 |
1292 | p-locate@^5.0.0:
1293 | version "5.0.0"
1294 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz"
1295 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
1296 | dependencies:
1297 | p-limit "^3.0.2"
1298 |
1299 | parent-module@^1.0.0:
1300 | version "1.0.1"
1301 | resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
1302 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
1303 | dependencies:
1304 | callsites "^3.0.0"
1305 |
1306 | path-exists@^4.0.0:
1307 | version "4.0.0"
1308 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
1309 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
1310 |
1311 | path-is-absolute@^1.0.0:
1312 | version "1.0.1"
1313 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
1314 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
1315 |
1316 | path-key@^3.0.0, path-key@^3.1.0:
1317 | version "3.1.1"
1318 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
1319 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
1320 |
1321 | path-key@^4.0.0:
1322 | version "4.0.0"
1323 | resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz"
1324 | integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
1325 |
1326 | path-parse@^1.0.7:
1327 | version "1.0.7"
1328 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
1329 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
1330 |
1331 | picocolors@^1.0.0:
1332 | version "1.0.0"
1333 | resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
1334 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
1335 |
1336 | picomatch@^2.3.1:
1337 | version "2.3.1"
1338 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
1339 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
1340 |
1341 | prelude-ls@^1.2.1:
1342 | version "1.2.1"
1343 | resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
1344 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
1345 |
1346 | prettier-linter-helpers@^1.0.0:
1347 | version "1.0.0"
1348 | resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz"
1349 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
1350 | dependencies:
1351 | fast-diff "^1.1.2"
1352 |
1353 | prettier@^3.0.3:
1354 | version "3.0.3"
1355 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
1356 | integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
1357 |
1358 | punycode@^2.1.0:
1359 | version "2.3.0"
1360 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
1361 | integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
1362 |
1363 | queue-microtask@^1.2.2:
1364 | version "1.2.3"
1365 | resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
1366 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
1367 |
1368 | regexp.prototype.flags@^1.5.1:
1369 | version "1.5.1"
1370 | resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e"
1371 | integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==
1372 | dependencies:
1373 | call-bind "^1.0.2"
1374 | define-properties "^1.2.0"
1375 | set-function-name "^2.0.0"
1376 |
1377 | resolve-from@^4.0.0:
1378 | version "4.0.0"
1379 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
1380 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
1381 |
1382 | resolve@^1.22.4:
1383 | version "1.22.4"
1384 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz"
1385 | integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
1386 | dependencies:
1387 | is-core-module "^2.13.0"
1388 | path-parse "^1.0.7"
1389 | supports-preserve-symlinks-flag "^1.0.0"
1390 |
1391 | reusify@^1.0.4:
1392 | version "1.0.4"
1393 | resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
1394 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
1395 |
1396 | rimraf@^3.0.2:
1397 | version "3.0.2"
1398 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
1399 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
1400 | dependencies:
1401 | glob "^7.1.3"
1402 |
1403 | run-applescript@^5.0.0:
1404 | version "5.0.0"
1405 | resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz"
1406 | integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==
1407 | dependencies:
1408 | execa "^5.0.0"
1409 |
1410 | run-parallel@^1.1.9:
1411 | version "1.2.0"
1412 | resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
1413 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
1414 | dependencies:
1415 | queue-microtask "^1.2.2"
1416 |
1417 | safe-array-concat@^1.0.1:
1418 | version "1.0.1"
1419 | resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c"
1420 | integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==
1421 | dependencies:
1422 | call-bind "^1.0.2"
1423 | get-intrinsic "^1.2.1"
1424 | has-symbols "^1.0.3"
1425 | isarray "^2.0.5"
1426 |
1427 | safe-regex-test@^1.0.0:
1428 | version "1.0.0"
1429 | resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz"
1430 | integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==
1431 | dependencies:
1432 | call-bind "^1.0.2"
1433 | get-intrinsic "^1.1.3"
1434 | is-regex "^1.1.4"
1435 |
1436 | semver@^6.3.1:
1437 | version "6.3.1"
1438 | resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
1439 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
1440 |
1441 | set-function-length@^1.1.1:
1442 | version "1.1.1"
1443 | resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed"
1444 | integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==
1445 | dependencies:
1446 | define-data-property "^1.1.1"
1447 | get-intrinsic "^1.2.1"
1448 | gopd "^1.0.1"
1449 | has-property-descriptors "^1.0.0"
1450 |
1451 | set-function-name@^2.0.0:
1452 | version "2.0.1"
1453 | resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a"
1454 | integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==
1455 | dependencies:
1456 | define-data-property "^1.0.1"
1457 | functions-have-names "^1.2.3"
1458 | has-property-descriptors "^1.0.0"
1459 |
1460 | shebang-command@^2.0.0:
1461 | version "2.0.0"
1462 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
1463 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
1464 | dependencies:
1465 | shebang-regex "^3.0.0"
1466 |
1467 | shebang-regex@^3.0.0:
1468 | version "3.0.0"
1469 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
1470 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
1471 |
1472 | side-channel@^1.0.4:
1473 | version "1.0.4"
1474 | resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
1475 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
1476 | dependencies:
1477 | call-bind "^1.0.0"
1478 | get-intrinsic "^1.0.2"
1479 | object-inspect "^1.9.0"
1480 |
1481 | signal-exit@^3.0.3, signal-exit@^3.0.7:
1482 | version "3.0.7"
1483 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
1484 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
1485 |
1486 | string.prototype.trim@^1.2.8:
1487 | version "1.2.8"
1488 | resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd"
1489 | integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==
1490 | dependencies:
1491 | call-bind "^1.0.2"
1492 | define-properties "^1.2.0"
1493 | es-abstract "^1.22.1"
1494 |
1495 | string.prototype.trimend@^1.0.7:
1496 | version "1.0.7"
1497 | resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e"
1498 | integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==
1499 | dependencies:
1500 | call-bind "^1.0.2"
1501 | define-properties "^1.2.0"
1502 | es-abstract "^1.22.1"
1503 |
1504 | string.prototype.trimstart@^1.0.7:
1505 | version "1.0.7"
1506 | resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298"
1507 | integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==
1508 | dependencies:
1509 | call-bind "^1.0.2"
1510 | define-properties "^1.2.0"
1511 | es-abstract "^1.22.1"
1512 |
1513 | strip-ansi@^6.0.1:
1514 | version "6.0.1"
1515 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
1516 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
1517 | dependencies:
1518 | ansi-regex "^5.0.1"
1519 |
1520 | strip-bom@^3.0.0:
1521 | version "3.0.0"
1522 | resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
1523 | integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
1524 |
1525 | strip-final-newline@^2.0.0:
1526 | version "2.0.0"
1527 | resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz"
1528 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
1529 |
1530 | strip-final-newline@^3.0.0:
1531 | version "3.0.0"
1532 | resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz"
1533 | integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
1534 |
1535 | strip-json-comments@^3.1.1:
1536 | version "3.1.1"
1537 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
1538 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
1539 |
1540 | supports-color@^7.1.0:
1541 | version "7.2.0"
1542 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
1543 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
1544 | dependencies:
1545 | has-flag "^4.0.0"
1546 |
1547 | supports-preserve-symlinks-flag@^1.0.0:
1548 | version "1.0.0"
1549 | resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
1550 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
1551 |
1552 | synckit@^0.8.5:
1553 | version "0.8.5"
1554 | resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz"
1555 | integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==
1556 | dependencies:
1557 | "@pkgr/utils" "^2.3.1"
1558 | tslib "^2.5.0"
1559 |
1560 | text-table@^0.2.0:
1561 | version "0.2.0"
1562 | resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
1563 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
1564 |
1565 | titleize@^3.0.0:
1566 | version "3.0.0"
1567 | resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz"
1568 | integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==
1569 |
1570 | to-regex-range@^5.0.1:
1571 | version "5.0.1"
1572 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
1573 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1574 | dependencies:
1575 | is-number "^7.0.0"
1576 |
1577 | tsconfig-paths@^3.14.2:
1578 | version "3.14.2"
1579 | resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz"
1580 | integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
1581 | dependencies:
1582 | "@types/json5" "^0.0.29"
1583 | json5 "^1.0.2"
1584 | minimist "^1.2.6"
1585 | strip-bom "^3.0.0"
1586 |
1587 | tslib@^2.5.0, tslib@^2.6.0:
1588 | version "2.6.1"
1589 | resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz"
1590 | integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==
1591 |
1592 | type-check@^0.4.0, type-check@~0.4.0:
1593 | version "0.4.0"
1594 | resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
1595 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
1596 | dependencies:
1597 | prelude-ls "^1.2.1"
1598 |
1599 | type-fest@^0.20.2:
1600 | version "0.20.2"
1601 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
1602 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
1603 |
1604 | typed-array-buffer@^1.0.0:
1605 | version "1.0.0"
1606 | resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz"
1607 | integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==
1608 | dependencies:
1609 | call-bind "^1.0.2"
1610 | get-intrinsic "^1.2.1"
1611 | is-typed-array "^1.1.10"
1612 |
1613 | typed-array-byte-length@^1.0.0:
1614 | version "1.0.0"
1615 | resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz"
1616 | integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==
1617 | dependencies:
1618 | call-bind "^1.0.2"
1619 | for-each "^0.3.3"
1620 | has-proto "^1.0.1"
1621 | is-typed-array "^1.1.10"
1622 |
1623 | typed-array-byte-offset@^1.0.0:
1624 | version "1.0.0"
1625 | resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz"
1626 | integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==
1627 | dependencies:
1628 | available-typed-arrays "^1.0.5"
1629 | call-bind "^1.0.2"
1630 | for-each "^0.3.3"
1631 | has-proto "^1.0.1"
1632 | is-typed-array "^1.1.10"
1633 |
1634 | typed-array-length@^1.0.4:
1635 | version "1.0.4"
1636 | resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz"
1637 | integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==
1638 | dependencies:
1639 | call-bind "^1.0.2"
1640 | for-each "^0.3.3"
1641 | is-typed-array "^1.1.9"
1642 |
1643 | unbox-primitive@^1.0.2:
1644 | version "1.0.2"
1645 | resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"
1646 | integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
1647 | dependencies:
1648 | call-bind "^1.0.2"
1649 | has-bigints "^1.0.2"
1650 | has-symbols "^1.0.3"
1651 | which-boxed-primitive "^1.0.2"
1652 |
1653 | untildify@^4.0.0:
1654 | version "4.0.0"
1655 | resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz"
1656 | integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
1657 |
1658 | uri-js@^4.2.2:
1659 | version "4.4.1"
1660 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
1661 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
1662 | dependencies:
1663 | punycode "^2.1.0"
1664 |
1665 | which-boxed-primitive@^1.0.2:
1666 | version "1.0.2"
1667 | resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
1668 | integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
1669 | dependencies:
1670 | is-bigint "^1.0.1"
1671 | is-boolean-object "^1.1.0"
1672 | is-number-object "^1.0.4"
1673 | is-string "^1.0.5"
1674 | is-symbol "^1.0.3"
1675 |
1676 | which-typed-array@^1.1.11:
1677 | version "1.1.11"
1678 | resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz"
1679 | integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==
1680 | dependencies:
1681 | available-typed-arrays "^1.0.5"
1682 | call-bind "^1.0.2"
1683 | for-each "^0.3.3"
1684 | gopd "^1.0.1"
1685 | has-tostringtag "^1.0.0"
1686 |
1687 | which-typed-array@^1.1.13:
1688 | version "1.1.13"
1689 | resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36"
1690 | integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==
1691 | dependencies:
1692 | available-typed-arrays "^1.0.5"
1693 | call-bind "^1.0.4"
1694 | for-each "^0.3.3"
1695 | gopd "^1.0.1"
1696 | has-tostringtag "^1.0.0"
1697 |
1698 | which@^2.0.1:
1699 | version "2.0.2"
1700 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
1701 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
1702 | dependencies:
1703 | isexe "^2.0.0"
1704 |
1705 | wrappy@1:
1706 | version "1.0.2"
1707 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
1708 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
1709 |
1710 | yocto-queue@^0.1.0:
1711 | version "0.1.0"
1712 | resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
1713 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
1714 |
--------------------------------------------------------------------------------