├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── release.yml ├── .gitignore ├── .npmrc ├── LICENSE ├── README.md ├── README.zh.md ├── doc ├── changelog.md └── img │ ├── header-auto-numbering-example.gif │ └── yaml-example.gif ├── esbuild.config.mjs ├── manifest.json ├── package-lock.json ├── package.json ├── src ├── config.ts ├── core.ts ├── i18n │ ├── en.ts │ ├── index.ts │ └── zh.ts ├── main.ts ├── setting.ts └── utils.ts ├── styles.css ├── tsconfig.json ├── version-bump.mjs └── versions.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = tab 9 | indent_size = 4 10 | tab_width = 4 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | main.js 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { "node": true }, 5 | "plugins": [ 6 | "@typescript-eslint" 7 | ], 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/eslint-recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parserOptions": { 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-unused-vars": "off", 18 | "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], 19 | "@typescript-eslint/ban-ts-comment": "off", 20 | "no-prototype-builtins": "off", 21 | "@typescript-eslint/no-empty-function": "off" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Obsidian plugin 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Use Node.js 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: "18.x" 19 | 20 | - name: Build plugin 21 | run: | 22 | npm install 23 | npm run build 24 | 25 | - name: Create release 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | run: | 29 | tag="${GITHUB_REF#refs/tags/}" 30 | 31 | gh release create "$tag" \ 32 | --title="$tag" \ 33 | --draft \ 34 | main.js manifest.json styles.css 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # vscode 2 | .vscode 3 | 4 | # Intellij 5 | *.iml 6 | .idea 7 | 8 | # npm 9 | node_modules 10 | 11 | # Don't include the compiled main.js file in the repo. 12 | # They should be uploaded to GitHub releases instead. 13 | main.js 14 | 15 | # Exclude sourcemaps 16 | *.map 17 | 18 | # obsidian 19 | data.json 20 | 21 | # Exclude macOS Finder (System Explorer) View States 22 | .DS_Store 23 | 24 | .git.backup -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Hobee Liu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Obsidian Header Enhancer

2 |
3 | 4 | [[中文](./README.zh.md)] [[English](./README.md)] 5 | 6 |
7 | 8 | This plugin is designed to enhance the header of [Obsidian](https://obsidian.md). The plugin will auto-detect the header level and add the number to the header. 9 | 10 | **Warning:** 11 | - This plugin is still in the early stage of development, so there may be some bugs. If you find any bugs, please feel free to report them in the [issue](https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/issues) 12 | - Data is invaluable, so please remember to create backups when using the beta plugin (which version number like 0.x.x). 13 | 14 | ## Core Features 15 | ### 1. Header Auto Numbering 16 | Header auto numbering provides the ability to add numbers to the header. The number will be added to the header when you press `Enter` key to create a new line and it will be updated when you change the header level. 17 | 18 | **Example:** 19 | 20 | ![header-auto-numbering-example](./doc/img/header-auto-numbering-example.gif) 21 | 22 | **Warning:** 23 | - Header Auto Numbering use `\t` split auto-number and your header. If your header contains `\t`, Header Auto Numbering may not work properly. 24 | - Header Auto Numbering will modify your Markdown source file directly, so that can be rendered in other Markdown editors. 25 | - Please make sure your header not inculde space if you set `Space` as separator. 26 | 27 | ### 2. Isolate Title Font [W.I.P] 28 | Isolate title font provides the ability to isolate the title font from the content. 29 | 30 | ## Installation 31 | 32 | ### From Obsidian \[Recommended\] 33 | 1. Open Settings -> Third-party plugins 34 | 2. Disable Safe mode 35 | 3. Click Browse community plugins 36 | 4. Search for "Header Enhancer" 37 | 5. Click Install 38 | 6. Once installed, close the community plugins window and enable the newly installed plugin 39 | 40 | ### From GitHub 41 | 1. Download the [Latest release](https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/releases/latest) 42 | 2. Extract the zip archive in `/.obsidian/plugins/` so that the `main.js` file is within the folder `/.obsidian/plugins/header-enhancer/`. 43 | 3. Reload Obsidian 44 | 4. If prompted about Safe Mode, you can disable safe mode and enable the plugin. 45 | 46 | ## Usage 47 | ### Header Auto Numbering 48 | Header auto-numbering is enabled by default. You can disable it in the plugin settings. 49 | 50 | #### a. Change auto number start header level 51 | You can change the auto number start header level in the plugin settings. The default value is `1` which means auto number start from H1 or `#`. 52 | 53 | #### b. Custom your numbering style 54 | You can customize your numbering style and observe the style preview in the plugin settings. Currently, only custom separator are supported. 55 | 56 | #### c. Use Yaml to Control Header Numbering 57 | You can use Yaml to control header numbering in the plugin settings. The default value is `false` which means use auto numbering. If you set it to `true`, you can use Yaml to control header numbering. 58 | 59 | **Example:** 60 | ![yaml-example](./doc/img/yaml-example.gif) 61 | 62 | ## Known bugs 63 | Here are some known bugs, I will fix them as soon as possible. 64 | - [ ] When you change the header level, the auto number will not be updated immediately. You need move cursor to header line and press `Enter` key to update it. 65 | 66 | ## Todo list 67 | - [x] Setting support Chinese. - Header Enhancer 68 | 69 | ## ChangeLog 70 | Full changelog can be found [here](./doc/changelog.md). 71 | 72 | ## Acknowledgements 73 | - https://github.com/Yaozhuwa/easy-typing-obsidian 74 | - https://github.com/lijyze/obsidian-state-switcher 75 | - https://github.com/onlyafly/number-headings-obsidian 76 | 77 | ## Support 78 | If you like this plugin, you can support me by: 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 |

Obsidian Header Enhancer|Obsidian 标题增强插件

2 |
3 | 4 | [[中文](./README.zh.md)] [[English](./README.md)] 5 | 6 |
7 | 8 | 这个插件旨在增强 [Obsidian](https://obsidian.md) 的标题。该插件将自动检测标题级别并为标题添加序号。 9 | 10 | **警告:** 11 | - 这个插件还处于早期开发阶段,所以可能存在一些bug。如果您发现任何bug,请随时在[问题跟踪](https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/issues)中报告。 12 | - 数据是无价的,所以请记得在使用测试版插件(版本号像0.x.x)时创建备份。 13 | 14 | ## 核心特性 15 | 16 | ### 1. 标题自动编号 17 | 标题自动编号提供了为标题添加序号的功能。当您按`Enter`键创建新行时,序号将被添加到标题中,并在您更改标题级别时更新。 18 | 19 | **示例:** 20 | 21 | ![header-auto-numbering-example](./doc/img/header-auto-numbering-example.gif) 22 | 23 | **警告:** 24 | - 标题自动编号使用`\t`分隔自动编号和标题。如果您的标题包含`\t`,则标题自动编号可能无法正常工作。 25 | - 标题自动编号将直接修改您的 Markdown 源文件,以便在其他 Markdown 编辑器中呈现。 26 | - 如果您将分隔符设置为`Space`,请确保您的标题不包含空格。 27 | 28 | ### 2. 隔离标题字体 [开发中] 29 | 隔离标题字体提供了将标题字体与内容分离的功能。 30 | 31 | ## 安装 32 | 33 | ### 从Obsidian【推荐】 34 | 1. 打开设置 -> 第三方插件 35 | 2. 禁用安全模式 36 | 3. 点击浏览社区插件 37 | 4. 搜索“Header Enhancer” 38 | 5. 点击安装 39 | 6. 安装完成后,关闭社区插件窗口并启用新安装的插件 40 | 41 | ### 从GitHub 42 | 1. 下载 [最新版本](https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/releases/latest) 43 | 2. 将zip归档提取到`/.obsidian/plugins/`中,以便`main.js`文件在`/.obsidian/plugins/header-enhancer/`文件夹中。 44 | 3. 重新加载Obsidian 45 | 4. 如果提示安全模式,可以禁用安全模式并启用插件。 46 | 47 | ## 用法 48 | ### 标题自动编号 49 | 标题自动编号默认启用。您可以在插件设置中禁用它。 50 | 51 | #### a. 更改自动编号起始标题级别 52 | 您可以在插件设置中更改自动编号的起始标题级别。默认值为`1`,这意味着自动编号从 H1 或 `#` 开始。 53 | 54 | #### b. 自定义编号样式 55 | 您可以在插件设置中自定义编号样式并预览样式。目前仅支持自定义分隔符。 56 | 57 | #### c. 使用Yaml控制标题编号 58 | 您可以在插件设置中使用Yaml控制标题编号。默认值为`false`,这意味着使用自动编号。如果您将其设置为`true`,则可以使用Yaml控制标题编号。 59 | 60 | **示例:** 61 | ![yaml-example](./doc/img/yaml-example.gif) 62 | 63 | ## 已知 bug 64 | 这里列出了一些已知的bug,我会尽快修复它们。 65 | - [ ] 当您更改标题级别时,自动编号不会立即更新。您需要将光标移动到标题行并按`Enter`键来更新它。 66 | 67 | ## 待办事项 68 | - [x] 设置支持中文。 - 标题增强器 69 | 70 | ## 更新日志 71 | 完整的更新日志可以在[这里](./doc/changelog.md).找到。 72 | 73 | ## 致谢 74 | - https://github.com/Yaozhuwa/easy-typing-obsidian 75 | - https://github.com/lijyze/obsidian-state-switcher 76 | - https://github.com/onlyafly/number-headings-obsidian 77 | 78 | ## 支持 79 | 如果您喜欢这个插件,您可以通过以下方式支持我: 80 | 81 | 82 | -------------------------------------------------------------------------------- /doc/changelog.md: -------------------------------------------------------------------------------- 1 | # 更新记录 - Changelog 2 | 3 | ## [0.1.5] - 2024-12-15 4 | ### Added 5 | - 增加多语言支持 - Added multi-language support 6 | 7 | ## [0.1.4] - 2024-06-12 8 | ### Refactor 9 | - 重构了代码,提高了代码质量 - Refactored the code to improve code quality 10 | 11 | ## [0.1.3] - 2023-11-27 12 | ### Fixed 13 | - 修复 issue#16 中提到的【无法忽略代码块中 '#' 的问题 - Fixed the problem of "Unable to Ignore '#' in Code Block" mentioned in issue#16 14 | 15 | ## [0.1.2] - 2023-10-30 16 | ### Fixed 17 | - 修复发版错误 - Fixed release error 18 | 19 | ## [0.1.1] - 2023-10-27 20 | ### Fixed 21 | - 修复发版错误 - Fixed release error 22 | 23 | ## [0.1.0] - 2023-10-27 24 | ### Added 25 | - 增加【支持空格作为分隔符】的功能 - Added the function of "Support Space as Separator" 26 | 27 | ## [0.0.6] - 2023-10-05 28 | ### Added 29 | - 增加【使用Yaml控制标题编号】的功能 - Added the function of "Use Yaml to Control Header Numbering" 30 | 31 | ## [0.0.5] - 2023-10-02 32 | ### Fixed 33 | - 修复 issue#5 中提到的【列表中插入新行】的问题 - Fixed the problem of "Insert New Line in List" mentioned in issue#5 34 | 35 | ## [0.0.4] - 2023-09-09 36 | ### Added 37 | - 增加设置中【预览自定义编号样式】实时渲染的功能 - Added the function of real-time rendering of "Preview Custom Numbering Style" in the settings 38 | ### Fixed 39 | - 修复 issue#1 中提到的【标题开始编号】设置不起作用的问题 - Fixed the problem that the "Title Start Numbering" setting does not work mentioned in issue#1 40 | 41 | ## [0.0.3] - 2023-09-05 42 | ### Changed 43 | - 根据审核意见完成插件修改 - Complete plugin modification according to review opinions 44 | 45 | ## [0.0.2] - 2023-08-07 46 | ### Changed 47 | - 更新插件 id ,为发布做准备 - Update plugin id for release 48 | 49 | ## [0.0.1] - 2023-08-07 50 | ### Added 51 | - 初步完成了主要功能模块 - Primary function modules completed 52 | ### Changed 53 | - 优化了用户体验 - Optimized user experience 54 | ### Fixed 55 | - 修复插入自动编号后光标位移的bug - Fixed cursor displacement bug after inserting automatic numbering 56 | 57 | ## [0.0.0] - 2023-07-01 58 | ### Added 59 | - 创建了项目,初始化了仓库 - Created project and initialized repository -------------------------------------------------------------------------------- /doc/img/header-auto-numbering-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoBeedzc/obsidian-header-enhancer-plugin/0bcc34cfd4c2599fa27d45e3209e2fc4bf22dd1b/doc/img/header-auto-numbering-example.gif -------------------------------------------------------------------------------- /doc/img/yaml-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HoBeedzc/obsidian-header-enhancer-plugin/0bcc34cfd4c2599fa27d45e3209e2fc4bf22dd1b/doc/img/yaml-example.gif -------------------------------------------------------------------------------- /esbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import process from "process"; 3 | import builtins from "builtin-modules"; 4 | 5 | const banner = 6 | `/* 7 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 8 | if you want to view the source, please visit the github repository of this plugin 9 | */ 10 | `; 11 | 12 | const prod = (process.argv[2] === "production"); 13 | 14 | const context = await esbuild.context({ 15 | banner: { 16 | js: banner, 17 | }, 18 | entryPoints: ["./src/main.ts"], 19 | bundle: true, 20 | external: [ 21 | "obsidian", 22 | "electron", 23 | "@codemirror/autocomplete", 24 | "@codemirror/collab", 25 | "@codemirror/commands", 26 | "@codemirror/language", 27 | "@codemirror/lint", 28 | "@codemirror/search", 29 | "@codemirror/state", 30 | "@codemirror/view", 31 | "@lezer/common", 32 | "@lezer/highlight", 33 | "@lezer/lr", 34 | ...builtins], 35 | format: "cjs", 36 | target: "es2018", 37 | logLevel: "info", 38 | sourcemap: prod ? false : "inline", 39 | treeShaking: true, 40 | outfile: "main.js", 41 | }); 42 | 43 | if (prod) { 44 | await context.rebuild(); 45 | process.exit(0); 46 | } else { 47 | await context.watch(); 48 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "header-enhancer", 3 | "name": "Header Enhancer", 4 | "version": "0.1.5", 5 | "minAppVersion": "0.15.0", 6 | "description": "Level up your headers, customize your notes. Header Enhancer makes your notes header better and more useful.", 7 | "author": "Hobee Liu", 8 | "authorUrl": "https://github.com/HoBeedzc", 9 | "fundingUrl": "https://bmc.link/hobee", 10 | "isDesktopOnly": false 11 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-header-enhancer-plugin", 3 | "version": "0.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "obsidian-header-enhancer-plugin", 9 | "version": "0.0.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@codemirror/language": "^6.8.0" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^16.11.6", 16 | "@typescript-eslint/eslint-plugin": "5.29.0", 17 | "@typescript-eslint/parser": "5.29.0", 18 | "builtin-modules": "3.3.0", 19 | "esbuild": "0.17.3", 20 | "obsidian": "latest", 21 | "tslib": "2.4.0", 22 | "typescript": "4.7.4" 23 | } 24 | }, 25 | "node_modules/@codemirror/language": { 26 | "version": "6.8.0", 27 | "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.8.0.tgz", 28 | "integrity": "sha512-r1paAyWOZkfY0RaYEZj3Kul+MiQTEbDvYqf8gPGaRvNneHXCmfSaAVFjwRUPlgxS8yflMxw2CTu6uCMp8R8A2g==", 29 | "dependencies": { 30 | "@codemirror/state": "^6.0.0", 31 | "@codemirror/view": "^6.0.0", 32 | "@lezer/common": "^1.0.0", 33 | "@lezer/highlight": "^1.0.0", 34 | "@lezer/lr": "^1.0.0", 35 | "style-mod": "^4.0.0" 36 | } 37 | }, 38 | "node_modules/@codemirror/state": { 39 | "version": "6.2.1", 40 | "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.1.tgz", 41 | "integrity": "sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==" 42 | }, 43 | "node_modules/@codemirror/view": { 44 | "version": "6.13.0", 45 | "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.13.0.tgz", 46 | "integrity": "sha512-oXTfJzHJ5Tl7f6T8ZO0HKf981zubxgKohjddLobbntbNZHlOZGMRL+pPZGtclDWFaFJWtGBYRGyNdjQ6Xsx5yA==", 47 | "dependencies": { 48 | "@codemirror/state": "^6.1.4", 49 | "style-mod": "^4.0.0", 50 | "w3c-keyname": "^2.2.4" 51 | } 52 | }, 53 | "node_modules/@esbuild/android-arm": { 54 | "version": "0.17.3", 55 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz", 56 | "integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==", 57 | "cpu": [ 58 | "arm" 59 | ], 60 | "dev": true, 61 | "optional": true, 62 | "os": [ 63 | "android" 64 | ], 65 | "engines": { 66 | "node": ">=12" 67 | } 68 | }, 69 | "node_modules/@esbuild/android-arm64": { 70 | "version": "0.17.3", 71 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz", 72 | "integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==", 73 | "cpu": [ 74 | "arm64" 75 | ], 76 | "dev": true, 77 | "optional": true, 78 | "os": [ 79 | "android" 80 | ], 81 | "engines": { 82 | "node": ">=12" 83 | } 84 | }, 85 | "node_modules/@esbuild/android-x64": { 86 | "version": "0.17.3", 87 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz", 88 | "integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==", 89 | "cpu": [ 90 | "x64" 91 | ], 92 | "dev": true, 93 | "optional": true, 94 | "os": [ 95 | "android" 96 | ], 97 | "engines": { 98 | "node": ">=12" 99 | } 100 | }, 101 | "node_modules/@esbuild/darwin-arm64": { 102 | "version": "0.17.3", 103 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz", 104 | "integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==", 105 | "cpu": [ 106 | "arm64" 107 | ], 108 | "dev": true, 109 | "optional": true, 110 | "os": [ 111 | "darwin" 112 | ], 113 | "engines": { 114 | "node": ">=12" 115 | } 116 | }, 117 | "node_modules/@esbuild/darwin-x64": { 118 | "version": "0.17.3", 119 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz", 120 | "integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==", 121 | "cpu": [ 122 | "x64" 123 | ], 124 | "dev": true, 125 | "optional": true, 126 | "os": [ 127 | "darwin" 128 | ], 129 | "engines": { 130 | "node": ">=12" 131 | } 132 | }, 133 | "node_modules/@esbuild/freebsd-arm64": { 134 | "version": "0.17.3", 135 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz", 136 | "integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==", 137 | "cpu": [ 138 | "arm64" 139 | ], 140 | "dev": true, 141 | "optional": true, 142 | "os": [ 143 | "freebsd" 144 | ], 145 | "engines": { 146 | "node": ">=12" 147 | } 148 | }, 149 | "node_modules/@esbuild/freebsd-x64": { 150 | "version": "0.17.3", 151 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz", 152 | "integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==", 153 | "cpu": [ 154 | "x64" 155 | ], 156 | "dev": true, 157 | "optional": true, 158 | "os": [ 159 | "freebsd" 160 | ], 161 | "engines": { 162 | "node": ">=12" 163 | } 164 | }, 165 | "node_modules/@esbuild/linux-arm": { 166 | "version": "0.17.3", 167 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz", 168 | "integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==", 169 | "cpu": [ 170 | "arm" 171 | ], 172 | "dev": true, 173 | "optional": true, 174 | "os": [ 175 | "linux" 176 | ], 177 | "engines": { 178 | "node": ">=12" 179 | } 180 | }, 181 | "node_modules/@esbuild/linux-arm64": { 182 | "version": "0.17.3", 183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz", 184 | "integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==", 185 | "cpu": [ 186 | "arm64" 187 | ], 188 | "dev": true, 189 | "optional": true, 190 | "os": [ 191 | "linux" 192 | ], 193 | "engines": { 194 | "node": ">=12" 195 | } 196 | }, 197 | "node_modules/@esbuild/linux-ia32": { 198 | "version": "0.17.3", 199 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz", 200 | "integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==", 201 | "cpu": [ 202 | "ia32" 203 | ], 204 | "dev": true, 205 | "optional": true, 206 | "os": [ 207 | "linux" 208 | ], 209 | "engines": { 210 | "node": ">=12" 211 | } 212 | }, 213 | "node_modules/@esbuild/linux-loong64": { 214 | "version": "0.17.3", 215 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz", 216 | "integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==", 217 | "cpu": [ 218 | "loong64" 219 | ], 220 | "dev": true, 221 | "optional": true, 222 | "os": [ 223 | "linux" 224 | ], 225 | "engines": { 226 | "node": ">=12" 227 | } 228 | }, 229 | "node_modules/@esbuild/linux-mips64el": { 230 | "version": "0.17.3", 231 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz", 232 | "integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==", 233 | "cpu": [ 234 | "mips64el" 235 | ], 236 | "dev": true, 237 | "optional": true, 238 | "os": [ 239 | "linux" 240 | ], 241 | "engines": { 242 | "node": ">=12" 243 | } 244 | }, 245 | "node_modules/@esbuild/linux-ppc64": { 246 | "version": "0.17.3", 247 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz", 248 | "integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==", 249 | "cpu": [ 250 | "ppc64" 251 | ], 252 | "dev": true, 253 | "optional": true, 254 | "os": [ 255 | "linux" 256 | ], 257 | "engines": { 258 | "node": ">=12" 259 | } 260 | }, 261 | "node_modules/@esbuild/linux-riscv64": { 262 | "version": "0.17.3", 263 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz", 264 | "integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==", 265 | "cpu": [ 266 | "riscv64" 267 | ], 268 | "dev": true, 269 | "optional": true, 270 | "os": [ 271 | "linux" 272 | ], 273 | "engines": { 274 | "node": ">=12" 275 | } 276 | }, 277 | "node_modules/@esbuild/linux-s390x": { 278 | "version": "0.17.3", 279 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz", 280 | "integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==", 281 | "cpu": [ 282 | "s390x" 283 | ], 284 | "dev": true, 285 | "optional": true, 286 | "os": [ 287 | "linux" 288 | ], 289 | "engines": { 290 | "node": ">=12" 291 | } 292 | }, 293 | "node_modules/@esbuild/linux-x64": { 294 | "version": "0.17.3", 295 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz", 296 | "integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==", 297 | "cpu": [ 298 | "x64" 299 | ], 300 | "dev": true, 301 | "optional": true, 302 | "os": [ 303 | "linux" 304 | ], 305 | "engines": { 306 | "node": ">=12" 307 | } 308 | }, 309 | "node_modules/@esbuild/netbsd-x64": { 310 | "version": "0.17.3", 311 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz", 312 | "integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==", 313 | "cpu": [ 314 | "x64" 315 | ], 316 | "dev": true, 317 | "optional": true, 318 | "os": [ 319 | "netbsd" 320 | ], 321 | "engines": { 322 | "node": ">=12" 323 | } 324 | }, 325 | "node_modules/@esbuild/openbsd-x64": { 326 | "version": "0.17.3", 327 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz", 328 | "integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==", 329 | "cpu": [ 330 | "x64" 331 | ], 332 | "dev": true, 333 | "optional": true, 334 | "os": [ 335 | "openbsd" 336 | ], 337 | "engines": { 338 | "node": ">=12" 339 | } 340 | }, 341 | "node_modules/@esbuild/sunos-x64": { 342 | "version": "0.17.3", 343 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz", 344 | "integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==", 345 | "cpu": [ 346 | "x64" 347 | ], 348 | "dev": true, 349 | "optional": true, 350 | "os": [ 351 | "sunos" 352 | ], 353 | "engines": { 354 | "node": ">=12" 355 | } 356 | }, 357 | "node_modules/@esbuild/win32-arm64": { 358 | "version": "0.17.3", 359 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz", 360 | "integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==", 361 | "cpu": [ 362 | "arm64" 363 | ], 364 | "dev": true, 365 | "optional": true, 366 | "os": [ 367 | "win32" 368 | ], 369 | "engines": { 370 | "node": ">=12" 371 | } 372 | }, 373 | "node_modules/@esbuild/win32-ia32": { 374 | "version": "0.17.3", 375 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz", 376 | "integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==", 377 | "cpu": [ 378 | "ia32" 379 | ], 380 | "dev": true, 381 | "optional": true, 382 | "os": [ 383 | "win32" 384 | ], 385 | "engines": { 386 | "node": ">=12" 387 | } 388 | }, 389 | "node_modules/@esbuild/win32-x64": { 390 | "version": "0.17.3", 391 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz", 392 | "integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==", 393 | "cpu": [ 394 | "x64" 395 | ], 396 | "dev": true, 397 | "optional": true, 398 | "os": [ 399 | "win32" 400 | ], 401 | "engines": { 402 | "node": ">=12" 403 | } 404 | }, 405 | "node_modules/@eslint-community/eslint-utils": { 406 | "version": "4.4.0", 407 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 408 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 409 | "dev": true, 410 | "peer": true, 411 | "dependencies": { 412 | "eslint-visitor-keys": "^3.3.0" 413 | }, 414 | "engines": { 415 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 416 | }, 417 | "peerDependencies": { 418 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 419 | } 420 | }, 421 | "node_modules/@eslint-community/regexpp": { 422 | "version": "4.5.1", 423 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", 424 | "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", 425 | "dev": true, 426 | "peer": true, 427 | "engines": { 428 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 429 | } 430 | }, 431 | "node_modules/@eslint/eslintrc": { 432 | "version": "2.0.3", 433 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", 434 | "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", 435 | "dev": true, 436 | "peer": true, 437 | "dependencies": { 438 | "ajv": "^6.12.4", 439 | "debug": "^4.3.2", 440 | "espree": "^9.5.2", 441 | "globals": "^13.19.0", 442 | "ignore": "^5.2.0", 443 | "import-fresh": "^3.2.1", 444 | "js-yaml": "^4.1.0", 445 | "minimatch": "^3.1.2", 446 | "strip-json-comments": "^3.1.1" 447 | }, 448 | "engines": { 449 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 450 | }, 451 | "funding": { 452 | "url": "https://opencollective.com/eslint" 453 | } 454 | }, 455 | "node_modules/@eslint/js": { 456 | "version": "8.42.0", 457 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", 458 | "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", 459 | "dev": true, 460 | "peer": true, 461 | "engines": { 462 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 463 | } 464 | }, 465 | "node_modules/@humanwhocodes/config-array": { 466 | "version": "0.11.10", 467 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", 468 | "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", 469 | "dev": true, 470 | "peer": true, 471 | "dependencies": { 472 | "@humanwhocodes/object-schema": "^1.2.1", 473 | "debug": "^4.1.1", 474 | "minimatch": "^3.0.5" 475 | }, 476 | "engines": { 477 | "node": ">=10.10.0" 478 | } 479 | }, 480 | "node_modules/@humanwhocodes/module-importer": { 481 | "version": "1.0.1", 482 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 483 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 484 | "dev": true, 485 | "peer": true, 486 | "engines": { 487 | "node": ">=12.22" 488 | }, 489 | "funding": { 490 | "type": "github", 491 | "url": "https://github.com/sponsors/nzakas" 492 | } 493 | }, 494 | "node_modules/@humanwhocodes/object-schema": { 495 | "version": "1.2.1", 496 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 497 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 498 | "dev": true, 499 | "peer": true 500 | }, 501 | "node_modules/@lezer/common": { 502 | "version": "1.0.3", 503 | "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.3.tgz", 504 | "integrity": "sha512-JH4wAXCgUOcCGNekQPLhVeUtIqjH0yPBs7vvUdSjyQama9618IOKFJwkv2kcqdhF0my8hQEgCTEJU0GIgnahvA==" 505 | }, 506 | "node_modules/@lezer/highlight": { 507 | "version": "1.1.6", 508 | "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.6.tgz", 509 | "integrity": "sha512-cmSJYa2us+r3SePpRCjN5ymCqCPv+zyXmDl0ciWtVaNiORT/MxM7ZgOMQZADD0o51qOaOg24qc/zBViOIwAjJg==", 510 | "dependencies": { 511 | "@lezer/common": "^1.0.0" 512 | } 513 | }, 514 | "node_modules/@lezer/lr": { 515 | "version": "1.3.6", 516 | "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.6.tgz", 517 | "integrity": "sha512-IDhcWjfxwWACnatUi0GzWBCbochfqxo3LZZlS27LbJh8RVYYXXyR5Ck9659IhkWkhSW/kZlaaiJpUO+YZTUK+Q==", 518 | "dependencies": { 519 | "@lezer/common": "^1.0.0" 520 | } 521 | }, 522 | "node_modules/@nodelib/fs.scandir": { 523 | "version": "2.1.5", 524 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 525 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 526 | "dev": true, 527 | "dependencies": { 528 | "@nodelib/fs.stat": "2.0.5", 529 | "run-parallel": "^1.1.9" 530 | }, 531 | "engines": { 532 | "node": ">= 8" 533 | } 534 | }, 535 | "node_modules/@nodelib/fs.stat": { 536 | "version": "2.0.5", 537 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 538 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 539 | "dev": true, 540 | "engines": { 541 | "node": ">= 8" 542 | } 543 | }, 544 | "node_modules/@nodelib/fs.walk": { 545 | "version": "1.2.8", 546 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 547 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 548 | "dev": true, 549 | "dependencies": { 550 | "@nodelib/fs.scandir": "2.1.5", 551 | "fastq": "^1.6.0" 552 | }, 553 | "engines": { 554 | "node": ">= 8" 555 | } 556 | }, 557 | "node_modules/@types/codemirror": { 558 | "version": "0.0.108", 559 | "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.108.tgz", 560 | "integrity": "sha512-3FGFcus0P7C2UOGCNUVENqObEb4SFk+S8Dnxq7K6aIsLVs/vDtlangl3PEO0ykaKXyK56swVF6Nho7VsA44uhw==", 561 | "dev": true, 562 | "dependencies": { 563 | "@types/tern": "*" 564 | } 565 | }, 566 | "node_modules/@types/estree": { 567 | "version": "1.0.1", 568 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", 569 | "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", 570 | "dev": true 571 | }, 572 | "node_modules/@types/json-schema": { 573 | "version": "7.0.12", 574 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", 575 | "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", 576 | "dev": true 577 | }, 578 | "node_modules/@types/node": { 579 | "version": "16.18.34", 580 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz", 581 | "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==", 582 | "dev": true 583 | }, 584 | "node_modules/@types/tern": { 585 | "version": "0.23.4", 586 | "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.4.tgz", 587 | "integrity": "sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==", 588 | "dev": true, 589 | "dependencies": { 590 | "@types/estree": "*" 591 | } 592 | }, 593 | "node_modules/@typescript-eslint/eslint-plugin": { 594 | "version": "5.29.0", 595 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz", 596 | "integrity": "sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==", 597 | "dev": true, 598 | "dependencies": { 599 | "@typescript-eslint/scope-manager": "5.29.0", 600 | "@typescript-eslint/type-utils": "5.29.0", 601 | "@typescript-eslint/utils": "5.29.0", 602 | "debug": "^4.3.4", 603 | "functional-red-black-tree": "^1.0.1", 604 | "ignore": "^5.2.0", 605 | "regexpp": "^3.2.0", 606 | "semver": "^7.3.7", 607 | "tsutils": "^3.21.0" 608 | }, 609 | "engines": { 610 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 611 | }, 612 | "funding": { 613 | "type": "opencollective", 614 | "url": "https://opencollective.com/typescript-eslint" 615 | }, 616 | "peerDependencies": { 617 | "@typescript-eslint/parser": "^5.0.0", 618 | "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" 619 | }, 620 | "peerDependenciesMeta": { 621 | "typescript": { 622 | "optional": true 623 | } 624 | } 625 | }, 626 | "node_modules/@typescript-eslint/parser": { 627 | "version": "5.29.0", 628 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", 629 | "integrity": "sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==", 630 | "dev": true, 631 | "dependencies": { 632 | "@typescript-eslint/scope-manager": "5.29.0", 633 | "@typescript-eslint/types": "5.29.0", 634 | "@typescript-eslint/typescript-estree": "5.29.0", 635 | "debug": "^4.3.4" 636 | }, 637 | "engines": { 638 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 639 | }, 640 | "funding": { 641 | "type": "opencollective", 642 | "url": "https://opencollective.com/typescript-eslint" 643 | }, 644 | "peerDependencies": { 645 | "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" 646 | }, 647 | "peerDependenciesMeta": { 648 | "typescript": { 649 | "optional": true 650 | } 651 | } 652 | }, 653 | "node_modules/@typescript-eslint/scope-manager": { 654 | "version": "5.29.0", 655 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz", 656 | "integrity": "sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==", 657 | "dev": true, 658 | "dependencies": { 659 | "@typescript-eslint/types": "5.29.0", 660 | "@typescript-eslint/visitor-keys": "5.29.0" 661 | }, 662 | "engines": { 663 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 664 | }, 665 | "funding": { 666 | "type": "opencollective", 667 | "url": "https://opencollective.com/typescript-eslint" 668 | } 669 | }, 670 | "node_modules/@typescript-eslint/type-utils": { 671 | "version": "5.29.0", 672 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz", 673 | "integrity": "sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==", 674 | "dev": true, 675 | "dependencies": { 676 | "@typescript-eslint/utils": "5.29.0", 677 | "debug": "^4.3.4", 678 | "tsutils": "^3.21.0" 679 | }, 680 | "engines": { 681 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 682 | }, 683 | "funding": { 684 | "type": "opencollective", 685 | "url": "https://opencollective.com/typescript-eslint" 686 | }, 687 | "peerDependencies": { 688 | "eslint": "*" 689 | }, 690 | "peerDependenciesMeta": { 691 | "typescript": { 692 | "optional": true 693 | } 694 | } 695 | }, 696 | "node_modules/@typescript-eslint/types": { 697 | "version": "5.29.0", 698 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.29.0.tgz", 699 | "integrity": "sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==", 700 | "dev": true, 701 | "engines": { 702 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 703 | }, 704 | "funding": { 705 | "type": "opencollective", 706 | "url": "https://opencollective.com/typescript-eslint" 707 | } 708 | }, 709 | "node_modules/@typescript-eslint/typescript-estree": { 710 | "version": "5.29.0", 711 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz", 712 | "integrity": "sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==", 713 | "dev": true, 714 | "dependencies": { 715 | "@typescript-eslint/types": "5.29.0", 716 | "@typescript-eslint/visitor-keys": "5.29.0", 717 | "debug": "^4.3.4", 718 | "globby": "^11.1.0", 719 | "is-glob": "^4.0.3", 720 | "semver": "^7.3.7", 721 | "tsutils": "^3.21.0" 722 | }, 723 | "engines": { 724 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 725 | }, 726 | "funding": { 727 | "type": "opencollective", 728 | "url": "https://opencollective.com/typescript-eslint" 729 | }, 730 | "peerDependenciesMeta": { 731 | "typescript": { 732 | "optional": true 733 | } 734 | } 735 | }, 736 | "node_modules/@typescript-eslint/utils": { 737 | "version": "5.29.0", 738 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.29.0.tgz", 739 | "integrity": "sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==", 740 | "dev": true, 741 | "dependencies": { 742 | "@types/json-schema": "^7.0.9", 743 | "@typescript-eslint/scope-manager": "5.29.0", 744 | "@typescript-eslint/types": "5.29.0", 745 | "@typescript-eslint/typescript-estree": "5.29.0", 746 | "eslint-scope": "^5.1.1", 747 | "eslint-utils": "^3.0.0" 748 | }, 749 | "engines": { 750 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 751 | }, 752 | "funding": { 753 | "type": "opencollective", 754 | "url": "https://opencollective.com/typescript-eslint" 755 | }, 756 | "peerDependencies": { 757 | "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" 758 | } 759 | }, 760 | "node_modules/@typescript-eslint/visitor-keys": { 761 | "version": "5.29.0", 762 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz", 763 | "integrity": "sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==", 764 | "dev": true, 765 | "dependencies": { 766 | "@typescript-eslint/types": "5.29.0", 767 | "eslint-visitor-keys": "^3.3.0" 768 | }, 769 | "engines": { 770 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 771 | }, 772 | "funding": { 773 | "type": "opencollective", 774 | "url": "https://opencollective.com/typescript-eslint" 775 | } 776 | }, 777 | "node_modules/acorn": { 778 | "version": "8.8.2", 779 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", 780 | "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", 781 | "dev": true, 782 | "peer": true, 783 | "bin": { 784 | "acorn": "bin/acorn" 785 | }, 786 | "engines": { 787 | "node": ">=0.4.0" 788 | } 789 | }, 790 | "node_modules/acorn-jsx": { 791 | "version": "5.3.2", 792 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 793 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 794 | "dev": true, 795 | "peer": true, 796 | "peerDependencies": { 797 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 798 | } 799 | }, 800 | "node_modules/ajv": { 801 | "version": "6.12.6", 802 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 803 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 804 | "dev": true, 805 | "peer": true, 806 | "dependencies": { 807 | "fast-deep-equal": "^3.1.1", 808 | "fast-json-stable-stringify": "^2.0.0", 809 | "json-schema-traverse": "^0.4.1", 810 | "uri-js": "^4.2.2" 811 | }, 812 | "funding": { 813 | "type": "github", 814 | "url": "https://github.com/sponsors/epoberezkin" 815 | } 816 | }, 817 | "node_modules/ansi-regex": { 818 | "version": "5.0.1", 819 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 820 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 821 | "dev": true, 822 | "peer": true, 823 | "engines": { 824 | "node": ">=8" 825 | } 826 | }, 827 | "node_modules/ansi-styles": { 828 | "version": "4.3.0", 829 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 830 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 831 | "dev": true, 832 | "peer": true, 833 | "dependencies": { 834 | "color-convert": "^2.0.1" 835 | }, 836 | "engines": { 837 | "node": ">=8" 838 | }, 839 | "funding": { 840 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 841 | } 842 | }, 843 | "node_modules/argparse": { 844 | "version": "2.0.1", 845 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 846 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 847 | "dev": true, 848 | "peer": true 849 | }, 850 | "node_modules/array-union": { 851 | "version": "2.1.0", 852 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 853 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 854 | "dev": true, 855 | "engines": { 856 | "node": ">=8" 857 | } 858 | }, 859 | "node_modules/balanced-match": { 860 | "version": "1.0.2", 861 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 862 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 863 | "dev": true, 864 | "peer": true 865 | }, 866 | "node_modules/brace-expansion": { 867 | "version": "1.1.11", 868 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 869 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 870 | "dev": true, 871 | "peer": true, 872 | "dependencies": { 873 | "balanced-match": "^1.0.0", 874 | "concat-map": "0.0.1" 875 | } 876 | }, 877 | "node_modules/braces": { 878 | "version": "3.0.2", 879 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 880 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 881 | "dev": true, 882 | "dependencies": { 883 | "fill-range": "^7.0.1" 884 | }, 885 | "engines": { 886 | "node": ">=8" 887 | } 888 | }, 889 | "node_modules/builtin-modules": { 890 | "version": "3.3.0", 891 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", 892 | "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", 893 | "dev": true, 894 | "engines": { 895 | "node": ">=6" 896 | }, 897 | "funding": { 898 | "url": "https://github.com/sponsors/sindresorhus" 899 | } 900 | }, 901 | "node_modules/callsites": { 902 | "version": "3.1.0", 903 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 904 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 905 | "dev": true, 906 | "peer": true, 907 | "engines": { 908 | "node": ">=6" 909 | } 910 | }, 911 | "node_modules/chalk": { 912 | "version": "4.1.2", 913 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 914 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 915 | "dev": true, 916 | "peer": true, 917 | "dependencies": { 918 | "ansi-styles": "^4.1.0", 919 | "supports-color": "^7.1.0" 920 | }, 921 | "engines": { 922 | "node": ">=10" 923 | }, 924 | "funding": { 925 | "url": "https://github.com/chalk/chalk?sponsor=1" 926 | } 927 | }, 928 | "node_modules/color-convert": { 929 | "version": "2.0.1", 930 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 931 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 932 | "dev": true, 933 | "peer": true, 934 | "dependencies": { 935 | "color-name": "~1.1.4" 936 | }, 937 | "engines": { 938 | "node": ">=7.0.0" 939 | } 940 | }, 941 | "node_modules/color-name": { 942 | "version": "1.1.4", 943 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 944 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 945 | "dev": true, 946 | "peer": true 947 | }, 948 | "node_modules/concat-map": { 949 | "version": "0.0.1", 950 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 951 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 952 | "dev": true, 953 | "peer": true 954 | }, 955 | "node_modules/cross-spawn": { 956 | "version": "7.0.3", 957 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 958 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 959 | "dev": true, 960 | "peer": true, 961 | "dependencies": { 962 | "path-key": "^3.1.0", 963 | "shebang-command": "^2.0.0", 964 | "which": "^2.0.1" 965 | }, 966 | "engines": { 967 | "node": ">= 8" 968 | } 969 | }, 970 | "node_modules/debug": { 971 | "version": "4.3.4", 972 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 973 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 974 | "dev": true, 975 | "dependencies": { 976 | "ms": "2.1.2" 977 | }, 978 | "engines": { 979 | "node": ">=6.0" 980 | }, 981 | "peerDependenciesMeta": { 982 | "supports-color": { 983 | "optional": true 984 | } 985 | } 986 | }, 987 | "node_modules/deep-is": { 988 | "version": "0.1.4", 989 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 990 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 991 | "dev": true, 992 | "peer": true 993 | }, 994 | "node_modules/dir-glob": { 995 | "version": "3.0.1", 996 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 997 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 998 | "dev": true, 999 | "dependencies": { 1000 | "path-type": "^4.0.0" 1001 | }, 1002 | "engines": { 1003 | "node": ">=8" 1004 | } 1005 | }, 1006 | "node_modules/doctrine": { 1007 | "version": "3.0.0", 1008 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 1009 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 1010 | "dev": true, 1011 | "peer": true, 1012 | "dependencies": { 1013 | "esutils": "^2.0.2" 1014 | }, 1015 | "engines": { 1016 | "node": ">=6.0.0" 1017 | } 1018 | }, 1019 | "node_modules/esbuild": { 1020 | "version": "0.17.3", 1021 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz", 1022 | "integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==", 1023 | "dev": true, 1024 | "hasInstallScript": true, 1025 | "bin": { 1026 | "esbuild": "bin/esbuild" 1027 | }, 1028 | "engines": { 1029 | "node": ">=12" 1030 | }, 1031 | "optionalDependencies": { 1032 | "@esbuild/android-arm": "0.17.3", 1033 | "@esbuild/android-arm64": "0.17.3", 1034 | "@esbuild/android-x64": "0.17.3", 1035 | "@esbuild/darwin-arm64": "0.17.3", 1036 | "@esbuild/darwin-x64": "0.17.3", 1037 | "@esbuild/freebsd-arm64": "0.17.3", 1038 | "@esbuild/freebsd-x64": "0.17.3", 1039 | "@esbuild/linux-arm": "0.17.3", 1040 | "@esbuild/linux-arm64": "0.17.3", 1041 | "@esbuild/linux-ia32": "0.17.3", 1042 | "@esbuild/linux-loong64": "0.17.3", 1043 | "@esbuild/linux-mips64el": "0.17.3", 1044 | "@esbuild/linux-ppc64": "0.17.3", 1045 | "@esbuild/linux-riscv64": "0.17.3", 1046 | "@esbuild/linux-s390x": "0.17.3", 1047 | "@esbuild/linux-x64": "0.17.3", 1048 | "@esbuild/netbsd-x64": "0.17.3", 1049 | "@esbuild/openbsd-x64": "0.17.3", 1050 | "@esbuild/sunos-x64": "0.17.3", 1051 | "@esbuild/win32-arm64": "0.17.3", 1052 | "@esbuild/win32-ia32": "0.17.3", 1053 | "@esbuild/win32-x64": "0.17.3" 1054 | } 1055 | }, 1056 | "node_modules/escape-string-regexp": { 1057 | "version": "4.0.0", 1058 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1059 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1060 | "dev": true, 1061 | "peer": true, 1062 | "engines": { 1063 | "node": ">=10" 1064 | }, 1065 | "funding": { 1066 | "url": "https://github.com/sponsors/sindresorhus" 1067 | } 1068 | }, 1069 | "node_modules/eslint": { 1070 | "version": "8.42.0", 1071 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", 1072 | "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", 1073 | "dev": true, 1074 | "peer": true, 1075 | "dependencies": { 1076 | "@eslint-community/eslint-utils": "^4.2.0", 1077 | "@eslint-community/regexpp": "^4.4.0", 1078 | "@eslint/eslintrc": "^2.0.3", 1079 | "@eslint/js": "8.42.0", 1080 | "@humanwhocodes/config-array": "^0.11.10", 1081 | "@humanwhocodes/module-importer": "^1.0.1", 1082 | "@nodelib/fs.walk": "^1.2.8", 1083 | "ajv": "^6.10.0", 1084 | "chalk": "^4.0.0", 1085 | "cross-spawn": "^7.0.2", 1086 | "debug": "^4.3.2", 1087 | "doctrine": "^3.0.0", 1088 | "escape-string-regexp": "^4.0.0", 1089 | "eslint-scope": "^7.2.0", 1090 | "eslint-visitor-keys": "^3.4.1", 1091 | "espree": "^9.5.2", 1092 | "esquery": "^1.4.2", 1093 | "esutils": "^2.0.2", 1094 | "fast-deep-equal": "^3.1.3", 1095 | "file-entry-cache": "^6.0.1", 1096 | "find-up": "^5.0.0", 1097 | "glob-parent": "^6.0.2", 1098 | "globals": "^13.19.0", 1099 | "graphemer": "^1.4.0", 1100 | "ignore": "^5.2.0", 1101 | "import-fresh": "^3.0.0", 1102 | "imurmurhash": "^0.1.4", 1103 | "is-glob": "^4.0.0", 1104 | "is-path-inside": "^3.0.3", 1105 | "js-yaml": "^4.1.0", 1106 | "json-stable-stringify-without-jsonify": "^1.0.1", 1107 | "levn": "^0.4.1", 1108 | "lodash.merge": "^4.6.2", 1109 | "minimatch": "^3.1.2", 1110 | "natural-compare": "^1.4.0", 1111 | "optionator": "^0.9.1", 1112 | "strip-ansi": "^6.0.1", 1113 | "strip-json-comments": "^3.1.0", 1114 | "text-table": "^0.2.0" 1115 | }, 1116 | "bin": { 1117 | "eslint": "bin/eslint.js" 1118 | }, 1119 | "engines": { 1120 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1121 | }, 1122 | "funding": { 1123 | "url": "https://opencollective.com/eslint" 1124 | } 1125 | }, 1126 | "node_modules/eslint-scope": { 1127 | "version": "5.1.1", 1128 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 1129 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 1130 | "dev": true, 1131 | "dependencies": { 1132 | "esrecurse": "^4.3.0", 1133 | "estraverse": "^4.1.1" 1134 | }, 1135 | "engines": { 1136 | "node": ">=8.0.0" 1137 | } 1138 | }, 1139 | "node_modules/eslint-utils": { 1140 | "version": "3.0.0", 1141 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 1142 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 1143 | "dev": true, 1144 | "dependencies": { 1145 | "eslint-visitor-keys": "^2.0.0" 1146 | }, 1147 | "engines": { 1148 | "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" 1149 | }, 1150 | "funding": { 1151 | "url": "https://github.com/sponsors/mysticatea" 1152 | }, 1153 | "peerDependencies": { 1154 | "eslint": ">=5" 1155 | } 1156 | }, 1157 | "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { 1158 | "version": "2.1.0", 1159 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 1160 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 1161 | "dev": true, 1162 | "engines": { 1163 | "node": ">=10" 1164 | } 1165 | }, 1166 | "node_modules/eslint-visitor-keys": { 1167 | "version": "3.4.1", 1168 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", 1169 | "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", 1170 | "dev": true, 1171 | "engines": { 1172 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1173 | }, 1174 | "funding": { 1175 | "url": "https://opencollective.com/eslint" 1176 | } 1177 | }, 1178 | "node_modules/eslint/node_modules/eslint-scope": { 1179 | "version": "7.2.0", 1180 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", 1181 | "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", 1182 | "dev": true, 1183 | "peer": true, 1184 | "dependencies": { 1185 | "esrecurse": "^4.3.0", 1186 | "estraverse": "^5.2.0" 1187 | }, 1188 | "engines": { 1189 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1190 | }, 1191 | "funding": { 1192 | "url": "https://opencollective.com/eslint" 1193 | } 1194 | }, 1195 | "node_modules/eslint/node_modules/estraverse": { 1196 | "version": "5.3.0", 1197 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1198 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1199 | "dev": true, 1200 | "peer": true, 1201 | "engines": { 1202 | "node": ">=4.0" 1203 | } 1204 | }, 1205 | "node_modules/espree": { 1206 | "version": "9.5.2", 1207 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", 1208 | "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", 1209 | "dev": true, 1210 | "peer": true, 1211 | "dependencies": { 1212 | "acorn": "^8.8.0", 1213 | "acorn-jsx": "^5.3.2", 1214 | "eslint-visitor-keys": "^3.4.1" 1215 | }, 1216 | "engines": { 1217 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1218 | }, 1219 | "funding": { 1220 | "url": "https://opencollective.com/eslint" 1221 | } 1222 | }, 1223 | "node_modules/esquery": { 1224 | "version": "1.5.0", 1225 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 1226 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 1227 | "dev": true, 1228 | "peer": true, 1229 | "dependencies": { 1230 | "estraverse": "^5.1.0" 1231 | }, 1232 | "engines": { 1233 | "node": ">=0.10" 1234 | } 1235 | }, 1236 | "node_modules/esquery/node_modules/estraverse": { 1237 | "version": "5.3.0", 1238 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1239 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1240 | "dev": true, 1241 | "peer": true, 1242 | "engines": { 1243 | "node": ">=4.0" 1244 | } 1245 | }, 1246 | "node_modules/esrecurse": { 1247 | "version": "4.3.0", 1248 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1249 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1250 | "dev": true, 1251 | "dependencies": { 1252 | "estraverse": "^5.2.0" 1253 | }, 1254 | "engines": { 1255 | "node": ">=4.0" 1256 | } 1257 | }, 1258 | "node_modules/esrecurse/node_modules/estraverse": { 1259 | "version": "5.3.0", 1260 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1261 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1262 | "dev": true, 1263 | "engines": { 1264 | "node": ">=4.0" 1265 | } 1266 | }, 1267 | "node_modules/estraverse": { 1268 | "version": "4.3.0", 1269 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1270 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1271 | "dev": true, 1272 | "engines": { 1273 | "node": ">=4.0" 1274 | } 1275 | }, 1276 | "node_modules/esutils": { 1277 | "version": "2.0.3", 1278 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1279 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1280 | "dev": true, 1281 | "peer": true, 1282 | "engines": { 1283 | "node": ">=0.10.0" 1284 | } 1285 | }, 1286 | "node_modules/fast-deep-equal": { 1287 | "version": "3.1.3", 1288 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1289 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1290 | "dev": true, 1291 | "peer": true 1292 | }, 1293 | "node_modules/fast-glob": { 1294 | "version": "3.2.12", 1295 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", 1296 | "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", 1297 | "dev": true, 1298 | "dependencies": { 1299 | "@nodelib/fs.stat": "^2.0.2", 1300 | "@nodelib/fs.walk": "^1.2.3", 1301 | "glob-parent": "^5.1.2", 1302 | "merge2": "^1.3.0", 1303 | "micromatch": "^4.0.4" 1304 | }, 1305 | "engines": { 1306 | "node": ">=8.6.0" 1307 | } 1308 | }, 1309 | "node_modules/fast-glob/node_modules/glob-parent": { 1310 | "version": "5.1.2", 1311 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1312 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1313 | "dev": true, 1314 | "dependencies": { 1315 | "is-glob": "^4.0.1" 1316 | }, 1317 | "engines": { 1318 | "node": ">= 6" 1319 | } 1320 | }, 1321 | "node_modules/fast-json-stable-stringify": { 1322 | "version": "2.1.0", 1323 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1324 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1325 | "dev": true, 1326 | "peer": true 1327 | }, 1328 | "node_modules/fast-levenshtein": { 1329 | "version": "2.0.6", 1330 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1331 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1332 | "dev": true, 1333 | "peer": true 1334 | }, 1335 | "node_modules/fastq": { 1336 | "version": "1.15.0", 1337 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 1338 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 1339 | "dev": true, 1340 | "dependencies": { 1341 | "reusify": "^1.0.4" 1342 | } 1343 | }, 1344 | "node_modules/file-entry-cache": { 1345 | "version": "6.0.1", 1346 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 1347 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 1348 | "dev": true, 1349 | "peer": true, 1350 | "dependencies": { 1351 | "flat-cache": "^3.0.4" 1352 | }, 1353 | "engines": { 1354 | "node": "^10.12.0 || >=12.0.0" 1355 | } 1356 | }, 1357 | "node_modules/fill-range": { 1358 | "version": "7.0.1", 1359 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1360 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1361 | "dev": true, 1362 | "dependencies": { 1363 | "to-regex-range": "^5.0.1" 1364 | }, 1365 | "engines": { 1366 | "node": ">=8" 1367 | } 1368 | }, 1369 | "node_modules/find-up": { 1370 | "version": "5.0.0", 1371 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1372 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1373 | "dev": true, 1374 | "peer": true, 1375 | "dependencies": { 1376 | "locate-path": "^6.0.0", 1377 | "path-exists": "^4.0.0" 1378 | }, 1379 | "engines": { 1380 | "node": ">=10" 1381 | }, 1382 | "funding": { 1383 | "url": "https://github.com/sponsors/sindresorhus" 1384 | } 1385 | }, 1386 | "node_modules/flat-cache": { 1387 | "version": "3.0.4", 1388 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 1389 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 1390 | "dev": true, 1391 | "peer": true, 1392 | "dependencies": { 1393 | "flatted": "^3.1.0", 1394 | "rimraf": "^3.0.2" 1395 | }, 1396 | "engines": { 1397 | "node": "^10.12.0 || >=12.0.0" 1398 | } 1399 | }, 1400 | "node_modules/flatted": { 1401 | "version": "3.2.7", 1402 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", 1403 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", 1404 | "dev": true, 1405 | "peer": true 1406 | }, 1407 | "node_modules/fs.realpath": { 1408 | "version": "1.0.0", 1409 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1410 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1411 | "dev": true, 1412 | "peer": true 1413 | }, 1414 | "node_modules/functional-red-black-tree": { 1415 | "version": "1.0.1", 1416 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1417 | "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", 1418 | "dev": true 1419 | }, 1420 | "node_modules/glob": { 1421 | "version": "7.2.3", 1422 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1423 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1424 | "dev": true, 1425 | "peer": true, 1426 | "dependencies": { 1427 | "fs.realpath": "^1.0.0", 1428 | "inflight": "^1.0.4", 1429 | "inherits": "2", 1430 | "minimatch": "^3.1.1", 1431 | "once": "^1.3.0", 1432 | "path-is-absolute": "^1.0.0" 1433 | }, 1434 | "engines": { 1435 | "node": "*" 1436 | }, 1437 | "funding": { 1438 | "url": "https://github.com/sponsors/isaacs" 1439 | } 1440 | }, 1441 | "node_modules/glob-parent": { 1442 | "version": "6.0.2", 1443 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1444 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1445 | "dev": true, 1446 | "peer": true, 1447 | "dependencies": { 1448 | "is-glob": "^4.0.3" 1449 | }, 1450 | "engines": { 1451 | "node": ">=10.13.0" 1452 | } 1453 | }, 1454 | "node_modules/globals": { 1455 | "version": "13.20.0", 1456 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", 1457 | "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", 1458 | "dev": true, 1459 | "peer": true, 1460 | "dependencies": { 1461 | "type-fest": "^0.20.2" 1462 | }, 1463 | "engines": { 1464 | "node": ">=8" 1465 | }, 1466 | "funding": { 1467 | "url": "https://github.com/sponsors/sindresorhus" 1468 | } 1469 | }, 1470 | "node_modules/globby": { 1471 | "version": "11.1.0", 1472 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 1473 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 1474 | "dev": true, 1475 | "dependencies": { 1476 | "array-union": "^2.1.0", 1477 | "dir-glob": "^3.0.1", 1478 | "fast-glob": "^3.2.9", 1479 | "ignore": "^5.2.0", 1480 | "merge2": "^1.4.1", 1481 | "slash": "^3.0.0" 1482 | }, 1483 | "engines": { 1484 | "node": ">=10" 1485 | }, 1486 | "funding": { 1487 | "url": "https://github.com/sponsors/sindresorhus" 1488 | } 1489 | }, 1490 | "node_modules/graphemer": { 1491 | "version": "1.4.0", 1492 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 1493 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 1494 | "dev": true, 1495 | "peer": true 1496 | }, 1497 | "node_modules/has-flag": { 1498 | "version": "4.0.0", 1499 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1500 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1501 | "dev": true, 1502 | "peer": true, 1503 | "engines": { 1504 | "node": ">=8" 1505 | } 1506 | }, 1507 | "node_modules/ignore": { 1508 | "version": "5.2.4", 1509 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", 1510 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", 1511 | "dev": true, 1512 | "engines": { 1513 | "node": ">= 4" 1514 | } 1515 | }, 1516 | "node_modules/import-fresh": { 1517 | "version": "3.3.0", 1518 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 1519 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 1520 | "dev": true, 1521 | "peer": true, 1522 | "dependencies": { 1523 | "parent-module": "^1.0.0", 1524 | "resolve-from": "^4.0.0" 1525 | }, 1526 | "engines": { 1527 | "node": ">=6" 1528 | }, 1529 | "funding": { 1530 | "url": "https://github.com/sponsors/sindresorhus" 1531 | } 1532 | }, 1533 | "node_modules/imurmurhash": { 1534 | "version": "0.1.4", 1535 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1536 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1537 | "dev": true, 1538 | "peer": true, 1539 | "engines": { 1540 | "node": ">=0.8.19" 1541 | } 1542 | }, 1543 | "node_modules/inflight": { 1544 | "version": "1.0.6", 1545 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1546 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1547 | "dev": true, 1548 | "peer": true, 1549 | "dependencies": { 1550 | "once": "^1.3.0", 1551 | "wrappy": "1" 1552 | } 1553 | }, 1554 | "node_modules/inherits": { 1555 | "version": "2.0.4", 1556 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1557 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1558 | "dev": true, 1559 | "peer": true 1560 | }, 1561 | "node_modules/is-extglob": { 1562 | "version": "2.1.1", 1563 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1564 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1565 | "dev": true, 1566 | "engines": { 1567 | "node": ">=0.10.0" 1568 | } 1569 | }, 1570 | "node_modules/is-glob": { 1571 | "version": "4.0.3", 1572 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1573 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1574 | "dev": true, 1575 | "dependencies": { 1576 | "is-extglob": "^2.1.1" 1577 | }, 1578 | "engines": { 1579 | "node": ">=0.10.0" 1580 | } 1581 | }, 1582 | "node_modules/is-number": { 1583 | "version": "7.0.0", 1584 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1585 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1586 | "dev": true, 1587 | "engines": { 1588 | "node": ">=0.12.0" 1589 | } 1590 | }, 1591 | "node_modules/is-path-inside": { 1592 | "version": "3.0.3", 1593 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 1594 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 1595 | "dev": true, 1596 | "peer": true, 1597 | "engines": { 1598 | "node": ">=8" 1599 | } 1600 | }, 1601 | "node_modules/isexe": { 1602 | "version": "2.0.0", 1603 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1604 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1605 | "dev": true, 1606 | "peer": true 1607 | }, 1608 | "node_modules/js-yaml": { 1609 | "version": "4.1.0", 1610 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1611 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1612 | "dev": true, 1613 | "peer": true, 1614 | "dependencies": { 1615 | "argparse": "^2.0.1" 1616 | }, 1617 | "bin": { 1618 | "js-yaml": "bin/js-yaml.js" 1619 | } 1620 | }, 1621 | "node_modules/json-schema-traverse": { 1622 | "version": "0.4.1", 1623 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1624 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1625 | "dev": true, 1626 | "peer": true 1627 | }, 1628 | "node_modules/json-stable-stringify-without-jsonify": { 1629 | "version": "1.0.1", 1630 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1631 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1632 | "dev": true, 1633 | "peer": true 1634 | }, 1635 | "node_modules/levn": { 1636 | "version": "0.4.1", 1637 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1638 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1639 | "dev": true, 1640 | "peer": true, 1641 | "dependencies": { 1642 | "prelude-ls": "^1.2.1", 1643 | "type-check": "~0.4.0" 1644 | }, 1645 | "engines": { 1646 | "node": ">= 0.8.0" 1647 | } 1648 | }, 1649 | "node_modules/locate-path": { 1650 | "version": "6.0.0", 1651 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1652 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1653 | "dev": true, 1654 | "peer": true, 1655 | "dependencies": { 1656 | "p-locate": "^5.0.0" 1657 | }, 1658 | "engines": { 1659 | "node": ">=10" 1660 | }, 1661 | "funding": { 1662 | "url": "https://github.com/sponsors/sindresorhus" 1663 | } 1664 | }, 1665 | "node_modules/lodash.merge": { 1666 | "version": "4.6.2", 1667 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1668 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1669 | "dev": true, 1670 | "peer": true 1671 | }, 1672 | "node_modules/lru-cache": { 1673 | "version": "6.0.0", 1674 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1675 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1676 | "dev": true, 1677 | "dependencies": { 1678 | "yallist": "^4.0.0" 1679 | }, 1680 | "engines": { 1681 | "node": ">=10" 1682 | } 1683 | }, 1684 | "node_modules/merge2": { 1685 | "version": "1.4.1", 1686 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1687 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1688 | "dev": true, 1689 | "engines": { 1690 | "node": ">= 8" 1691 | } 1692 | }, 1693 | "node_modules/micromatch": { 1694 | "version": "4.0.5", 1695 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1696 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1697 | "dev": true, 1698 | "dependencies": { 1699 | "braces": "^3.0.2", 1700 | "picomatch": "^2.3.1" 1701 | }, 1702 | "engines": { 1703 | "node": ">=8.6" 1704 | } 1705 | }, 1706 | "node_modules/minimatch": { 1707 | "version": "3.1.2", 1708 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1709 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1710 | "dev": true, 1711 | "peer": true, 1712 | "dependencies": { 1713 | "brace-expansion": "^1.1.7" 1714 | }, 1715 | "engines": { 1716 | "node": "*" 1717 | } 1718 | }, 1719 | "node_modules/moment": { 1720 | "version": "2.29.4", 1721 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", 1722 | "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", 1723 | "dev": true, 1724 | "engines": { 1725 | "node": "*" 1726 | } 1727 | }, 1728 | "node_modules/ms": { 1729 | "version": "2.1.2", 1730 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1731 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1732 | "dev": true 1733 | }, 1734 | "node_modules/natural-compare": { 1735 | "version": "1.4.0", 1736 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1737 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1738 | "dev": true, 1739 | "peer": true 1740 | }, 1741 | "node_modules/obsidian": { 1742 | "version": "1.2.8", 1743 | "resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.2.8.tgz", 1744 | "integrity": "sha512-HrC+feA8o0tXspj4lEAqxb1btwLwHD2oHXSwbbN+CdRHURqbCkuIDLld+nkuyJ1w1c9uvVDRVk8BoeOnWheOrQ==", 1745 | "dev": true, 1746 | "dependencies": { 1747 | "@types/codemirror": "0.0.108", 1748 | "moment": "2.29.4" 1749 | }, 1750 | "peerDependencies": { 1751 | "@codemirror/state": "^6.0.0", 1752 | "@codemirror/view": "^6.0.0" 1753 | } 1754 | }, 1755 | "node_modules/once": { 1756 | "version": "1.4.0", 1757 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1758 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1759 | "dev": true, 1760 | "peer": true, 1761 | "dependencies": { 1762 | "wrappy": "1" 1763 | } 1764 | }, 1765 | "node_modules/optionator": { 1766 | "version": "0.9.1", 1767 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1768 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1769 | "dev": true, 1770 | "peer": true, 1771 | "dependencies": { 1772 | "deep-is": "^0.1.3", 1773 | "fast-levenshtein": "^2.0.6", 1774 | "levn": "^0.4.1", 1775 | "prelude-ls": "^1.2.1", 1776 | "type-check": "^0.4.0", 1777 | "word-wrap": "^1.2.3" 1778 | }, 1779 | "engines": { 1780 | "node": ">= 0.8.0" 1781 | } 1782 | }, 1783 | "node_modules/p-limit": { 1784 | "version": "3.1.0", 1785 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1786 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1787 | "dev": true, 1788 | "peer": true, 1789 | "dependencies": { 1790 | "yocto-queue": "^0.1.0" 1791 | }, 1792 | "engines": { 1793 | "node": ">=10" 1794 | }, 1795 | "funding": { 1796 | "url": "https://github.com/sponsors/sindresorhus" 1797 | } 1798 | }, 1799 | "node_modules/p-locate": { 1800 | "version": "5.0.0", 1801 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1802 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1803 | "dev": true, 1804 | "peer": true, 1805 | "dependencies": { 1806 | "p-limit": "^3.0.2" 1807 | }, 1808 | "engines": { 1809 | "node": ">=10" 1810 | }, 1811 | "funding": { 1812 | "url": "https://github.com/sponsors/sindresorhus" 1813 | } 1814 | }, 1815 | "node_modules/parent-module": { 1816 | "version": "1.0.1", 1817 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1818 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1819 | "dev": true, 1820 | "peer": true, 1821 | "dependencies": { 1822 | "callsites": "^3.0.0" 1823 | }, 1824 | "engines": { 1825 | "node": ">=6" 1826 | } 1827 | }, 1828 | "node_modules/path-exists": { 1829 | "version": "4.0.0", 1830 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1831 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1832 | "dev": true, 1833 | "peer": true, 1834 | "engines": { 1835 | "node": ">=8" 1836 | } 1837 | }, 1838 | "node_modules/path-is-absolute": { 1839 | "version": "1.0.1", 1840 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1841 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1842 | "dev": true, 1843 | "peer": true, 1844 | "engines": { 1845 | "node": ">=0.10.0" 1846 | } 1847 | }, 1848 | "node_modules/path-key": { 1849 | "version": "3.1.1", 1850 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1851 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1852 | "dev": true, 1853 | "peer": true, 1854 | "engines": { 1855 | "node": ">=8" 1856 | } 1857 | }, 1858 | "node_modules/path-type": { 1859 | "version": "4.0.0", 1860 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1861 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1862 | "dev": true, 1863 | "engines": { 1864 | "node": ">=8" 1865 | } 1866 | }, 1867 | "node_modules/picomatch": { 1868 | "version": "2.3.1", 1869 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1870 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1871 | "dev": true, 1872 | "engines": { 1873 | "node": ">=8.6" 1874 | }, 1875 | "funding": { 1876 | "url": "https://github.com/sponsors/jonschlinkert" 1877 | } 1878 | }, 1879 | "node_modules/prelude-ls": { 1880 | "version": "1.2.1", 1881 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1882 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1883 | "dev": true, 1884 | "peer": true, 1885 | "engines": { 1886 | "node": ">= 0.8.0" 1887 | } 1888 | }, 1889 | "node_modules/punycode": { 1890 | "version": "2.3.0", 1891 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", 1892 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", 1893 | "dev": true, 1894 | "peer": true, 1895 | "engines": { 1896 | "node": ">=6" 1897 | } 1898 | }, 1899 | "node_modules/queue-microtask": { 1900 | "version": "1.2.3", 1901 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1902 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1903 | "dev": true, 1904 | "funding": [ 1905 | { 1906 | "type": "github", 1907 | "url": "https://github.com/sponsors/feross" 1908 | }, 1909 | { 1910 | "type": "patreon", 1911 | "url": "https://www.patreon.com/feross" 1912 | }, 1913 | { 1914 | "type": "consulting", 1915 | "url": "https://feross.org/support" 1916 | } 1917 | ] 1918 | }, 1919 | "node_modules/regexpp": { 1920 | "version": "3.2.0", 1921 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 1922 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 1923 | "dev": true, 1924 | "engines": { 1925 | "node": ">=8" 1926 | }, 1927 | "funding": { 1928 | "url": "https://github.com/sponsors/mysticatea" 1929 | } 1930 | }, 1931 | "node_modules/resolve-from": { 1932 | "version": "4.0.0", 1933 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1934 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1935 | "dev": true, 1936 | "peer": true, 1937 | "engines": { 1938 | "node": ">=4" 1939 | } 1940 | }, 1941 | "node_modules/reusify": { 1942 | "version": "1.0.4", 1943 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1944 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1945 | "dev": true, 1946 | "engines": { 1947 | "iojs": ">=1.0.0", 1948 | "node": ">=0.10.0" 1949 | } 1950 | }, 1951 | "node_modules/rimraf": { 1952 | "version": "3.0.2", 1953 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1954 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1955 | "dev": true, 1956 | "peer": true, 1957 | "dependencies": { 1958 | "glob": "^7.1.3" 1959 | }, 1960 | "bin": { 1961 | "rimraf": "bin.js" 1962 | }, 1963 | "funding": { 1964 | "url": "https://github.com/sponsors/isaacs" 1965 | } 1966 | }, 1967 | "node_modules/run-parallel": { 1968 | "version": "1.2.0", 1969 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1970 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1971 | "dev": true, 1972 | "funding": [ 1973 | { 1974 | "type": "github", 1975 | "url": "https://github.com/sponsors/feross" 1976 | }, 1977 | { 1978 | "type": "patreon", 1979 | "url": "https://www.patreon.com/feross" 1980 | }, 1981 | { 1982 | "type": "consulting", 1983 | "url": "https://feross.org/support" 1984 | } 1985 | ], 1986 | "dependencies": { 1987 | "queue-microtask": "^1.2.2" 1988 | } 1989 | }, 1990 | "node_modules/semver": { 1991 | "version": "7.5.1", 1992 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", 1993 | "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", 1994 | "dev": true, 1995 | "dependencies": { 1996 | "lru-cache": "^6.0.0" 1997 | }, 1998 | "bin": { 1999 | "semver": "bin/semver.js" 2000 | }, 2001 | "engines": { 2002 | "node": ">=10" 2003 | } 2004 | }, 2005 | "node_modules/shebang-command": { 2006 | "version": "2.0.0", 2007 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2008 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2009 | "dev": true, 2010 | "peer": true, 2011 | "dependencies": { 2012 | "shebang-regex": "^3.0.0" 2013 | }, 2014 | "engines": { 2015 | "node": ">=8" 2016 | } 2017 | }, 2018 | "node_modules/shebang-regex": { 2019 | "version": "3.0.0", 2020 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2021 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2022 | "dev": true, 2023 | "peer": true, 2024 | "engines": { 2025 | "node": ">=8" 2026 | } 2027 | }, 2028 | "node_modules/slash": { 2029 | "version": "3.0.0", 2030 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 2031 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 2032 | "dev": true, 2033 | "engines": { 2034 | "node": ">=8" 2035 | } 2036 | }, 2037 | "node_modules/strip-ansi": { 2038 | "version": "6.0.1", 2039 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2040 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2041 | "dev": true, 2042 | "peer": true, 2043 | "dependencies": { 2044 | "ansi-regex": "^5.0.1" 2045 | }, 2046 | "engines": { 2047 | "node": ">=8" 2048 | } 2049 | }, 2050 | "node_modules/strip-json-comments": { 2051 | "version": "3.1.1", 2052 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2053 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2054 | "dev": true, 2055 | "peer": true, 2056 | "engines": { 2057 | "node": ">=8" 2058 | }, 2059 | "funding": { 2060 | "url": "https://github.com/sponsors/sindresorhus" 2061 | } 2062 | }, 2063 | "node_modules/style-mod": { 2064 | "version": "4.0.3", 2065 | "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.3.tgz", 2066 | "integrity": "sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==" 2067 | }, 2068 | "node_modules/supports-color": { 2069 | "version": "7.2.0", 2070 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2071 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2072 | "dev": true, 2073 | "peer": true, 2074 | "dependencies": { 2075 | "has-flag": "^4.0.0" 2076 | }, 2077 | "engines": { 2078 | "node": ">=8" 2079 | } 2080 | }, 2081 | "node_modules/text-table": { 2082 | "version": "0.2.0", 2083 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2084 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 2085 | "dev": true, 2086 | "peer": true 2087 | }, 2088 | "node_modules/to-regex-range": { 2089 | "version": "5.0.1", 2090 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2091 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2092 | "dev": true, 2093 | "dependencies": { 2094 | "is-number": "^7.0.0" 2095 | }, 2096 | "engines": { 2097 | "node": ">=8.0" 2098 | } 2099 | }, 2100 | "node_modules/tslib": { 2101 | "version": "2.4.0", 2102 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", 2103 | "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", 2104 | "dev": true 2105 | }, 2106 | "node_modules/tsutils": { 2107 | "version": "3.21.0", 2108 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", 2109 | "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", 2110 | "dev": true, 2111 | "dependencies": { 2112 | "tslib": "^1.8.1" 2113 | }, 2114 | "engines": { 2115 | "node": ">= 6" 2116 | }, 2117 | "peerDependencies": { 2118 | "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" 2119 | } 2120 | }, 2121 | "node_modules/tsutils/node_modules/tslib": { 2122 | "version": "1.14.1", 2123 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 2124 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", 2125 | "dev": true 2126 | }, 2127 | "node_modules/type-check": { 2128 | "version": "0.4.0", 2129 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2130 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2131 | "dev": true, 2132 | "peer": true, 2133 | "dependencies": { 2134 | "prelude-ls": "^1.2.1" 2135 | }, 2136 | "engines": { 2137 | "node": ">= 0.8.0" 2138 | } 2139 | }, 2140 | "node_modules/type-fest": { 2141 | "version": "0.20.2", 2142 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 2143 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 2144 | "dev": true, 2145 | "peer": true, 2146 | "engines": { 2147 | "node": ">=10" 2148 | }, 2149 | "funding": { 2150 | "url": "https://github.com/sponsors/sindresorhus" 2151 | } 2152 | }, 2153 | "node_modules/typescript": { 2154 | "version": "4.7.4", 2155 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", 2156 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", 2157 | "dev": true, 2158 | "bin": { 2159 | "tsc": "bin/tsc", 2160 | "tsserver": "bin/tsserver" 2161 | }, 2162 | "engines": { 2163 | "node": ">=4.2.0" 2164 | } 2165 | }, 2166 | "node_modules/uri-js": { 2167 | "version": "4.4.1", 2168 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2169 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2170 | "dev": true, 2171 | "peer": true, 2172 | "dependencies": { 2173 | "punycode": "^2.1.0" 2174 | } 2175 | }, 2176 | "node_modules/w3c-keyname": { 2177 | "version": "2.2.7", 2178 | "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.7.tgz", 2179 | "integrity": "sha512-XB8aa62d4rrVfoZYQaYNy3fy+z4nrfy2ooea3/0BnBzXW0tSdZ+lRgjzBZhk0La0H6h8fVyYCxx/qkQcAIuvfg==" 2180 | }, 2181 | "node_modules/which": { 2182 | "version": "2.0.2", 2183 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2184 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2185 | "dev": true, 2186 | "peer": true, 2187 | "dependencies": { 2188 | "isexe": "^2.0.0" 2189 | }, 2190 | "bin": { 2191 | "node-which": "bin/node-which" 2192 | }, 2193 | "engines": { 2194 | "node": ">= 8" 2195 | } 2196 | }, 2197 | "node_modules/word-wrap": { 2198 | "version": "1.2.3", 2199 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2200 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2201 | "dev": true, 2202 | "peer": true, 2203 | "engines": { 2204 | "node": ">=0.10.0" 2205 | } 2206 | }, 2207 | "node_modules/wrappy": { 2208 | "version": "1.0.2", 2209 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2210 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2211 | "dev": true, 2212 | "peer": true 2213 | }, 2214 | "node_modules/yallist": { 2215 | "version": "4.0.0", 2216 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2217 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2218 | "dev": true 2219 | }, 2220 | "node_modules/yocto-queue": { 2221 | "version": "0.1.0", 2222 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2223 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2224 | "dev": true, 2225 | "peer": true, 2226 | "engines": { 2227 | "node": ">=10" 2228 | }, 2229 | "funding": { 2230 | "url": "https://github.com/sponsors/sindresorhus" 2231 | } 2232 | } 2233 | } 2234 | } 2235 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-header-enhancer-plugin", 3 | "version": "0.0.1", 4 | "description": "This plugin is used to enhance the title and header of Obsidian.", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "node esbuild.config.mjs", 8 | "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", 9 | "version": "node version-bump.mjs && git add manifest.json versions.json" 10 | }, 11 | "keywords": [ 12 | "Header Enhancement" 13 | ], 14 | "author": "Hobee Liu", 15 | "license": "MIT", 16 | "devDependencies": { 17 | "@types/node": "^16.11.6", 18 | "@typescript-eslint/eslint-plugin": "5.29.0", 19 | "@typescript-eslint/parser": "5.29.0", 20 | "builtin-modules": "3.3.0", 21 | "esbuild": "0.17.3", 22 | "obsidian": "latest", 23 | "tslib": "2.4.0", 24 | "typescript": "4.7.4" 25 | }, 26 | "dependencies": { 27 | "@codemirror/language": "^6.8.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from "obsidian"; 2 | import { HeaderEnhancerSettings } from "./setting"; 3 | import { getAutoNumberingYaml } from "./utils"; 4 | 5 | export interface AutoNumberingConfig { 6 | state: boolean; 7 | startLevel: number; 8 | maxLevel: number; 9 | startNumber: number; 10 | separator: string; 11 | } 12 | 13 | export function getAutoNumberingConfig( 14 | setting: HeaderEnhancerSettings, 15 | editor: Editor 16 | ): AutoNumberingConfig { 17 | const config: AutoNumberingConfig = { 18 | state: setting.isAutoNumbering, 19 | startLevel: setting.startHeaderLevel, 20 | maxLevel: setting.maxHeaderLevel, 21 | startNumber: parseInt(setting.autoNumberingStartNumber), 22 | separator: setting.autoNumberingSeparator, 23 | }; 24 | 25 | if (setting.isUseYaml) { 26 | const yaml = getAutoNumberingYaml(editor); 27 | if (yaml === "") return config; 28 | 29 | for (const item of yaml) { 30 | const [key, value] = item.split(" "); 31 | switch (key) { 32 | case "state": 33 | config.state = value == "on" ? true : false; 34 | break; 35 | case "start-level": 36 | config.startLevel = parseInt(value[1]); 37 | break; 38 | case "max-level": 39 | config.maxLevel = parseInt(value[1]); 40 | break; 41 | case "start-number": 42 | config.startNumber = parseInt(value); 43 | break; 44 | case "separator": 45 | config.separator = value; 46 | break; 47 | } 48 | } 49 | } 50 | return config; 51 | } 52 | -------------------------------------------------------------------------------- /src/core.ts: -------------------------------------------------------------------------------- 1 | export function getHeaderLevel( 2 | text: string, 3 | startHeaderLevel: number 4 | ): [number, number] { 5 | const match = text.match(/^#+/); 6 | if (!match) return [0, 0]; 7 | let level = match ? match[0].length : 0; 8 | return [level - startHeaderLevel + 1, level]; 9 | } 10 | 11 | export function getNextNumber( 12 | cntNums: number[], 13 | headerLevel: number 14 | ): number[] { 15 | let nextNums = [...cntNums]; 16 | if (nextNums.length >= headerLevel) { 17 | nextNums = nextNums.slice(0, headerLevel); 18 | nextNums[nextNums.length - 1]++; 19 | } else { 20 | while (nextNums.length < headerLevel) { 21 | nextNums.push(1); 22 | } 23 | } 24 | return nextNums; 25 | } 26 | 27 | export function isNeedInsertNumber(text: string, splitor: string): boolean { 28 | // '## header' true 29 | // '## 1.1 splitor header' false 30 | if (splitor == " ") return text.split(splitor).length === 2; 31 | else return !text.contains(splitor); 32 | } 33 | 34 | export function isNeedUpdateNumber( 35 | nextNumsStr: string, 36 | text: string, 37 | splitor: string 38 | ): boolean { 39 | let cntNumsStr: string; 40 | if (splitor == " ") { 41 | cntNumsStr = text.split(splitor)[1]; 42 | } else { 43 | cntNumsStr = text.split(splitor)[0].split(" ")[0]; 44 | } 45 | return nextNumsStr !== cntNumsStr; 46 | } 47 | 48 | export function removeHeaderNumber(text: string, splitor: string): string { 49 | // remove '1.1 splitor' from '## 1.1 splitor text' 50 | let sharp: string, header: string; 51 | if (splitor == " ") { 52 | sharp = text.split(splitor)[0]; 53 | header = text.split(splitor)[2]; 54 | } else { 55 | if (!text.contains(splitor)) return text; 56 | sharp = text.split(splitor)[0].split(" ")[0]; 57 | header = text.split(splitor)[1]; 58 | } 59 | return sharp + " " + header; 60 | } 61 | 62 | export function isHeader(text: string): boolean { 63 | return /^#{1,6} .*/.test(text.trim()); 64 | } 65 | -------------------------------------------------------------------------------- /src/i18n/en.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | settings: { 3 | title: "Header Enhancer Settings", 4 | general: "General", 5 | language: { 6 | name: "Language", 7 | desc: "Language for automatic numbering" 8 | }, 9 | statusBar: { 10 | name: "Show on Status Bar", 11 | desc: "Show current header level on status bar" 12 | }, 13 | autoDetect: { 14 | name: "Auto Detect Header Level", 15 | desc: "Automatically detect header level based on context" 16 | }, 17 | headerLevel: { 18 | start: { 19 | name: "Start Header Level", 20 | desc: "The starting level for headers" 21 | }, 22 | max: { 23 | name: "Max Header Level", 24 | desc: "Maximum level for headers" 25 | } 26 | }, 27 | autoNumbering: { 28 | title: "Header Auto Numbering", 29 | enable: { 30 | name: "Enable Auto Numbering", 31 | desc: "Enable automatic header numbering", 32 | notice: "You can only change this option in side bar" 33 | }, 34 | useYaml: { 35 | name: "Use YAML", 36 | desc: "Use YAML to control the format of header numbers" 37 | }, 38 | headerLevel: { 39 | name: "Header Level Settings", 40 | desc: "Configure the header level settings" 41 | }, 42 | startNumber: { 43 | name: "Start Number", 44 | desc: "Start numbering at this number", 45 | placeholder: "Enter a number" 46 | }, 47 | separator: { 48 | name: "Number Separator", 49 | desc: "Separator between numbers (one of '. , / -')", 50 | placeholder: "Enter separator" 51 | }, 52 | headerSeparator: { 53 | name: "Header Separator", 54 | desc: "Separator between header number and text", 55 | error: "You can't change header separator when auto numbering is enabled" 56 | }, 57 | format: { 58 | name: "Your auto numbering format is", 59 | fromLevel: "from H", 60 | toLevel: "to H", 61 | autoDetect: "[Auto Detect]", 62 | manual: "[Manual]" 63 | } 64 | }, 65 | font: { 66 | title: "Title Font Settings", 67 | separate: { 68 | name: "Separate Title Font", 69 | desc: "Use different font settings for titles", 70 | notice: "This feature is not available now, please wait for the next version" 71 | }, 72 | family: { 73 | name: "Font Family", 74 | desc: "Title font family (inherit from global font by default)", 75 | placeholder: "global font" 76 | }, 77 | size: { 78 | name: "Font Size", 79 | desc: "Title font size (inherit from global font size by default)", 80 | placeholder: "global font size" 81 | } 82 | }, 83 | reset: { 84 | name: "Reset Settings", 85 | confirm: "Are you sure you want to reset settings to default?" 86 | }, 87 | moreInfo: "More Information", 88 | author: "Author: ", 89 | license: "License: ", 90 | githubRepo: "Github Repository: ", 91 | anyQuestion: "Any questions? Send feedback on " 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import en from './en'; 2 | import zh from './zh'; 3 | 4 | export type Translation = typeof en; 5 | 6 | const translations: { [key: string]: Translation } = { 7 | en, 8 | zh 9 | }; 10 | 11 | export class I18n { 12 | private static instance: I18n; 13 | private currentLanguage: string = 'en'; 14 | 15 | private constructor() {} 16 | 17 | public static getInstance(): I18n { 18 | if (!I18n.instance) { 19 | I18n.instance = new I18n(); 20 | } 21 | return I18n.instance; 22 | } 23 | 24 | public setLanguage(lang: string): void { 25 | if (translations[lang]) { 26 | this.currentLanguage = lang; 27 | } 28 | } 29 | 30 | public t(key: string): string { 31 | const keys = key.split('.'); 32 | let value: any = translations[this.currentLanguage]; 33 | 34 | for (const k of keys) { 35 | if (value && value[k]) { 36 | value = value[k]; 37 | } else { 38 | // Fallback to English if translation is missing 39 | value = translations['en']; 40 | for (const fallbackKey of keys) { 41 | if (value && value[fallbackKey]) { 42 | value = value[fallbackKey]; 43 | } else { 44 | return key; // Return the key if translation is missing 45 | } 46 | } 47 | } 48 | } 49 | 50 | return typeof value === 'string' ? value : key; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/i18n/zh.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | settings: { 3 | title: "标题增强设置", 4 | general: "常规", 5 | language: { 6 | name: "语言", 7 | desc: "自动编号的语言" 8 | }, 9 | statusBar: { 10 | name: "在状态栏显示", 11 | desc: "在状态栏显示当前标题级别" 12 | }, 13 | autoDetect: { 14 | name: "自动检测标题级别", 15 | desc: "根据上下文自动检测标题级别" 16 | }, 17 | headerLevel: { 18 | start: { 19 | name: "起始标题级别", 20 | desc: "标题的起始级别" 21 | }, 22 | max: { 23 | name: "最大标题级别", 24 | desc: "标题的最大级别" 25 | } 26 | }, 27 | autoNumbering: { 28 | title: "标题自动编号", 29 | enable: { 30 | name: "启用自动编号", 31 | desc: "启用标题自动编号", 32 | notice: "此选项只能在侧边栏中更改" 33 | }, 34 | useYaml: { 35 | name: "使用YAML", 36 | desc: "使用YAML控制标题编号格式" 37 | }, 38 | headerLevel: { 39 | name: "标题级别设置", 40 | desc: "配置标题级别设置" 41 | }, 42 | startNumber: { 43 | name: "起始编号", 44 | desc: "自动编号的起始数字", 45 | placeholder: "输入数字" 46 | }, 47 | separator: { 48 | name: "数字分隔符", 49 | desc: "数字之间的分隔符(可选 '. , / -')", 50 | placeholder: "输入分隔符" 51 | }, 52 | headerSeparator: { 53 | name: "标题分隔符", 54 | desc: "标题编号和文本之间的分隔符", 55 | error: "启用自动编号时无法更改标题分隔符" 56 | }, 57 | format: { 58 | name: "你的自动编号格式是", 59 | fromLevel: "从 H", 60 | toLevel: "到 H", 61 | autoDetect: "[自动检测]", 62 | manual: "[手动]" 63 | } 64 | }, 65 | font: { 66 | title: "标题字体设置", 67 | separate: { 68 | name: "独立标题字体", 69 | desc: "为标题使用不同的字体设置", 70 | notice: "此功能暂不可用,请等待下一个版本" 71 | }, 72 | family: { 73 | name: "字体系列", 74 | desc: "标题字体系列(默认继承全局字体)", 75 | placeholder: "全局字体" 76 | }, 77 | size: { 78 | name: "字体大小", 79 | desc: "标题字体大小(默认继承全局字体大小)", 80 | placeholder: "全局字体大小" 81 | } 82 | }, 83 | reset: { 84 | name: "重置设置", 85 | confirm: "确定要将设置重置为默认值吗?" 86 | }, 87 | moreInfo: "更多信息", 88 | author: "作者:", 89 | license: "许可证:", 90 | githubRepo: "Github仓库:", 91 | anyQuestion: "有任何问题?请在这里反馈" 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { MarkdownView, Notice, Plugin } from "obsidian"; 2 | import { EditorView, keymap } from "@codemirror/view"; 3 | import { Prec } from "@codemirror/state"; 4 | 5 | import { 6 | getHeaderLevel, 7 | getNextNumber, 8 | isNeedUpdateNumber, 9 | isNeedInsertNumber, 10 | removeHeaderNumber, 11 | isHeader, 12 | } from "./core"; 13 | import { getAutoNumberingYaml, setAutoNumberingYaml } from "./utils"; 14 | import { 15 | HeaderEnhancerSettingTab, 16 | DEFAULT_SETTINGS, 17 | HeaderEnhancerSettings, 18 | } from "./setting"; 19 | import { getAutoNumberingConfig } from "./config"; 20 | 21 | export default class HeaderEnhancerPlugin extends Plugin { 22 | settings: HeaderEnhancerSettings; 23 | statusBarItemEl: HTMLElement; 24 | 25 | async onload() { 26 | await this.loadSettings(); 27 | 28 | // Creates an icon in the left ribbon. 29 | const ribbonIconEl = this.addRibbonIcon( 30 | "heading-glyph", 31 | "Header Enhancer", 32 | (evt: MouseEvent) => { 33 | const app = this.app; // this is the obsidian App instance 34 | const activeView = 35 | app.workspace.getActiveViewOfType(MarkdownView); 36 | if (!activeView) { 37 | new Notice( 38 | "No active MarkdownView, cannot toggle auto numbering." 39 | ); 40 | return; 41 | } 42 | // toggle header numbering on/off 43 | if (this.settings.isAutoNumbering) { 44 | this.settings.isAutoNumbering = false; 45 | new Notice("Auto numbering is off"); 46 | this.handleRemoveHeaderNumber(activeView); 47 | } else { 48 | // turn on auto-numbering 49 | this.settings.isAutoNumbering = true; 50 | new Notice("Auto numbering is on"); 51 | this.handleAddHeaderNumber(activeView); 52 | } 53 | this.handleShowStateBarChange(); 54 | } 55 | ); 56 | 57 | // This adds a status bar item to the bottom of the app. Does not work on mobile apps. 58 | this.statusBarItemEl = this.addStatusBarItem(); 59 | this.handleShowStateBarChange(); 60 | 61 | // register keymap 62 | this.registerEditorExtension( 63 | Prec.highest( 64 | keymap.of([ 65 | { 66 | key: "Enter", 67 | run: (view: EditorView): boolean => { 68 | const state = view.state; 69 | const pos = state.selection.main.to; 70 | const currentLine = state.doc.lineAt(pos); 71 | 72 | // 只有在标题行并且自动编号开启时才进行处理 73 | if (!isHeader(currentLine.text) || !this.settings.isAutoNumbering) { 74 | return false; // 不处理,让默认处理程序处理 75 | } 76 | 77 | // 执行自定义Enter处理 78 | return this.handlePressEnter(view); 79 | }, 80 | }, 81 | ]) 82 | ) 83 | ); 84 | 85 | this.registerEditorExtension( 86 | Prec.highest( 87 | keymap.of([ 88 | { 89 | key: "Backspace", 90 | run: (view: EditorView): boolean => { 91 | const state = view.state; 92 | const pos = state.selection.main.to; 93 | const currentLine = state.doc.lineAt(pos); 94 | 95 | // 只有在标题行时才进行处理 96 | if (!isHeader(currentLine.text)) { 97 | return false; // 不处理,让默认处理程序处理 98 | } 99 | 100 | return this.handlePressBackspace(view); 101 | }, 102 | }, 103 | ]) 104 | ) 105 | ); 106 | 107 | // This adds a command that can be triggered anywhere 108 | this.addCommand({ 109 | id: "toggle-auto-numbering", 110 | name: "toggle auto numbering", 111 | callback: () => { 112 | const app = this.app; // this is the obsidian App instance 113 | const activeView = 114 | app.workspace.getActiveViewOfType(MarkdownView); 115 | if (!activeView) { 116 | new Notice( 117 | "No active MarkdownView, cannot toggle auto numbering." 118 | ); 119 | return; 120 | } 121 | // toggle header numbering on/off 122 | if (this.settings.isAutoNumbering) { 123 | this.settings.isAutoNumbering = false; 124 | new Notice("Auto numbering is off"); 125 | this.handleRemoveHeaderNumber(activeView); 126 | } else { 127 | // turn on auto-numbering 128 | this.settings.isAutoNumbering = true; 129 | new Notice("Auto numbering is on"); 130 | this.handleAddHeaderNumber(activeView); 131 | } 132 | this.handleShowStateBarChange(); 133 | }, 134 | }); 135 | 136 | this.addCommand({ 137 | id: "add-auto-numbering-yaml", 138 | name: "add auto numbering yaml", 139 | callback: () => { 140 | app = this.app; 141 | const activeView = 142 | app.workspace.getActiveViewOfType(MarkdownView); 143 | if (!activeView) { 144 | new Notice( 145 | "No active MarkdownView, cannot add auto numbering yaml." 146 | ); 147 | return; 148 | } else { 149 | const editor = activeView.editor; 150 | const yaml = getAutoNumberingYaml(editor); 151 | if (yaml === "") { 152 | setAutoNumberingYaml(editor); 153 | } else { 154 | new Notice("auto numbering yaml already exists"); 155 | } 156 | } 157 | }, 158 | }); 159 | 160 | this.addCommand({ 161 | id: "reset-auto-numbering-yaml", 162 | name: "reset auto numbering yaml", 163 | callback: () => { 164 | app = this.app; 165 | const activeView = 166 | app.workspace.getActiveViewOfType(MarkdownView); 167 | if (!activeView) { 168 | new Notice( 169 | "No active MarkdownView, cannot reset auto numbering yaml." 170 | ); 171 | return; 172 | } else { 173 | const editor = activeView.editor; 174 | const yaml = getAutoNumberingYaml(editor); 175 | if (yaml === "") { 176 | new Notice("auto numbering yaml not exists"); 177 | } else { 178 | const value = [ 179 | "state on", 180 | "first-level h2", 181 | "max 1", 182 | "start-at 1", 183 | "separator .", 184 | ]; 185 | setAutoNumberingYaml(editor, value); 186 | } 187 | } 188 | }, 189 | }); 190 | 191 | this.addCommand({ 192 | id: "remove-auto-numbering-yaml", 193 | name: "remove auto numbering yaml", 194 | callback: () => { 195 | app = this.app; 196 | const activeView = 197 | app.workspace.getActiveViewOfType(MarkdownView); 198 | if (!activeView) { 199 | new Notice( 200 | "No active MarkdownView, cannot remove auto numbering yaml." 201 | ); 202 | return; 203 | } else { 204 | const editor = activeView.editor; 205 | const yaml = getAutoNumberingYaml(editor); 206 | if (yaml === "") { 207 | new Notice("auto numbering yaml not exists"); 208 | } else { 209 | setAutoNumberingYaml(editor, []); 210 | } 211 | } 212 | }, 213 | }); 214 | 215 | // This adds a settings tab so the user can configure various aspects of the plugin 216 | this.addSettingTab(new HeaderEnhancerSettingTab(this.app, this)); 217 | 218 | // When registering intervals, this function will automatically clear the interval when the plugin is disabled. 219 | this.registerInterval( 220 | window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000) 221 | ); 222 | } 223 | 224 | onunload() {} 225 | 226 | async loadSettings() { 227 | this.settings = Object.assign( 228 | {}, 229 | DEFAULT_SETTINGS, 230 | await this.loadData() 231 | ); 232 | } 233 | 234 | async saveSettings() { 235 | await this.saveData(this.settings); 236 | } 237 | 238 | handleShowStateBarChange() { 239 | if (this.settings.showOnStatusBar) { 240 | // This adds a status bar item to the bottom of the app. Does not work on mobile apps. 241 | const autoNumberingStatus = this.settings.isAutoNumbering 242 | ? "On" 243 | : "Off"; 244 | this.statusBarItemEl.setText( 245 | "Auto Numbering: " + autoNumberingStatus 246 | ); 247 | } else { 248 | this.statusBarItemEl.setText(""); 249 | } 250 | } 251 | 252 | handleAddHeaderNumber(view: MarkdownView): boolean { 253 | const editor = view.editor; 254 | const lineCount = editor.lineCount(); 255 | let docCharCount = 0; 256 | 257 | const config = getAutoNumberingConfig(this.settings, editor); 258 | 259 | if (!this.settings.isAutoNumbering) { 260 | return false; 261 | } 262 | 263 | if (config.state) { 264 | let insertNumber: number[] = [Number(config.startNumber) - 1]; 265 | let isCodeBlock: boolean = false; 266 | for (let i = 0; i <= lineCount; i++) { 267 | const line = editor.getLine(i); 268 | docCharCount += line.length; 269 | 270 | if (line.startsWith("```")) { 271 | isCodeBlock = !isCodeBlock; 272 | if (line.slice(3).contains("```")) { 273 | isCodeBlock = !isCodeBlock; 274 | } 275 | } 276 | 277 | if (isCodeBlock) { 278 | continue; 279 | } 280 | 281 | if (isHeader(line)) { 282 | const [headerLevel, realHeaderLevel] = getHeaderLevel( 283 | line, 284 | config.startLevel 285 | ); 286 | if (headerLevel <= 0) { 287 | continue; 288 | } 289 | insertNumber = getNextNumber(insertNumber, headerLevel); 290 | const insertNumberStr = insertNumber.join(config.separator); 291 | if ( 292 | isNeedInsertNumber( 293 | line, 294 | this.settings.autoNumberingHeaderSeparator 295 | ) 296 | ) { 297 | editor.setLine( 298 | i, 299 | "#".repeat(realHeaderLevel) + 300 | " " + 301 | insertNumberStr + 302 | this.settings.autoNumberingHeaderSeparator + 303 | line.substring(realHeaderLevel + 1) 304 | ); 305 | } else if ( 306 | isNeedUpdateNumber( 307 | insertNumberStr, 308 | line, 309 | this.settings.autoNumberingHeaderSeparator 310 | ) 311 | ) { 312 | const originNumberLength = line 313 | .split( 314 | this.settings.autoNumberingHeaderSeparator 315 | )[0] 316 | .split(" ")[1].length; 317 | editor.setLine( 318 | i, 319 | "#".repeat(realHeaderLevel) + 320 | " " + 321 | insertNumberStr + 322 | line.substring( 323 | realHeaderLevel + originNumberLength + 1 324 | ) 325 | ); 326 | } 327 | } 328 | } 329 | } 330 | return true; 331 | } 332 | 333 | handleRemoveHeaderNumber(view: MarkdownView): boolean { 334 | const editor = view.editor; 335 | const lineCount = editor.lineCount(); 336 | 337 | const config = getAutoNumberingConfig(this.settings, editor); 338 | 339 | if (!this.settings.isAutoNumbering) { 340 | for (let i = 0; i <= lineCount; i++) { 341 | const line = editor.getLine(i); 342 | if (isHeader(line)) { 343 | const [headerLevel, _] = getHeaderLevel( 344 | line, 345 | config.startLevel 346 | ); 347 | if (headerLevel <= 0) { 348 | continue; 349 | } 350 | editor.setLine( 351 | i, 352 | removeHeaderNumber( 353 | line, 354 | this.settings.autoNumberingHeaderSeparator 355 | ) 356 | ); 357 | } 358 | } 359 | } 360 | return true; 361 | } 362 | 363 | async handlePressEnter(view: EditorView): Promise { 364 | let state = view.state; 365 | let doc = state.doc; 366 | const pos = state.selection.main.to; 367 | 368 | const app = this.app; 369 | const activeView = app.workspace.getActiveViewOfType(MarkdownView); 370 | if (!activeView) { 371 | return false; // 让默认处理程序处理 372 | } 373 | 374 | // 获取当前行信息 375 | const currentLine = doc.lineAt(pos); 376 | 377 | // 注意:这个检查已经在外层run函数做过了,这里可以简化 378 | // 但保留这个检查作为额外的安全措施 379 | if (!isHeader(currentLine.text) || !this.settings.isAutoNumbering) { 380 | return false; 381 | } 382 | 383 | const editor = activeView.editor; 384 | const config = getAutoNumberingConfig(this.settings, editor); 385 | 386 | // 处理在标题中间按Enter的情况 387 | // 获取光标前后的文本 388 | const textBeforeCursor = currentLine.text.substring(0, pos - currentLine.from); 389 | const textAfterCursor = currentLine.text.substring(pos - currentLine.from); 390 | 391 | // 创建更改操作 - 直接替换整行,而不是分多次操作 392 | const changes = [{ 393 | from: currentLine.from, 394 | to: currentLine.to, 395 | insert: textBeforeCursor + "\n" + textAfterCursor 396 | }]; 397 | 398 | // 应用更改并设置光标位置 399 | view.dispatch({ 400 | changes, 401 | selection: { anchor: currentLine.from + textBeforeCursor.length + 1 }, 402 | userEvent: "HeaderEnhancer.changeAutoNumbering", 403 | }); 404 | 405 | // 在操作完成后更新标题编号 406 | if (config.state) { 407 | // 使用setTimeout确保编辑操作已完成 408 | setTimeout(() => { 409 | this.handleAddHeaderNumber(activeView); 410 | }, 10); 411 | } 412 | 413 | return true; 414 | } 415 | 416 | handlePressBackspace(view: EditorView): boolean { 417 | let state = view.state; 418 | let doc = state.doc; 419 | const pos = state.selection.main.to; 420 | // let posLine = doc.lineAt(pos) 421 | const lineCount = doc.lines; 422 | const changes = []; 423 | let docCharCount = 0; 424 | let insertCharCount = 0; 425 | let insertCharCountBeforePos = 0; // count of inserted chars, used to calculate the position of cursor 426 | 427 | if (!isHeader(doc.lineAt(pos).text)) { 428 | return false; 429 | } 430 | 431 | // instert a new line in current pos first 432 | changes.push({ 433 | from: pos - 1, 434 | to: pos, 435 | insert: "", 436 | }); 437 | 438 | if (this.settings.isAutoNumbering) { 439 | // some header may be deleted, so we need to recalculate the number 440 | // TODO: feature 441 | } 442 | 443 | view.dispatch({ 444 | changes, 445 | selection: { anchor: pos - 1 }, 446 | userEvent: "HeaderEnhancer.changeAutoNumbering", 447 | }); 448 | 449 | return true; 450 | } 451 | } 452 | -------------------------------------------------------------------------------- /src/setting.ts: -------------------------------------------------------------------------------- 1 | import { App, PluginSettingTab, Setting, Notice } from "obsidian"; 2 | import HeaderEnhancerPlugin from "./main"; 3 | import { I18n } from './i18n'; 4 | 5 | export interface HeaderEnhancerSettings { 6 | language: string; 7 | showOnStatusBar: boolean; 8 | isAutoDetectHeaderLevel: boolean; 9 | startHeaderLevel: number; 10 | maxHeaderLevel: number; 11 | isAutoNumbering: boolean; 12 | isUseYaml: boolean; 13 | autoNumberingStartNumber: string; 14 | autoNumberingSeparator: string; 15 | autoNumberingHeaderSeparator: string; 16 | isSeparateTitleFont: boolean; 17 | titleFontFamily: string; 18 | titleFontSize: string; 19 | } 20 | 21 | export const DEFAULT_SETTINGS: HeaderEnhancerSettings = { 22 | language: "en", 23 | showOnStatusBar: true, 24 | isAutoDetectHeaderLevel: false, // TODO: auto detect header level is not available now 25 | startHeaderLevel: 1, 26 | maxHeaderLevel: 6, 27 | isAutoNumbering: true, 28 | isUseYaml: false, 29 | autoNumberingStartNumber: "1", 30 | autoNumberingSeparator: ".", 31 | autoNumberingHeaderSeparator: "\t", 32 | isSeparateTitleFont: true, 33 | titleFontFamily: "inherit", 34 | titleFontSize: "inherit", 35 | }; 36 | 37 | export class HeaderEnhancerSettingTab extends PluginSettingTab { 38 | plugin: HeaderEnhancerPlugin; 39 | 40 | constructor(app: App, plugin: HeaderEnhancerPlugin) { 41 | super(app, plugin); 42 | this.plugin = plugin; 43 | } 44 | 45 | display(): void { 46 | const { containerEl } = this; 47 | const i18n = I18n.getInstance(); 48 | 49 | containerEl.empty(); 50 | 51 | containerEl.createEl("h1", { text: i18n.t("settings.title") }); 52 | 53 | containerEl.createEl("h2", { text: i18n.t("settings.general") }); 54 | new Setting(containerEl) 55 | .setName(i18n.t("settings.language.name")) 56 | .setDesc(i18n.t("settings.language.desc")) 57 | .addDropdown((dropdown) => { 58 | dropdown.addOption("en", "English"); 59 | dropdown.addOption("zh", "中文"); 60 | dropdown.setValue(this.plugin.settings.language); 61 | dropdown.onChange(async (value) => { 62 | this.plugin.settings.language = value; 63 | i18n.setLanguage(value); 64 | await this.plugin.saveSettings(); 65 | this.display(); // Refresh the settings page 66 | }); 67 | }); 68 | new Setting(containerEl) 69 | .setName(i18n.t("settings.statusBar.name")) 70 | .setDesc(i18n.t("settings.statusBar.desc")) 71 | .addToggle((toggle) => { 72 | toggle 73 | .setValue(this.plugin.settings.showOnStatusBar) 74 | .onChange(async (value) => { 75 | this.plugin.settings.showOnStatusBar = value; 76 | await this.plugin.saveSettings(); 77 | this.plugin.handleShowStateBarChange(); 78 | }); 79 | }); 80 | 81 | containerEl.createEl("h2", { text: i18n.t("settings.autoNumbering.title") }); 82 | new Setting(containerEl) 83 | .setName(i18n.t("settings.autoNumbering.enable.name")) 84 | .setDesc(i18n.t("settings.autoNumbering.enable.desc")) 85 | .setDisabled(true) 86 | .addToggle((toggle) => { 87 | toggle 88 | .setValue(this.plugin.settings.isAutoNumbering) 89 | .onChange(async (value) => { 90 | new Notice( 91 | i18n.t("settings.autoNumbering.enable.notice") 92 | ); 93 | }); 94 | }); 95 | new Setting(containerEl) 96 | .setName(i18n.t("settings.autoNumbering.useYaml.name")) 97 | .setDesc(i18n.t("settings.autoNumbering.useYaml.desc")) 98 | .addToggle((toggle) => { 99 | toggle 100 | .setValue(this.plugin.settings.isUseYaml) 101 | .onChange(async (value) => { 102 | this.plugin.settings.isUseYaml = value; 103 | await this.plugin.saveSettings(); 104 | this.plugin.handleShowStateBarChange(); 105 | }); 106 | }); 107 | new Setting(containerEl) 108 | .setName(i18n.t("settings.autoNumbering.headerLevel.name")) 109 | .setDesc(i18n.t("settings.autoNumbering.headerLevel.desc")) 110 | .addToggle((toggle) => { 111 | toggle.setValue(this.plugin.settings.isAutoDetectHeaderLevel) 112 | .onChange(async (value) => { 113 | this.plugin.settings.isAutoDetectHeaderLevel = value; 114 | await this.plugin.saveSettings(); 115 | this.display(); 116 | }) 117 | .setDisabled(true); 118 | }) 119 | .addDropdown((dropdown) => { 120 | dropdown.addOption("1", "H1"); 121 | dropdown.addOption("2", "H2"); 122 | dropdown.addOption("3", "H3"); 123 | dropdown.addOption("4", "H4"); 124 | dropdown.addOption("5", "H5"); 125 | dropdown.addOption("6", "H6"); 126 | dropdown.setValue( 127 | this.plugin.settings.startHeaderLevel.toString() 128 | ); 129 | dropdown.setDisabled(this.plugin.settings.isAutoDetectHeaderLevel); 130 | dropdown.onChange(async (value) => { 131 | this.plugin.settings.startHeaderLevel = parseInt(value, 10); 132 | await this.plugin.saveSettings(); 133 | this.display(); 134 | }); 135 | }) 136 | .addDropdown((dropdown) => { 137 | dropdown.addOption("1", "H1"); 138 | dropdown.addOption("2", "H2"); 139 | dropdown.addOption("3", "H3"); 140 | dropdown.addOption("4", "H4"); 141 | dropdown.addOption("5", "H5"); 142 | dropdown.addOption("6", "H6"); 143 | dropdown.setValue( 144 | this.plugin.settings.maxHeaderLevel.toString() 145 | ); 146 | dropdown.setDisabled(this.plugin.settings.isAutoDetectHeaderLevel); 147 | dropdown.onChange(async (value) => { 148 | if (this.checkMaxLevel(parseInt(value, 10))) { 149 | this.plugin.settings.maxHeaderLevel = parseInt( 150 | value, 151 | 10 152 | ); 153 | await this.plugin.saveSettings(); 154 | this.display(); 155 | } else { 156 | new Notice( 157 | "Max header level should be greater than or equal to start header level" 158 | ); 159 | } 160 | }); 161 | }); 162 | new Setting(containerEl) 163 | .setName(i18n.t("settings.autoNumbering.startNumber.name")) 164 | .setDesc(i18n.t("settings.autoNumbering.startNumber.desc")) 165 | .addText((text) => 166 | text 167 | .setPlaceholder(i18n.t("settings.autoNumbering.startNumber.placeholder")) 168 | .setValue(this.plugin.settings.autoNumberingStartNumber) 169 | .onChange(async (value) => { 170 | if (this.checkStartNumber(value)) { 171 | this.plugin.settings.autoNumberingStartNumber = value; 172 | await this.plugin.saveSettings(); 173 | this.display(); 174 | } 175 | }) 176 | ); 177 | new Setting(containerEl) 178 | .setName(i18n.t("settings.autoNumbering.separator.name")) 179 | .setDesc(i18n.t("settings.autoNumbering.separator.desc")) 180 | .addText((text) => 181 | text 182 | .setPlaceholder(i18n.t("settings.autoNumbering.separator.placeholder")) 183 | .setValue(this.plugin.settings.autoNumberingSeparator) 184 | .onChange(async (value) => { 185 | if (this.checkSeparator(value)) { 186 | this.plugin.settings.autoNumberingSeparator = value; 187 | await this.plugin.saveSettings(); 188 | this.display(); 189 | } 190 | }) 191 | ); 192 | new Setting(containerEl) 193 | .setName(i18n.t("settings.autoNumbering.headerSeparator.name")) 194 | .setDesc(i18n.t("settings.autoNumbering.headerSeparator.desc")) 195 | .addDropdown((dropdown) => { 196 | dropdown.addOption("\t", "Tab"); 197 | dropdown.addOption(" ", "Space"); 198 | dropdown.setValue( 199 | this.plugin.settings.autoNumberingHeaderSeparator 200 | ); 201 | dropdown.onChange(async (value) => { 202 | if (this.checkHeaderSeparator(value)) { 203 | this.plugin.settings.autoNumberingHeaderSeparator = 204 | value; 205 | await this.plugin.saveSettings(); 206 | } else { 207 | new Notice(i18n.t("settings.autoNumbering.headerSeparator.error")); 208 | } 209 | }); 210 | }); 211 | new Setting(containerEl).setName( 212 | i18n.t("settings.autoNumbering.format.name") + 213 | ": \t" + 214 | this.plugin.settings.autoNumberingStartNumber + 215 | this.plugin.settings.autoNumberingSeparator + 216 | "1" + 217 | this.plugin.settings.autoNumberingSeparator + 218 | "1" + 219 | "\t" + i18n.t("settings.autoNumbering.format.fromLevel") + " " + 220 | this.plugin.settings.startHeaderLevel + 221 | " " + i18n.t("settings.autoNumbering.format.toLevel") + " " + 222 | this.plugin.settings.maxHeaderLevel + 223 | " " + 224 | (this.plugin.settings.isAutoDetectHeaderLevel 225 | ? i18n.t("settings.autoNumbering.format.autoDetect") 226 | : i18n.t("settings.autoNumbering.format.manual")) 227 | ); 228 | 229 | containerEl.createEl("h2", { text: i18n.t("settings.font.title") }); 230 | new Setting(containerEl) 231 | .setName(i18n.t("settings.font.separate.name")) 232 | .setDesc(i18n.t("settings.font.separate.desc")) 233 | .addToggle((toggle) => { 234 | toggle 235 | .setValue(this.plugin.settings.isSeparateTitleFont) 236 | .onChange(async (value) => { 237 | new Notice(i18n.t("settings.font.separate.notice")); 238 | }); 239 | }); 240 | new Setting(containerEl) 241 | .setName(i18n.t("settings.font.family.name")) 242 | .setDesc(i18n.t("settings.font.family.desc")) 243 | .addText((text) => 244 | text 245 | .setPlaceholder(i18n.t("settings.font.family.placeholder")) 246 | .setValue(this.plugin.settings.titleFontFamily) 247 | .onChange(async (value) => { 248 | this.plugin.settings.titleFontFamily = value; 249 | await this.plugin.saveSettings(); 250 | }) 251 | ); 252 | new Setting(containerEl) 253 | .setName(i18n.t("settings.font.size.name")) 254 | .setDesc(i18n.t("settings.font.size.desc")) 255 | .addText((text) => 256 | text 257 | .setPlaceholder(i18n.t("settings.font.size.placeholder")) 258 | .setValue(this.plugin.settings.titleFontSize) 259 | .onChange(async (value) => { 260 | this.plugin.settings.titleFontSize = value; 261 | await this.plugin.saveSettings(); 262 | }) 263 | ); 264 | new Setting(containerEl) 265 | .addButton((button) => { 266 | button.setButtonText(i18n.t("settings.resetSettings.name")).onClick(async () => { 267 | if ( 268 | confirm( 269 | i18n.t("settings.resetSettings.confirm") 270 | ) 271 | ) { 272 | this.plugin.settings = DEFAULT_SETTINGS; 273 | await this.plugin.saveSettings(); 274 | this.display(); 275 | } 276 | }); 277 | }); 278 | 279 | containerEl.createEl("h2", { text: i18n.t("settings.moreInfo") }); 280 | containerEl.createEl("p", { text: i18n.t("settings.author") }).createEl("a", { 281 | text: "Hobee Liu", 282 | href: "https://github.com/HoBeedzc", 283 | }); 284 | containerEl.createEl("p", { text: i18n.t("settings.license") }).createEl("a", { 285 | text: "MIT", 286 | href: "https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/blob/master/LICENSE", 287 | }); 288 | containerEl.createEl("p", { text: i18n.t("settings.githubRepo") }).createEl("a", { 289 | text: "obsidian-header-enhancer", 290 | href: "https://github.com/HoBeedzc/obsidian-header-enhancer-plugin", 291 | }); 292 | containerEl 293 | .createEl("p", { text: i18n.t("settings.anyQuestion") }) 294 | .createEl("a", { 295 | text: "Github Issues", 296 | href: "https://github.com/HoBeedzc/obsidian-header-enhancer-plugin/issues", 297 | }); 298 | } 299 | 300 | checkMaxLevel(maxLevel: number): boolean { 301 | return this.plugin.settings.startHeaderLevel <= maxLevel; 302 | } 303 | 304 | checkStartNumber(startNumber: string): boolean { 305 | const reg = /^[0-9]*$/; 306 | return reg.test(startNumber); 307 | } 308 | 309 | checkSeparator(separator: string): boolean { 310 | if (separator.length != 1) { 311 | return false; 312 | } 313 | const separators = [".", ",", "-", "/"]; 314 | return separators.includes(separator); 315 | } 316 | 317 | checkHeaderSeparator(separator: string): boolean { 318 | if (this.plugin.settings.isAutoNumbering) { 319 | return false; 320 | } 321 | return true; 322 | } 323 | } 324 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | // reference https://github.com/lijyze/obsidian-state-switcher/blob/main/src/util.ts 2 | import { Editor, EditorPosition, parseYaml, stringifyYaml } from "obsidian"; 3 | 4 | const YAML_REGEX = /^---\n(?:((?:.|\n)*?)\n)?---(?=\n|$)/; 5 | const DEFAULT_YAML_SETTING = [ 6 | "state on", 7 | "start-level h2", 8 | "max-level h1", 9 | "start-number 1", 10 | "separator .", 11 | ]; 12 | 13 | // Get yaml section 14 | function getYaml(editor: Editor): string { 15 | const matchResult = editor.getValue().match(YAML_REGEX); 16 | 17 | return matchResult?.[0] ?? ""; 18 | } 19 | 20 | export function getAutoNumberingYaml(editor: Editor): string { 21 | const yaml = getYaml(editor); 22 | const parsedYaml = parseYaml(yaml.slice(4, -4)); 23 | 24 | return parsedYaml?.["header-auto-numbering"] ?? ""; 25 | } 26 | 27 | export function setAutoNumberingYaml( 28 | editor: Editor, 29 | value: string[] = DEFAULT_YAML_SETTING 30 | ): void { 31 | const yaml = getYaml(editor); 32 | const parsedYaml = parseYaml(yaml.slice(4, -4)); 33 | 34 | if (parsedYaml) { 35 | parsedYaml["header-auto-numbering"] = value; 36 | } 37 | 38 | const newContent = `---\n${stringifyYaml(parsedYaml)}---`; 39 | const startPosition: EditorPosition = { line: 0, ch: 0 }; 40 | const endPosition: EditorPosition = editor.offsetToPos(yaml.length); 41 | editor.replaceRange(newContent, startPosition, endPosition); 42 | } 43 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This CSS file will be included with your plugin, and 4 | available in the app when your plugin is enabled. 5 | 6 | If your plugin does not need CSS, delete this file. 7 | 8 | */ -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "module": "ESNext", 7 | "target": "ES6", 8 | "allowJs": true, 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "importHelpers": true, 12 | "isolatedModules": true, 13 | "strictNullChecks": true, 14 | "lib": [ 15 | "DOM", 16 | "ES5", 17 | "ES6", 18 | "ES7" 19 | ] 20 | }, 21 | "include": [ 22 | "**/*.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /version-bump.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from "fs"; 2 | 3 | const targetVersion = process.env.npm_package_version; 4 | 5 | // read minAppVersion from manifest.json and bump version to target version 6 | let manifest = JSON.parse(readFileSync("manifest.json", "utf8")); 7 | const { minAppVersion } = manifest; 8 | manifest.version = targetVersion; 9 | writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); 10 | 11 | // update versions.json with target version and minAppVersion from manifest.json 12 | let versions = JSON.parse(readFileSync("versions.json", "utf8")); 13 | versions[targetVersion] = minAppVersion; 14 | writeFileSync("versions.json", JSON.stringify(versions, null, "\t")); 15 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.0": "0.15.0" 3 | } 4 | --------------------------------------------------------------------------------