├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ └── release.yml ├── .gitignore ├── .npmrc ├── README.md ├── assets └── Fold-Anywhere.gif ├── esbuild.config.mjs ├── manifest.json ├── package.json ├── pnpm-lock.yaml ├── src ├── foldAnyWhereIndex.ts ├── types │ └── obsidian.d.ts ├── typings │ └── lodash.d.ts ├── utils │ └── line.ts └── widgets │ ├── foldMarkerWidget.ts │ └── foldService.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 | npm node_modules 2 | build -------------------------------------------------------------------------------- /.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/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: [ "bug" ] 5 | body: 6 | - type: textarea 7 | id: bug-description 8 | attributes: 9 | label: Bug Description 10 | description: A clear and concise description of the bug. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: screenshot 15 | attributes: 16 | label: Relevant Screenshot 17 | description: If applicable, add screenshots or a screen recording to help explain your problem. 18 | - type: textarea 19 | id: reproduction-steps 20 | attributes: 21 | label: To Reproduce 22 | description: Steps to reproduce the problem 23 | placeholder: | 24 | For example: 25 | 1. Go to '...' 26 | 2. Click on '...' 27 | 3. Scroll down to '...' 28 | - type: input 29 | id: obsi-version 30 | attributes: 31 | label: Obsidian Version 32 | description: You can find the version in the *About* Tab of the settings. 33 | placeholder: 0.13.19 34 | validations: 35 | required: true 36 | - type: checkboxes 37 | id: checklist 38 | attributes: 39 | label: Checklist 40 | options: 41 | - label: I updated to the latest version of the plugin. 42 | required: true 43 | 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea 3 | title: "Feature Request: " 4 | labels: [ "feature request" ] 5 | body: 6 | - type: textarea 7 | id: feature-requested 8 | attributes: 9 | label: Feature Requested 10 | description: A clear and concise description of the feature. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: screenshot 15 | attributes: 16 | label: Relevant Screenshot 17 | description: If applicable, add screenshots or a screen recording to help explain the request. 18 | - type: checkboxes 19 | id: checklist 20 | attributes: 21 | label: Checklist 22 | options: 23 | - label: The feature would be useful to more users than just me. 24 | required: true 25 | 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Obsidian plugin 2 | 3 | on: 4 | release: 5 | types: [ created ] 6 | 7 | env: 8 | PLUGIN_NAME: obsidian-fold-anywhere 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Use Node.js 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: 16 19 | - name: Build 20 | id: build 21 | run: | 22 | npm install 23 | npm run build 24 | mkdir ${{ env.PLUGIN_NAME }} 25 | cp main.js manifest.json styles.css ${{ env.PLUGIN_NAME }} 26 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} 27 | ls 28 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" 29 | - name: Upload zip file 30 | id: upload-zip 31 | uses: actions/upload-release-asset@v1 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | with: 35 | upload_url: ${{ github.event.release.upload_url }} 36 | asset_path: ./${{ env.PLUGIN_NAME }}.zip 37 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip 38 | asset_content_type: application/zip 39 | 40 | - name: Upload main.js 41 | id: upload-main 42 | uses: actions/upload-release-asset@v1 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | with: 46 | upload_url: ${{ github.event.release.upload_url }} 47 | asset_path: ./main.js 48 | asset_name: main.js 49 | asset_content_type: text/javascript 50 | 51 | - name: Upload manifest.json 52 | id: upload-manifest 53 | uses: actions/upload-release-asset@v1 54 | env: 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | with: 57 | upload_url: ${{ github.event.release.upload_url }} 58 | asset_path: ./manifest.json 59 | asset_name: manifest.json 60 | asset_content_type: application/json 61 | 62 | - name: Upload styles.css 63 | id: upload-css 64 | uses: actions/upload-release-asset@v1 65 | env: 66 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 67 | with: 68 | upload_url: ${{ github.event.release.upload_url }} 69 | asset_path: ./styles.css 70 | asset_name: styles.css 71 | asset_content_type: text/css 72 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian Fold Anywhere 2 | 3 | A plugin for [Obsidian](https://obsidian.md) that allows you to fold any text anywhere. 4 | 5 | ![Fold-AnyWhere](./assets/Fold-Anywhere.gif) 6 | 7 | ## Usage 8 | 9 | - Commands 10 | - `Fold Anywhere: Fold Between Start and End Marks` - Fold the selected text 11 | - `Fold Anywhere: Unfold Between Start and End Marks` - Unfold the selected text 12 | - `Fold Anywhere: Mark as Start` - Mark the current pos as the start of a fold 13 | - `Fold Anywhere: Mark as End` - Mark the current pos as the end of a fold 14 | - `Fold Anywhere: Fold Selected Text` - Fold the selected text 15 | - `Fold Anywhere: Remove All Marks` - Remove all marks 16 | - Context menu in editor 17 | - `Fold Selected Text` - Fold the selected text 18 | - `Mark as Start` - Mark the current pos as the start of a fold 19 | - `Mark as End` - Mark the current pos as the end of a fold 20 | - Mouse 21 | - `Click` - Fold the selected text 22 | - `Ctrl + Click` - Remove selected mark 23 | 24 | ## Installation 25 | 26 | - Not ready for market yet 27 | - Can be installed via the [Brat](https://github.com/TfTHacker/obsidian42-brat) plugin 28 | - Manual installation 29 | 30 | 1. Find the release page on this github page and click 31 | 2. Download the latest release zip file 32 | 3. Unzip it, copy the unzipped folder to the obsidian plugin folder, make sure there are main.js and manifest.json files 33 | in the folder 34 | 4. Restart obsidian (do not restart also, you have to refresh plugin list), in the settings interface to enable the 35 | plugin 36 | 5. Done! 37 | 38 | ## Support 39 | 40 | If you are enjoying this plugin then please support my work and enthusiasm by buying me a coffee 41 | on [https://www.buymeacoffee.com/boninall](https://www.buymeacoffee.com/boninall). 42 | . 43 | 44 | 45 | -------------------------------------------------------------------------------- /assets/Fold-Anywhere.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quorafind/Obsidian-Fold-Anywhere/fb071f62fc5b8054a2b13c4b8faf71a133237591/assets/Fold-Anywhere.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 | esbuild.build({ 15 | banner: { 16 | js: banner, 17 | }, 18 | entryPoints: ['src/foldAnyWhereIndex.ts'], 19 | bundle: true, 20 | external: [ 21 | "obsidian", 22 | "electron", 23 | "codemirror", 24 | "@codemirror/closebrackets", 25 | "@codemirror/commands", 26 | "@codemirror/fold", 27 | "@codemirror/gutter", 28 | "@codemirror/history", 29 | "@codemirror/language", 30 | "@codemirror/rangeset", 31 | "@codemirror/rectangular-selection", 32 | "@codemirror/search", 33 | "@codemirror/state", 34 | "@codemirror/stream-parser", 35 | "@codemirror/text", 36 | "@codemirror/view", 37 | '@lezer/common', 38 | '@lezer/highlight', 39 | '@lezer/lr', 40 | ...builtins], 41 | format: 'cjs', 42 | watch: !prod, 43 | target: 'es2018', 44 | logLevel: "info", 45 | sourcemap: prod ? false : 'inline', 46 | treeShaking: true, 47 | outfile: 'main.js', 48 | }).catch(() => process.exit(1)); 49 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fold-anywhere", 3 | "name": "Fold Anywhere", 4 | "version": "2.1.1", 5 | "minAppVersion": "0.15.0", 6 | "description": "Set start and end marker, and then fold any text anywhere.", 7 | "author": "Boninall", 8 | "authorUrl": "https://github.com/Quorafind", 9 | "fundingUrl": { 10 | "Buy Me a Coffee": "https://www.buymeacoffee.com/boninall", 11 | "爱发电": "https://afdian.net/a/boninall", 12 | "支付宝": "https://cdn.jsdelivr.net/gh/Quorafind/.github@main/IMAGE/%E6%94%AF%E4%BB%98%E5%AE%9D%E4%BB%98%E6%AC%BE%E7%A0%81.jpg" 13 | }, 14 | "isDesktopOnly": false 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fold-anywhere", 3 | "version": "2.1.1", 4 | "description": "Set start and end marker, and then fold any text anywhere", 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 | "author": "", 13 | "license": "MIT", 14 | "peerDependencies": { 15 | "@codemirror/language": "0.19.x", 16 | "@codemirror/rangeset": "0.19.x", 17 | "@codemirror/view": "0.19.x" 18 | }, 19 | "devDependencies": { 20 | "@codemirror/basic-setup": "^0.20.0", 21 | "@codemirror/buildhelper": "^1.0.0", 22 | "@codemirror/fold": "^0.19.4", 23 | "@codemirror/lang-css": "^6.2.0", 24 | "@codemirror/language": "^6.8.0", 25 | "@codemirror/rangeset": "^0.19.9", 26 | "@codemirror/state": "^6.2.1", 27 | "@codemirror/view": "^6.15.0", 28 | "@typescript-eslint/eslint-plugin": "5.13.0", 29 | "@typescript-eslint/parser": "5.13.0", 30 | "builtin-modules": "3.3.0", 31 | "esbuild": "0.14.47", 32 | "obsidian": "^1.8.7", 33 | "tslib": "2.4.0", 34 | "typescript": "4.7.4" 35 | }, 36 | "dependencies": { 37 | "lodash": "^4.17.21", 38 | "monkey-around": "^3.0.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | lodash: 12 | specifier: ^4.17.21 13 | version: 4.17.21 14 | monkey-around: 15 | specifier: ^3.0.0 16 | version: 3.0.0 17 | devDependencies: 18 | '@codemirror/basic-setup': 19 | specifier: ^0.20.0 20 | version: 0.20.0 21 | '@codemirror/buildhelper': 22 | specifier: ^1.0.0 23 | version: 1.0.0 24 | '@codemirror/fold': 25 | specifier: ^0.19.4 26 | version: 0.19.4 27 | '@codemirror/lang-css': 28 | specifier: ^6.2.0 29 | version: 6.2.0(@codemirror/view@6.15.0) 30 | '@codemirror/language': 31 | specifier: ^6.8.0 32 | version: 6.8.0 33 | '@codemirror/rangeset': 34 | specifier: ^0.19.9 35 | version: 0.19.9 36 | '@codemirror/state': 37 | specifier: ^6.2.1 38 | version: 6.2.1 39 | '@codemirror/view': 40 | specifier: ^6.15.0 41 | version: 6.15.0 42 | '@typescript-eslint/eslint-plugin': 43 | specifier: 5.13.0 44 | version: 5.13.0(@typescript-eslint/parser@5.13.0(eslint@8.46.0)(typescript@4.7.4))(eslint@8.46.0)(typescript@4.7.4) 45 | '@typescript-eslint/parser': 46 | specifier: 5.13.0 47 | version: 5.13.0(eslint@8.46.0)(typescript@4.7.4) 48 | builtin-modules: 49 | specifier: 3.3.0 50 | version: 3.3.0 51 | esbuild: 52 | specifier: 0.14.47 53 | version: 0.14.47 54 | obsidian: 55 | specifier: ^1.8.7 56 | version: 1.8.7(@codemirror/state@6.2.1)(@codemirror/view@6.15.0) 57 | tslib: 58 | specifier: 2.4.0 59 | version: 2.4.0 60 | typescript: 61 | specifier: 4.7.4 62 | version: 4.7.4 63 | 64 | packages: 65 | 66 | '@aashutoshrathi/word-wrap@1.2.6': 67 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} 68 | engines: {node: '>=0.10.0'} 69 | 70 | '@babel/code-frame@7.22.5': 71 | resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} 72 | engines: {node: '>=6.9.0'} 73 | 74 | '@babel/helper-validator-identifier@7.22.5': 75 | resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} 76 | engines: {node: '>=6.9.0'} 77 | 78 | '@babel/highlight@7.22.5': 79 | resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} 80 | engines: {node: '>=6.9.0'} 81 | 82 | '@codemirror/autocomplete@0.20.3': 83 | resolution: {integrity: sha512-lYB+NPGP+LEzAudkWhLfMxhTrxtLILGl938w+RcFrGdrIc54A+UgmCoz+McE3IYRFp4xyQcL4uFJwo+93YdgHw==} 84 | 85 | '@codemirror/autocomplete@6.9.0': 86 | resolution: {integrity: sha512-Fbwm0V/Wn3BkEJZRhr0hi5BhCo5a7eBL6LYaliPjOSwCyfOpnjXY59HruSxOUNV+1OYer0Tgx1zRNQttjXyDog==} 87 | peerDependencies: 88 | '@codemirror/language': ^6.0.0 89 | '@codemirror/state': ^6.0.0 90 | '@codemirror/view': ^6.0.0 91 | '@lezer/common': ^1.0.0 92 | 93 | '@codemirror/basic-setup@0.20.0': 94 | resolution: {integrity: sha512-W/ERKMLErWkrVLyP5I8Yh8PXl4r+WFNkdYVSzkXYPQv2RMPSkWpr2BgggiSJ8AHF/q3GuApncDD8I4BZz65fyg==} 95 | deprecated: In version 6.0, this package has been renamed to just 'codemirror' 96 | 97 | '@codemirror/buildhelper@1.0.0': 98 | resolution: {integrity: sha512-tjVnizCUsDJHWZFNjQWBl4DAZrfLGSUmFEvjMkfom4eK5zyByiCITfrNHZOYZgi4xMWk2qJHS6LBWCq0IBWtmQ==} 99 | hasBin: true 100 | 101 | '@codemirror/commands@0.20.0': 102 | resolution: {integrity: sha512-v9L5NNVA+A9R6zaFvaTbxs30kc69F6BkOoiEbeFw4m4I0exmDEKBILN6mK+GksJtvTzGBxvhAPlVFTdQW8GB7Q==} 103 | 104 | '@codemirror/fold@0.19.4': 105 | resolution: {integrity: sha512-0SNSkRSOa6gymD6GauHa3sxiysjPhUC0SRVyTlvL52o0gz9GHdc8kNqNQskm3fBtGGOiSriGwF/kAsajRiGhVw==} 106 | deprecated: As of 0.20.0, this package has been merged into @codemirror/language 107 | 108 | '@codemirror/gutter@0.19.9': 109 | resolution: {integrity: sha512-PFrtmilahin1g6uL27aG5tM/rqR9DZzZYZsIrCXA5Uc2OFTFqx4owuhoU9hqfYxHp5ovfvBwQ+txFzqS4vog6Q==} 110 | deprecated: As of 0.20.0, this package has been merged into @codemirror/view 111 | 112 | '@codemirror/lang-css@6.2.0': 113 | resolution: {integrity: sha512-oyIdJM29AyRPM3+PPq1I2oIk8NpUfEN3kAM05XWDDs6o3gSneIKaVJifT2P+fqONLou2uIgXynFyMUDQvo/szA==} 114 | 115 | '@codemirror/language@0.19.10': 116 | resolution: {integrity: sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==} 117 | 118 | '@codemirror/language@0.20.2': 119 | resolution: {integrity: sha512-WB3Bnuusw0xhVvhBocieYKwJm04SOk5bPoOEYksVHKHcGHFOaYaw+eZVxR4gIqMMcGzOIUil0FsCmFk8yrhHpw==} 120 | 121 | '@codemirror/language@6.8.0': 122 | resolution: {integrity: sha512-r1paAyWOZkfY0RaYEZj3Kul+MiQTEbDvYqf8gPGaRvNneHXCmfSaAVFjwRUPlgxS8yflMxw2CTu6uCMp8R8A2g==} 123 | 124 | '@codemirror/lint@0.20.3': 125 | resolution: {integrity: sha512-06xUScbbspZ8mKoODQCEx6hz1bjaq9m8W8DxdycWARMiiX1wMtfCh/MoHpaL7ws/KUMwlsFFfp2qhm32oaCvVA==} 126 | 127 | '@codemirror/rangeset@0.19.9': 128 | resolution: {integrity: sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==} 129 | deprecated: As of 0.20.0, this package has been merged into @codemirror/state 130 | 131 | '@codemirror/search@0.20.1': 132 | resolution: {integrity: sha512-ROe6gRboQU5E4z6GAkNa2kxhXqsGNbeLEisbvzbOeB7nuDYXUZ70vGIgmqPu0tB+1M3F9yWk6W8k2vrFpJaD4Q==} 133 | 134 | '@codemirror/state@0.19.9': 135 | resolution: {integrity: sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==} 136 | 137 | '@codemirror/state@0.20.1': 138 | resolution: {integrity: sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ==} 139 | 140 | '@codemirror/state@6.2.1': 141 | resolution: {integrity: sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==} 142 | 143 | '@codemirror/text@0.19.6': 144 | resolution: {integrity: sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==} 145 | deprecated: As of 0.20.0, this package has been merged into @codemirror/state 146 | 147 | '@codemirror/view@0.19.48': 148 | resolution: {integrity: sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==} 149 | 150 | '@codemirror/view@0.20.7': 151 | resolution: {integrity: sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ==} 152 | 153 | '@codemirror/view@6.15.0': 154 | resolution: {integrity: sha512-3hPeBoD4+pUpzezhKSoARQyFjUP8g4zoI5AIy72+jKqWkE6fp0KV3H/dyTxNfig4jyW7x7ypp060/etvv/4yuA==} 155 | 156 | '@eslint-community/eslint-utils@4.4.0': 157 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 158 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 159 | peerDependencies: 160 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 161 | 162 | '@eslint-community/regexpp@4.6.2': 163 | resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} 164 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 165 | 166 | '@eslint/eslintrc@2.1.1': 167 | resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} 168 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 169 | 170 | '@eslint/js@8.46.0': 171 | resolution: {integrity: sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==} 172 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 173 | 174 | '@humanwhocodes/config-array@0.11.10': 175 | resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} 176 | engines: {node: '>=10.10.0'} 177 | deprecated: Use @eslint/config-array instead 178 | 179 | '@humanwhocodes/module-importer@1.0.1': 180 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 181 | engines: {node: '>=12.22'} 182 | 183 | '@humanwhocodes/object-schema@1.2.1': 184 | resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} 185 | deprecated: Use @eslint/object-schema instead 186 | 187 | '@lezer/common@0.15.12': 188 | resolution: {integrity: sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==} 189 | 190 | '@lezer/common@0.16.1': 191 | resolution: {integrity: sha512-qPmG7YTZ6lATyTOAWf8vXE+iRrt1NJd4cm2nJHK+v7X9TsOF6+HtuU/ctaZy2RCrluxDb89hI6KWQ5LfQGQWuA==} 192 | 193 | '@lezer/common@1.0.3': 194 | resolution: {integrity: sha512-JH4wAXCgUOcCGNekQPLhVeUtIqjH0yPBs7vvUdSjyQama9618IOKFJwkv2kcqdhF0my8hQEgCTEJU0GIgnahvA==} 195 | 196 | '@lezer/css@1.1.3': 197 | resolution: {integrity: sha512-SjSM4pkQnQdJDVc80LYzEaMiNy9txsFbI7HsMgeVF28NdLaAdHNtQ+kB/QqDUzRBV/75NTXjJ/R5IdC8QQGxMg==} 198 | 199 | '@lezer/generator@1.3.0': 200 | resolution: {integrity: sha512-7HfulDoOMOkskb97fnwgpC6StwPVSob4ptc0iuOH72rapNQBbp6lVj05y7vc5IM0E9pjFjiLmNQeiBiSbLpCtA==} 201 | hasBin: true 202 | 203 | '@lezer/highlight@0.16.0': 204 | resolution: {integrity: sha512-iE5f4flHlJ1g1clOStvXNLbORJoiW4Kytso6ubfYzHnaNo/eo5SKhxs4wv/rtvwZQeZrK3we8S9SyA7OGOoRKQ==} 205 | 206 | '@lezer/highlight@1.1.6': 207 | resolution: {integrity: sha512-cmSJYa2us+r3SePpRCjN5ymCqCPv+zyXmDl0ciWtVaNiORT/MxM7ZgOMQZADD0o51qOaOg24qc/zBViOIwAjJg==} 208 | 209 | '@lezer/lr@0.15.8': 210 | resolution: {integrity: sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==} 211 | 212 | '@lezer/lr@0.16.3': 213 | resolution: {integrity: sha512-pau7um4eAw94BEuuShUIeQDTf3k4Wt6oIUOYxMmkZgDHdqtIcxWND4LRxi8nI9KuT4I1bXQv67BCapkxt7Ywqw==} 214 | 215 | '@lezer/lr@1.3.9': 216 | resolution: {integrity: sha512-XPz6dzuTHlnsbA5M2DZgjflNQ+9Hi5Swhic0RULdp3oOs3rh6bqGZolosVqN/fQIT8uNiepzINJDnS39oweTHQ==} 217 | 218 | '@marijn/buildtool@0.1.4': 219 | resolution: {integrity: sha512-XHH+ZTlxd34snfIPwonUM0V1S4p2RBfDvG1sIDWWQyU7MQzRwLCHrPEWIrck6f+6iryOtYp/9p2IKJFJNkYZTw==} 220 | 221 | '@marijn/testtool@0.1.1': 222 | resolution: {integrity: sha512-mc8Tq46yGA5C4Nk0utPNy1iJmZGkezHkC9u0m8y46QMTwg/ImI76UCE3gnOa1NxV+yddrwV4JAK/9n//1JmtfA==} 223 | 224 | '@nodelib/fs.scandir@2.1.5': 225 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 226 | engines: {node: '>= 8'} 227 | 228 | '@nodelib/fs.stat@2.0.5': 229 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 230 | engines: {node: '>= 8'} 231 | 232 | '@nodelib/fs.walk@1.2.8': 233 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 234 | engines: {node: '>= 8'} 235 | 236 | '@types/codemirror@5.60.8': 237 | resolution: {integrity: sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==} 238 | 239 | '@types/estree@1.0.1': 240 | resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} 241 | 242 | '@types/json-schema@7.0.12': 243 | resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} 244 | 245 | '@types/mocha@9.1.1': 246 | resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} 247 | 248 | '@types/tern@0.23.4': 249 | resolution: {integrity: sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==} 250 | 251 | '@typescript-eslint/eslint-plugin@5.13.0': 252 | resolution: {integrity: sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==} 253 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 254 | peerDependencies: 255 | '@typescript-eslint/parser': ^5.0.0 256 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 257 | typescript: '*' 258 | peerDependenciesMeta: 259 | typescript: 260 | optional: true 261 | 262 | '@typescript-eslint/parser@5.13.0': 263 | resolution: {integrity: sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==} 264 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 265 | peerDependencies: 266 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 267 | typescript: '*' 268 | peerDependenciesMeta: 269 | typescript: 270 | optional: true 271 | 272 | '@typescript-eslint/scope-manager@5.13.0': 273 | resolution: {integrity: sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==} 274 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 275 | 276 | '@typescript-eslint/type-utils@5.13.0': 277 | resolution: {integrity: sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==} 278 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 279 | peerDependencies: 280 | eslint: '*' 281 | typescript: '*' 282 | peerDependenciesMeta: 283 | typescript: 284 | optional: true 285 | 286 | '@typescript-eslint/types@5.13.0': 287 | resolution: {integrity: sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==} 288 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 289 | 290 | '@typescript-eslint/typescript-estree@5.13.0': 291 | resolution: {integrity: sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==} 292 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 293 | peerDependencies: 294 | typescript: '*' 295 | peerDependenciesMeta: 296 | typescript: 297 | optional: true 298 | 299 | '@typescript-eslint/utils@5.13.0': 300 | resolution: {integrity: sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ==} 301 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 302 | peerDependencies: 303 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 304 | 305 | '@typescript-eslint/visitor-keys@5.13.0': 306 | resolution: {integrity: sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==} 307 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 308 | 309 | acorn-jsx@5.3.2: 310 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 311 | peerDependencies: 312 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 313 | 314 | acorn-walk@8.2.0: 315 | resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} 316 | engines: {node: '>=0.4.0'} 317 | 318 | acorn@8.10.0: 319 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} 320 | engines: {node: '>=0.4.0'} 321 | hasBin: true 322 | 323 | ajv@6.12.6: 324 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 325 | 326 | ansi-colors@4.1.1: 327 | resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} 328 | engines: {node: '>=6'} 329 | 330 | ansi-regex@5.0.1: 331 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 332 | engines: {node: '>=8'} 333 | 334 | ansi-styles@3.2.1: 335 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 336 | engines: {node: '>=4'} 337 | 338 | ansi-styles@4.3.0: 339 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 340 | engines: {node: '>=8'} 341 | 342 | anymatch@3.1.3: 343 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 344 | engines: {node: '>= 8'} 345 | 346 | argparse@2.0.1: 347 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 348 | 349 | array-union@2.1.0: 350 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 351 | engines: {node: '>=8'} 352 | 353 | balanced-match@1.0.2: 354 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 355 | 356 | binary-extensions@2.2.0: 357 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 358 | engines: {node: '>=8'} 359 | 360 | brace-expansion@1.1.11: 361 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 362 | 363 | brace-expansion@2.0.1: 364 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 365 | 366 | braces@3.0.2: 367 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 368 | engines: {node: '>=8'} 369 | 370 | browser-stdout@1.3.1: 371 | resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} 372 | 373 | builtin-modules@3.3.0: 374 | resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} 375 | engines: {node: '>=6'} 376 | 377 | callsites@3.1.0: 378 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 379 | engines: {node: '>=6'} 380 | 381 | camelcase@6.3.0: 382 | resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} 383 | engines: {node: '>=10'} 384 | 385 | chalk@2.4.2: 386 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 387 | engines: {node: '>=4'} 388 | 389 | chalk@4.1.2: 390 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 391 | engines: {node: '>=10'} 392 | 393 | chokidar@3.5.3: 394 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 395 | engines: {node: '>= 8.10.0'} 396 | 397 | cliui@7.0.4: 398 | resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} 399 | 400 | color-convert@1.9.3: 401 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 402 | 403 | color-convert@2.0.1: 404 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 405 | engines: {node: '>=7.0.0'} 406 | 407 | color-name@1.1.3: 408 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 409 | 410 | color-name@1.1.4: 411 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 412 | 413 | concat-map@0.0.1: 414 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 415 | 416 | core-util-is@1.0.3: 417 | resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} 418 | 419 | crelt@1.0.6: 420 | resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} 421 | 422 | cross-spawn@7.0.3: 423 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 424 | engines: {node: '>= 8'} 425 | 426 | debug@2.6.9: 427 | resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} 428 | peerDependencies: 429 | supports-color: '*' 430 | peerDependenciesMeta: 431 | supports-color: 432 | optional: true 433 | 434 | debug@4.3.4: 435 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 436 | engines: {node: '>=6.0'} 437 | peerDependencies: 438 | supports-color: '*' 439 | peerDependenciesMeta: 440 | supports-color: 441 | optional: true 442 | 443 | decamelize@4.0.0: 444 | resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} 445 | engines: {node: '>=10'} 446 | 447 | deep-is@0.1.4: 448 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 449 | 450 | depd@2.0.0: 451 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 452 | engines: {node: '>= 0.8'} 453 | 454 | destroy@1.2.0: 455 | resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} 456 | engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 457 | 458 | diff@5.0.0: 459 | resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} 460 | engines: {node: '>=0.3.1'} 461 | 462 | dir-glob@3.0.1: 463 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 464 | engines: {node: '>=8'} 465 | 466 | doctrine@3.0.0: 467 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} 468 | engines: {node: '>=6.0.0'} 469 | 470 | ee-first@1.1.1: 471 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 472 | 473 | emoji-regex@8.0.0: 474 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 475 | 476 | encodeurl@1.0.2: 477 | resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} 478 | engines: {node: '>= 0.8'} 479 | 480 | esbuild-android-64@0.14.47: 481 | resolution: {integrity: sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==} 482 | engines: {node: '>=12'} 483 | cpu: [x64] 484 | os: [android] 485 | 486 | esbuild-android-arm64@0.14.47: 487 | resolution: {integrity: sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==} 488 | engines: {node: '>=12'} 489 | cpu: [arm64] 490 | os: [android] 491 | 492 | esbuild-darwin-64@0.14.47: 493 | resolution: {integrity: sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==} 494 | engines: {node: '>=12'} 495 | cpu: [x64] 496 | os: [darwin] 497 | 498 | esbuild-darwin-arm64@0.14.47: 499 | resolution: {integrity: sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==} 500 | engines: {node: '>=12'} 501 | cpu: [arm64] 502 | os: [darwin] 503 | 504 | esbuild-freebsd-64@0.14.47: 505 | resolution: {integrity: sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==} 506 | engines: {node: '>=12'} 507 | cpu: [x64] 508 | os: [freebsd] 509 | 510 | esbuild-freebsd-arm64@0.14.47: 511 | resolution: {integrity: sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==} 512 | engines: {node: '>=12'} 513 | cpu: [arm64] 514 | os: [freebsd] 515 | 516 | esbuild-linux-32@0.14.47: 517 | resolution: {integrity: sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==} 518 | engines: {node: '>=12'} 519 | cpu: [ia32] 520 | os: [linux] 521 | 522 | esbuild-linux-64@0.14.47: 523 | resolution: {integrity: sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==} 524 | engines: {node: '>=12'} 525 | cpu: [x64] 526 | os: [linux] 527 | 528 | esbuild-linux-arm64@0.14.47: 529 | resolution: {integrity: sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==} 530 | engines: {node: '>=12'} 531 | cpu: [arm64] 532 | os: [linux] 533 | 534 | esbuild-linux-arm@0.14.47: 535 | resolution: {integrity: sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==} 536 | engines: {node: '>=12'} 537 | cpu: [arm] 538 | os: [linux] 539 | 540 | esbuild-linux-mips64le@0.14.47: 541 | resolution: {integrity: sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==} 542 | engines: {node: '>=12'} 543 | cpu: [mips64el] 544 | os: [linux] 545 | 546 | esbuild-linux-ppc64le@0.14.47: 547 | resolution: {integrity: sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==} 548 | engines: {node: '>=12'} 549 | cpu: [ppc64] 550 | os: [linux] 551 | 552 | esbuild-linux-riscv64@0.14.47: 553 | resolution: {integrity: sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==} 554 | engines: {node: '>=12'} 555 | cpu: [riscv64] 556 | os: [linux] 557 | 558 | esbuild-linux-s390x@0.14.47: 559 | resolution: {integrity: sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==} 560 | engines: {node: '>=12'} 561 | cpu: [s390x] 562 | os: [linux] 563 | 564 | esbuild-netbsd-64@0.14.47: 565 | resolution: {integrity: sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==} 566 | engines: {node: '>=12'} 567 | cpu: [x64] 568 | os: [netbsd] 569 | 570 | esbuild-openbsd-64@0.14.47: 571 | resolution: {integrity: sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==} 572 | engines: {node: '>=12'} 573 | cpu: [x64] 574 | os: [openbsd] 575 | 576 | esbuild-sunos-64@0.14.47: 577 | resolution: {integrity: sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==} 578 | engines: {node: '>=12'} 579 | cpu: [x64] 580 | os: [sunos] 581 | 582 | esbuild-windows-32@0.14.47: 583 | resolution: {integrity: sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==} 584 | engines: {node: '>=12'} 585 | cpu: [ia32] 586 | os: [win32] 587 | 588 | esbuild-windows-64@0.14.47: 589 | resolution: {integrity: sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==} 590 | engines: {node: '>=12'} 591 | cpu: [x64] 592 | os: [win32] 593 | 594 | esbuild-windows-arm64@0.14.47: 595 | resolution: {integrity: sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==} 596 | engines: {node: '>=12'} 597 | cpu: [arm64] 598 | os: [win32] 599 | 600 | esbuild@0.14.47: 601 | resolution: {integrity: sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==} 602 | engines: {node: '>=12'} 603 | hasBin: true 604 | 605 | escalade@3.1.1: 606 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 607 | engines: {node: '>=6'} 608 | 609 | escape-html@1.0.3: 610 | resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 611 | 612 | escape-string-regexp@1.0.5: 613 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 614 | engines: {node: '>=0.8.0'} 615 | 616 | escape-string-regexp@4.0.0: 617 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 618 | engines: {node: '>=10'} 619 | 620 | eslint-scope@5.1.1: 621 | resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} 622 | engines: {node: '>=8.0.0'} 623 | 624 | eslint-scope@7.2.2: 625 | resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} 626 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 627 | 628 | eslint-utils@3.0.0: 629 | resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} 630 | engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} 631 | peerDependencies: 632 | eslint: '>=5' 633 | 634 | eslint-visitor-keys@2.1.0: 635 | resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} 636 | engines: {node: '>=10'} 637 | 638 | eslint-visitor-keys@3.4.2: 639 | resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} 640 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 641 | 642 | eslint@8.46.0: 643 | resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} 644 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 645 | deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. 646 | hasBin: true 647 | 648 | esmoduleserve@0.2.0: 649 | resolution: {integrity: sha512-vg1j7fzKZUFR5TCsYQ3PABfBRMRi6V9K7mxcRh2MftO3gwAHBwYaPHtLHFDsKVSxdHmpu/GgT37lsRT+vezaKQ==} 650 | hasBin: true 651 | 652 | espree@9.6.1: 653 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} 654 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 655 | 656 | esquery@1.5.0: 657 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} 658 | engines: {node: '>=0.10'} 659 | 660 | esrecurse@4.3.0: 661 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 662 | engines: {node: '>=4.0'} 663 | 664 | estraverse@4.3.0: 665 | resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} 666 | engines: {node: '>=4.0'} 667 | 668 | estraverse@5.3.0: 669 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 670 | engines: {node: '>=4.0'} 671 | 672 | esutils@2.0.3: 673 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 674 | engines: {node: '>=0.10.0'} 675 | 676 | etag@1.8.1: 677 | resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} 678 | engines: {node: '>= 0.6'} 679 | 680 | fast-deep-equal@3.1.3: 681 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 682 | 683 | fast-glob@3.3.1: 684 | resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} 685 | engines: {node: '>=8.6.0'} 686 | 687 | fast-json-stable-stringify@2.1.0: 688 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 689 | 690 | fast-levenshtein@2.0.6: 691 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 692 | 693 | fastq@1.15.0: 694 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 695 | 696 | file-entry-cache@6.0.1: 697 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} 698 | engines: {node: ^10.12.0 || >=12.0.0} 699 | 700 | fill-range@7.0.1: 701 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 702 | engines: {node: '>=8'} 703 | 704 | find-up@5.0.0: 705 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 706 | engines: {node: '>=10'} 707 | 708 | flat-cache@3.0.4: 709 | resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} 710 | engines: {node: ^10.12.0 || >=12.0.0} 711 | 712 | flat@5.0.2: 713 | resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} 714 | hasBin: true 715 | 716 | flatted@3.2.7: 717 | resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} 718 | 719 | fresh@0.5.2: 720 | resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 721 | engines: {node: '>= 0.6'} 722 | 723 | fs.realpath@1.0.0: 724 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 725 | 726 | fsevents@2.3.2: 727 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 728 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 729 | os: [darwin] 730 | 731 | function-bind@1.1.1: 732 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 733 | 734 | functional-red-black-tree@1.0.1: 735 | resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} 736 | 737 | get-caller-file@2.0.5: 738 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 739 | engines: {node: 6.* || 8.* || >= 10.*} 740 | 741 | glob-parent@5.1.2: 742 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 743 | engines: {node: '>= 6'} 744 | 745 | glob-parent@6.0.2: 746 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 747 | engines: {node: '>=10.13.0'} 748 | 749 | glob@7.2.0: 750 | resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} 751 | 752 | glob@7.2.3: 753 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 754 | 755 | globals@13.20.0: 756 | resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} 757 | engines: {node: '>=8'} 758 | 759 | globby@11.1.0: 760 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 761 | engines: {node: '>=10'} 762 | 763 | graphemer@1.4.0: 764 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 765 | 766 | has-flag@3.0.0: 767 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 768 | engines: {node: '>=4'} 769 | 770 | has-flag@4.0.0: 771 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 772 | engines: {node: '>=8'} 773 | 774 | has@1.0.3: 775 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 776 | engines: {node: '>= 0.4.0'} 777 | 778 | he@1.2.0: 779 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 780 | hasBin: true 781 | 782 | http-errors@2.0.0: 783 | resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 784 | engines: {node: '>= 0.8'} 785 | 786 | ignore@5.2.4: 787 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 788 | engines: {node: '>= 4'} 789 | 790 | immediate@3.0.6: 791 | resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} 792 | 793 | import-fresh@3.3.0: 794 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 795 | engines: {node: '>=6'} 796 | 797 | imurmurhash@0.1.4: 798 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 799 | engines: {node: '>=0.8.19'} 800 | 801 | inflight@1.0.6: 802 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 803 | 804 | inherits@2.0.4: 805 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 806 | 807 | is-binary-path@2.1.0: 808 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 809 | engines: {node: '>=8'} 810 | 811 | is-core-module@2.12.1: 812 | resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} 813 | 814 | is-extglob@2.1.1: 815 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 816 | engines: {node: '>=0.10.0'} 817 | 818 | is-fullwidth-code-point@3.0.0: 819 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 820 | engines: {node: '>=8'} 821 | 822 | is-glob@4.0.3: 823 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 824 | engines: {node: '>=0.10.0'} 825 | 826 | is-number@7.0.0: 827 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 828 | engines: {node: '>=0.12.0'} 829 | 830 | is-path-inside@3.0.3: 831 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} 832 | engines: {node: '>=8'} 833 | 834 | is-plain-obj@2.1.0: 835 | resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} 836 | engines: {node: '>=8'} 837 | 838 | is-unicode-supported@0.1.0: 839 | resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} 840 | engines: {node: '>=10'} 841 | 842 | isarray@1.0.0: 843 | resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} 844 | 845 | isexe@2.0.0: 846 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 847 | 848 | ist@1.1.7: 849 | resolution: {integrity: sha512-ex9JyqY+tCjBlxN1pXlqxEgtGGUGp1TG83ll1xpu8SfPgOhfAhEGCuepNHlB+d7Le+hLoBcfCu/G0ZQaFbi9hA==} 850 | 851 | js-tokens@4.0.0: 852 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 853 | 854 | js-yaml@4.1.0: 855 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 856 | hasBin: true 857 | 858 | json-schema-traverse@0.4.1: 859 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 860 | 861 | json-stable-stringify-without-jsonify@1.0.1: 862 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 863 | 864 | jszip@3.10.1: 865 | resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} 866 | 867 | levn@0.4.1: 868 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 869 | engines: {node: '>= 0.8.0'} 870 | 871 | lie@3.3.0: 872 | resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} 873 | 874 | locate-path@6.0.0: 875 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 876 | engines: {node: '>=10'} 877 | 878 | lodash.merge@4.6.2: 879 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 880 | 881 | lodash@4.17.21: 882 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 883 | 884 | log-symbols@4.1.0: 885 | resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} 886 | engines: {node: '>=10'} 887 | 888 | lru-cache@6.0.0: 889 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 890 | engines: {node: '>=10'} 891 | 892 | magic-string@0.25.9: 893 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 894 | 895 | merge2@1.4.1: 896 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 897 | engines: {node: '>= 8'} 898 | 899 | micromatch@4.0.5: 900 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 901 | engines: {node: '>=8.6'} 902 | 903 | mime@1.6.0: 904 | resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} 905 | engines: {node: '>=4'} 906 | hasBin: true 907 | 908 | minimatch@3.1.2: 909 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 910 | 911 | minimatch@5.0.1: 912 | resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} 913 | engines: {node: '>=10'} 914 | 915 | mocha@10.2.0: 916 | resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} 917 | engines: {node: '>= 14.0.0'} 918 | hasBin: true 919 | 920 | moment@2.29.4: 921 | resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} 922 | 923 | monkey-around@3.0.0: 924 | resolution: {integrity: sha512-jL6uY2lEAoaHxZep1cNRkCZjoIWY4g5VYCjriEWmcyHU7w8NU1+JH57xE251UVTohK0lCxMjv0ZV4ByDLIXEpw==} 925 | 926 | ms@2.0.0: 927 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 928 | 929 | ms@2.1.2: 930 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 931 | 932 | ms@2.1.3: 933 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 934 | 935 | nanoid@3.3.3: 936 | resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} 937 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 938 | hasBin: true 939 | 940 | natural-compare@1.4.0: 941 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 942 | 943 | normalize-path@3.0.0: 944 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 945 | engines: {node: '>=0.10.0'} 946 | 947 | obsidian@1.8.7: 948 | resolution: {integrity: sha512-h4bWwNFAGRXlMlMAzdEiIM2ppTGlrh7uGOJS6w4gClrsjc+ei/3YAtU2VdFUlCiPuTHpY4aBpFJJW75S1Tl/JA==} 949 | peerDependencies: 950 | '@codemirror/state': ^6.0.0 951 | '@codemirror/view': ^6.0.0 952 | 953 | on-finished@2.4.1: 954 | resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 955 | engines: {node: '>= 0.8'} 956 | 957 | once@1.4.0: 958 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 959 | 960 | optionator@0.9.3: 961 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} 962 | engines: {node: '>= 0.8.0'} 963 | 964 | p-limit@3.1.0: 965 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 966 | engines: {node: '>=10'} 967 | 968 | p-locate@5.0.0: 969 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 970 | engines: {node: '>=10'} 971 | 972 | pako@1.0.11: 973 | resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} 974 | 975 | parent-module@1.0.1: 976 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 977 | engines: {node: '>=6'} 978 | 979 | parseurl@1.3.3: 980 | resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 981 | engines: {node: '>= 0.8'} 982 | 983 | path-exists@4.0.0: 984 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 985 | engines: {node: '>=8'} 986 | 987 | path-is-absolute@1.0.1: 988 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 989 | engines: {node: '>=0.10.0'} 990 | 991 | path-key@3.1.1: 992 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 993 | engines: {node: '>=8'} 994 | 995 | path-parse@1.0.7: 996 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 997 | 998 | path-type@4.0.0: 999 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1000 | engines: {node: '>=8'} 1001 | 1002 | picomatch@2.3.1: 1003 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1004 | engines: {node: '>=8.6'} 1005 | 1006 | prelude-ls@1.2.1: 1007 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1008 | engines: {node: '>= 0.8.0'} 1009 | 1010 | process-nextick-args@2.0.1: 1011 | resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} 1012 | 1013 | punycode@2.3.0: 1014 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 1015 | engines: {node: '>=6'} 1016 | 1017 | queue-microtask@1.2.3: 1018 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1019 | 1020 | randombytes@2.1.0: 1021 | resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} 1022 | 1023 | range-parser@1.2.1: 1024 | resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} 1025 | engines: {node: '>= 0.6'} 1026 | 1027 | readable-stream@2.3.8: 1028 | resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} 1029 | 1030 | readdirp@3.6.0: 1031 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1032 | engines: {node: '>=8.10.0'} 1033 | 1034 | regexpp@3.2.0: 1035 | resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} 1036 | engines: {node: '>=8'} 1037 | 1038 | require-directory@2.1.1: 1039 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 1040 | engines: {node: '>=0.10.0'} 1041 | 1042 | resolve-from@4.0.0: 1043 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1044 | engines: {node: '>=4'} 1045 | 1046 | resolve@1.22.2: 1047 | resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} 1048 | hasBin: true 1049 | 1050 | reusify@1.0.4: 1051 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1052 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1053 | 1054 | rimraf@3.0.2: 1055 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 1056 | hasBin: true 1057 | 1058 | rollup-plugin-dts@3.0.2: 1059 | resolution: {integrity: sha512-hswlsdWu/x7k5pXzaLP6OvKRKcx8Bzprksz9i9mUe72zvt8LvqAb/AZpzs6FkLgmyRaN8B6rUQOVtzA3yEt9Yw==} 1060 | engines: {node: '>=v12.22.1'} 1061 | peerDependencies: 1062 | rollup: ^2.48.0 1063 | typescript: ^4.2.4 1064 | 1065 | rollup@2.79.1: 1066 | resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} 1067 | engines: {node: '>=10.0.0'} 1068 | hasBin: true 1069 | 1070 | run-parallel@1.2.0: 1071 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1072 | 1073 | safe-buffer@5.1.2: 1074 | resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} 1075 | 1076 | safe-buffer@5.2.1: 1077 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 1078 | 1079 | selenium-webdriver@4.10.0: 1080 | resolution: {integrity: sha512-hSQPw6jgc+ej/UEcdQPG/iBwwMeCEgZr9HByY/J8ToyXztEqXzU9aLsIyrlj1BywBcStO4JQK/zMUWWrV8+riA==} 1081 | engines: {node: '>= 14.20.0'} 1082 | 1083 | semver@7.5.4: 1084 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 1085 | engines: {node: '>=10'} 1086 | hasBin: true 1087 | 1088 | send@0.18.0: 1089 | resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} 1090 | engines: {node: '>= 0.8.0'} 1091 | 1092 | serialize-javascript@6.0.0: 1093 | resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} 1094 | 1095 | serve-static@1.15.0: 1096 | resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} 1097 | engines: {node: '>= 0.8.0'} 1098 | 1099 | setimmediate@1.0.5: 1100 | resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} 1101 | 1102 | setprototypeof@1.2.0: 1103 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} 1104 | 1105 | shebang-command@2.0.0: 1106 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1107 | engines: {node: '>=8'} 1108 | 1109 | shebang-regex@3.0.0: 1110 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1111 | engines: {node: '>=8'} 1112 | 1113 | slash@3.0.0: 1114 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1115 | engines: {node: '>=8'} 1116 | 1117 | sourcemap-codec@1.4.8: 1118 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 1119 | deprecated: Please use @jridgewell/sourcemap-codec instead 1120 | 1121 | statuses@2.0.1: 1122 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 1123 | engines: {node: '>= 0.8'} 1124 | 1125 | string-width@4.2.3: 1126 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1127 | engines: {node: '>=8'} 1128 | 1129 | string_decoder@1.1.1: 1130 | resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} 1131 | 1132 | strip-ansi@6.0.1: 1133 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1134 | engines: {node: '>=8'} 1135 | 1136 | strip-json-comments@3.1.1: 1137 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1138 | engines: {node: '>=8'} 1139 | 1140 | style-mod@4.0.3: 1141 | resolution: {integrity: sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==} 1142 | 1143 | supports-color@5.5.0: 1144 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1145 | engines: {node: '>=4'} 1146 | 1147 | supports-color@7.2.0: 1148 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1149 | engines: {node: '>=8'} 1150 | 1151 | supports-color@8.1.1: 1152 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 1153 | engines: {node: '>=10'} 1154 | 1155 | supports-preserve-symlinks-flag@1.0.0: 1156 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1157 | engines: {node: '>= 0.4'} 1158 | 1159 | text-table@0.2.0: 1160 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 1161 | 1162 | tmp@0.2.1: 1163 | resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} 1164 | engines: {node: '>=8.17.0'} 1165 | 1166 | to-regex-range@5.0.1: 1167 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1168 | engines: {node: '>=8.0'} 1169 | 1170 | toidentifier@1.0.1: 1171 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 1172 | engines: {node: '>=0.6'} 1173 | 1174 | tslib@1.14.1: 1175 | resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} 1176 | 1177 | tslib@2.4.0: 1178 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} 1179 | 1180 | tsutils@3.21.0: 1181 | resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} 1182 | engines: {node: '>= 6'} 1183 | peerDependencies: 1184 | 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' 1185 | 1186 | type-check@0.4.0: 1187 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1188 | engines: {node: '>= 0.8.0'} 1189 | 1190 | type-fest@0.20.2: 1191 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} 1192 | engines: {node: '>=10'} 1193 | 1194 | typescript@4.7.4: 1195 | resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} 1196 | engines: {node: '>=4.2.0'} 1197 | hasBin: true 1198 | 1199 | uri-js@4.4.1: 1200 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1201 | 1202 | util-deprecate@1.0.2: 1203 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1204 | 1205 | w3c-keyname@2.2.8: 1206 | resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} 1207 | 1208 | which@2.0.2: 1209 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1210 | engines: {node: '>= 8'} 1211 | hasBin: true 1212 | 1213 | workerpool@6.2.1: 1214 | resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} 1215 | 1216 | wrap-ansi@7.0.0: 1217 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1218 | engines: {node: '>=10'} 1219 | 1220 | wrappy@1.0.2: 1221 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1222 | 1223 | ws@8.13.0: 1224 | resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} 1225 | engines: {node: '>=10.0.0'} 1226 | peerDependencies: 1227 | bufferutil: ^4.0.1 1228 | utf-8-validate: '>=5.0.2' 1229 | peerDependenciesMeta: 1230 | bufferutil: 1231 | optional: true 1232 | utf-8-validate: 1233 | optional: true 1234 | 1235 | y18n@5.0.8: 1236 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 1237 | engines: {node: '>=10'} 1238 | 1239 | yallist@4.0.0: 1240 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1241 | 1242 | yargs-parser@20.2.4: 1243 | resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} 1244 | engines: {node: '>=10'} 1245 | 1246 | yargs-unparser@2.0.0: 1247 | resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} 1248 | engines: {node: '>=10'} 1249 | 1250 | yargs@16.2.0: 1251 | resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} 1252 | engines: {node: '>=10'} 1253 | 1254 | yocto-queue@0.1.0: 1255 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1256 | engines: {node: '>=10'} 1257 | 1258 | snapshots: 1259 | 1260 | '@aashutoshrathi/word-wrap@1.2.6': {} 1261 | 1262 | '@babel/code-frame@7.22.5': 1263 | dependencies: 1264 | '@babel/highlight': 7.22.5 1265 | optional: true 1266 | 1267 | '@babel/helper-validator-identifier@7.22.5': 1268 | optional: true 1269 | 1270 | '@babel/highlight@7.22.5': 1271 | dependencies: 1272 | '@babel/helper-validator-identifier': 7.22.5 1273 | chalk: 2.4.2 1274 | js-tokens: 4.0.0 1275 | optional: true 1276 | 1277 | '@codemirror/autocomplete@0.20.3': 1278 | dependencies: 1279 | '@codemirror/language': 0.20.2 1280 | '@codemirror/state': 0.20.1 1281 | '@codemirror/view': 0.20.7 1282 | '@lezer/common': 0.16.1 1283 | 1284 | '@codemirror/autocomplete@6.9.0(@codemirror/language@6.8.0)(@codemirror/state@6.2.1)(@codemirror/view@6.15.0)(@lezer/common@1.0.3)': 1285 | dependencies: 1286 | '@codemirror/language': 6.8.0 1287 | '@codemirror/state': 6.2.1 1288 | '@codemirror/view': 6.15.0 1289 | '@lezer/common': 1.0.3 1290 | 1291 | '@codemirror/basic-setup@0.20.0': 1292 | dependencies: 1293 | '@codemirror/autocomplete': 0.20.3 1294 | '@codemirror/commands': 0.20.0 1295 | '@codemirror/language': 0.20.2 1296 | '@codemirror/lint': 0.20.3 1297 | '@codemirror/search': 0.20.1 1298 | '@codemirror/state': 0.20.1 1299 | '@codemirror/view': 0.20.7 1300 | 1301 | '@codemirror/buildhelper@1.0.0': 1302 | dependencies: 1303 | '@lezer/generator': 1.3.0 1304 | '@marijn/buildtool': 0.1.4 1305 | '@marijn/testtool': 0.1.1 1306 | transitivePeerDependencies: 1307 | - bufferutil 1308 | - supports-color 1309 | - utf-8-validate 1310 | 1311 | '@codemirror/commands@0.20.0': 1312 | dependencies: 1313 | '@codemirror/language': 0.20.2 1314 | '@codemirror/state': 0.20.1 1315 | '@codemirror/view': 0.20.7 1316 | '@lezer/common': 0.16.1 1317 | 1318 | '@codemirror/fold@0.19.4': 1319 | dependencies: 1320 | '@codemirror/gutter': 0.19.9 1321 | '@codemirror/language': 0.19.10 1322 | '@codemirror/rangeset': 0.19.9 1323 | '@codemirror/state': 0.19.9 1324 | '@codemirror/view': 0.19.48 1325 | 1326 | '@codemirror/gutter@0.19.9': 1327 | dependencies: 1328 | '@codemirror/rangeset': 0.19.9 1329 | '@codemirror/state': 0.19.9 1330 | '@codemirror/view': 0.19.48 1331 | 1332 | '@codemirror/lang-css@6.2.0(@codemirror/view@6.15.0)': 1333 | dependencies: 1334 | '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.8.0)(@codemirror/state@6.2.1)(@codemirror/view@6.15.0)(@lezer/common@1.0.3) 1335 | '@codemirror/language': 6.8.0 1336 | '@codemirror/state': 6.2.1 1337 | '@lezer/common': 1.0.3 1338 | '@lezer/css': 1.1.3 1339 | transitivePeerDependencies: 1340 | - '@codemirror/view' 1341 | 1342 | '@codemirror/language@0.19.10': 1343 | dependencies: 1344 | '@codemirror/state': 0.19.9 1345 | '@codemirror/text': 0.19.6 1346 | '@codemirror/view': 0.19.48 1347 | '@lezer/common': 0.15.12 1348 | '@lezer/lr': 0.15.8 1349 | 1350 | '@codemirror/language@0.20.2': 1351 | dependencies: 1352 | '@codemirror/state': 0.20.1 1353 | '@codemirror/view': 0.20.7 1354 | '@lezer/common': 0.16.1 1355 | '@lezer/highlight': 0.16.0 1356 | '@lezer/lr': 0.16.3 1357 | style-mod: 4.0.3 1358 | 1359 | '@codemirror/language@6.8.0': 1360 | dependencies: 1361 | '@codemirror/state': 6.2.1 1362 | '@codemirror/view': 6.15.0 1363 | '@lezer/common': 1.0.3 1364 | '@lezer/highlight': 1.1.6 1365 | '@lezer/lr': 1.3.9 1366 | style-mod: 4.0.3 1367 | 1368 | '@codemirror/lint@0.20.3': 1369 | dependencies: 1370 | '@codemirror/state': 0.20.1 1371 | '@codemirror/view': 0.20.7 1372 | crelt: 1.0.6 1373 | 1374 | '@codemirror/rangeset@0.19.9': 1375 | dependencies: 1376 | '@codemirror/state': 0.19.9 1377 | 1378 | '@codemirror/search@0.20.1': 1379 | dependencies: 1380 | '@codemirror/state': 0.20.1 1381 | '@codemirror/view': 0.20.7 1382 | crelt: 1.0.6 1383 | 1384 | '@codemirror/state@0.19.9': 1385 | dependencies: 1386 | '@codemirror/text': 0.19.6 1387 | 1388 | '@codemirror/state@0.20.1': {} 1389 | 1390 | '@codemirror/state@6.2.1': {} 1391 | 1392 | '@codemirror/text@0.19.6': {} 1393 | 1394 | '@codemirror/view@0.19.48': 1395 | dependencies: 1396 | '@codemirror/rangeset': 0.19.9 1397 | '@codemirror/state': 0.19.9 1398 | '@codemirror/text': 0.19.6 1399 | style-mod: 4.0.3 1400 | w3c-keyname: 2.2.8 1401 | 1402 | '@codemirror/view@0.20.7': 1403 | dependencies: 1404 | '@codemirror/state': 0.20.1 1405 | style-mod: 4.0.3 1406 | w3c-keyname: 2.2.8 1407 | 1408 | '@codemirror/view@6.15.0': 1409 | dependencies: 1410 | '@codemirror/state': 6.2.1 1411 | style-mod: 4.0.3 1412 | w3c-keyname: 2.2.8 1413 | 1414 | '@eslint-community/eslint-utils@4.4.0(eslint@8.46.0)': 1415 | dependencies: 1416 | eslint: 8.46.0 1417 | eslint-visitor-keys: 3.4.2 1418 | 1419 | '@eslint-community/regexpp@4.6.2': {} 1420 | 1421 | '@eslint/eslintrc@2.1.1': 1422 | dependencies: 1423 | ajv: 6.12.6 1424 | debug: 4.3.4(supports-color@8.1.1) 1425 | espree: 9.6.1 1426 | globals: 13.20.0 1427 | ignore: 5.2.4 1428 | import-fresh: 3.3.0 1429 | js-yaml: 4.1.0 1430 | minimatch: 3.1.2 1431 | strip-json-comments: 3.1.1 1432 | transitivePeerDependencies: 1433 | - supports-color 1434 | 1435 | '@eslint/js@8.46.0': {} 1436 | 1437 | '@humanwhocodes/config-array@0.11.10': 1438 | dependencies: 1439 | '@humanwhocodes/object-schema': 1.2.1 1440 | debug: 4.3.4(supports-color@8.1.1) 1441 | minimatch: 3.1.2 1442 | transitivePeerDependencies: 1443 | - supports-color 1444 | 1445 | '@humanwhocodes/module-importer@1.0.1': {} 1446 | 1447 | '@humanwhocodes/object-schema@1.2.1': {} 1448 | 1449 | '@lezer/common@0.15.12': {} 1450 | 1451 | '@lezer/common@0.16.1': {} 1452 | 1453 | '@lezer/common@1.0.3': {} 1454 | 1455 | '@lezer/css@1.1.3': 1456 | dependencies: 1457 | '@lezer/highlight': 1.1.6 1458 | '@lezer/lr': 1.3.9 1459 | 1460 | '@lezer/generator@1.3.0': 1461 | dependencies: 1462 | '@lezer/common': 1.0.3 1463 | '@lezer/lr': 1.3.9 1464 | 1465 | '@lezer/highlight@0.16.0': 1466 | dependencies: 1467 | '@lezer/common': 0.16.1 1468 | 1469 | '@lezer/highlight@1.1.6': 1470 | dependencies: 1471 | '@lezer/common': 1.0.3 1472 | 1473 | '@lezer/lr@0.15.8': 1474 | dependencies: 1475 | '@lezer/common': 0.15.12 1476 | 1477 | '@lezer/lr@0.16.3': 1478 | dependencies: 1479 | '@lezer/common': 0.16.1 1480 | 1481 | '@lezer/lr@1.3.9': 1482 | dependencies: 1483 | '@lezer/common': 1.0.3 1484 | 1485 | '@marijn/buildtool@0.1.4': 1486 | dependencies: 1487 | '@types/mocha': 9.1.1 1488 | acorn: 8.10.0 1489 | acorn-walk: 8.2.0 1490 | rollup: 2.79.1 1491 | rollup-plugin-dts: 3.0.2(rollup@2.79.1)(typescript@4.7.4) 1492 | typescript: 4.7.4 1493 | 1494 | '@marijn/testtool@0.1.1': 1495 | dependencies: 1496 | esmoduleserve: 0.2.0 1497 | ist: 1.1.7 1498 | mocha: 10.2.0 1499 | selenium-webdriver: 4.10.0 1500 | serve-static: 1.15.0 1501 | transitivePeerDependencies: 1502 | - bufferutil 1503 | - supports-color 1504 | - utf-8-validate 1505 | 1506 | '@nodelib/fs.scandir@2.1.5': 1507 | dependencies: 1508 | '@nodelib/fs.stat': 2.0.5 1509 | run-parallel: 1.2.0 1510 | 1511 | '@nodelib/fs.stat@2.0.5': {} 1512 | 1513 | '@nodelib/fs.walk@1.2.8': 1514 | dependencies: 1515 | '@nodelib/fs.scandir': 2.1.5 1516 | fastq: 1.15.0 1517 | 1518 | '@types/codemirror@5.60.8': 1519 | dependencies: 1520 | '@types/tern': 0.23.4 1521 | 1522 | '@types/estree@1.0.1': {} 1523 | 1524 | '@types/json-schema@7.0.12': {} 1525 | 1526 | '@types/mocha@9.1.1': {} 1527 | 1528 | '@types/tern@0.23.4': 1529 | dependencies: 1530 | '@types/estree': 1.0.1 1531 | 1532 | '@typescript-eslint/eslint-plugin@5.13.0(@typescript-eslint/parser@5.13.0(eslint@8.46.0)(typescript@4.7.4))(eslint@8.46.0)(typescript@4.7.4)': 1533 | dependencies: 1534 | '@typescript-eslint/parser': 5.13.0(eslint@8.46.0)(typescript@4.7.4) 1535 | '@typescript-eslint/scope-manager': 5.13.0 1536 | '@typescript-eslint/type-utils': 5.13.0(eslint@8.46.0)(typescript@4.7.4) 1537 | '@typescript-eslint/utils': 5.13.0(eslint@8.46.0)(typescript@4.7.4) 1538 | debug: 4.3.4(supports-color@8.1.1) 1539 | eslint: 8.46.0 1540 | functional-red-black-tree: 1.0.1 1541 | ignore: 5.2.4 1542 | regexpp: 3.2.0 1543 | semver: 7.5.4 1544 | tsutils: 3.21.0(typescript@4.7.4) 1545 | optionalDependencies: 1546 | typescript: 4.7.4 1547 | transitivePeerDependencies: 1548 | - supports-color 1549 | 1550 | '@typescript-eslint/parser@5.13.0(eslint@8.46.0)(typescript@4.7.4)': 1551 | dependencies: 1552 | '@typescript-eslint/scope-manager': 5.13.0 1553 | '@typescript-eslint/types': 5.13.0 1554 | '@typescript-eslint/typescript-estree': 5.13.0(typescript@4.7.4) 1555 | debug: 4.3.4(supports-color@8.1.1) 1556 | eslint: 8.46.0 1557 | optionalDependencies: 1558 | typescript: 4.7.4 1559 | transitivePeerDependencies: 1560 | - supports-color 1561 | 1562 | '@typescript-eslint/scope-manager@5.13.0': 1563 | dependencies: 1564 | '@typescript-eslint/types': 5.13.0 1565 | '@typescript-eslint/visitor-keys': 5.13.0 1566 | 1567 | '@typescript-eslint/type-utils@5.13.0(eslint@8.46.0)(typescript@4.7.4)': 1568 | dependencies: 1569 | '@typescript-eslint/utils': 5.13.0(eslint@8.46.0)(typescript@4.7.4) 1570 | debug: 4.3.4(supports-color@8.1.1) 1571 | eslint: 8.46.0 1572 | tsutils: 3.21.0(typescript@4.7.4) 1573 | optionalDependencies: 1574 | typescript: 4.7.4 1575 | transitivePeerDependencies: 1576 | - supports-color 1577 | 1578 | '@typescript-eslint/types@5.13.0': {} 1579 | 1580 | '@typescript-eslint/typescript-estree@5.13.0(typescript@4.7.4)': 1581 | dependencies: 1582 | '@typescript-eslint/types': 5.13.0 1583 | '@typescript-eslint/visitor-keys': 5.13.0 1584 | debug: 4.3.4(supports-color@8.1.1) 1585 | globby: 11.1.0 1586 | is-glob: 4.0.3 1587 | semver: 7.5.4 1588 | tsutils: 3.21.0(typescript@4.7.4) 1589 | optionalDependencies: 1590 | typescript: 4.7.4 1591 | transitivePeerDependencies: 1592 | - supports-color 1593 | 1594 | '@typescript-eslint/utils@5.13.0(eslint@8.46.0)(typescript@4.7.4)': 1595 | dependencies: 1596 | '@types/json-schema': 7.0.12 1597 | '@typescript-eslint/scope-manager': 5.13.0 1598 | '@typescript-eslint/types': 5.13.0 1599 | '@typescript-eslint/typescript-estree': 5.13.0(typescript@4.7.4) 1600 | eslint: 8.46.0 1601 | eslint-scope: 5.1.1 1602 | eslint-utils: 3.0.0(eslint@8.46.0) 1603 | transitivePeerDependencies: 1604 | - supports-color 1605 | - typescript 1606 | 1607 | '@typescript-eslint/visitor-keys@5.13.0': 1608 | dependencies: 1609 | '@typescript-eslint/types': 5.13.0 1610 | eslint-visitor-keys: 3.4.2 1611 | 1612 | acorn-jsx@5.3.2(acorn@8.10.0): 1613 | dependencies: 1614 | acorn: 8.10.0 1615 | 1616 | acorn-walk@8.2.0: {} 1617 | 1618 | acorn@8.10.0: {} 1619 | 1620 | ajv@6.12.6: 1621 | dependencies: 1622 | fast-deep-equal: 3.1.3 1623 | fast-json-stable-stringify: 2.1.0 1624 | json-schema-traverse: 0.4.1 1625 | uri-js: 4.4.1 1626 | 1627 | ansi-colors@4.1.1: {} 1628 | 1629 | ansi-regex@5.0.1: {} 1630 | 1631 | ansi-styles@3.2.1: 1632 | dependencies: 1633 | color-convert: 1.9.3 1634 | optional: true 1635 | 1636 | ansi-styles@4.3.0: 1637 | dependencies: 1638 | color-convert: 2.0.1 1639 | 1640 | anymatch@3.1.3: 1641 | dependencies: 1642 | normalize-path: 3.0.0 1643 | picomatch: 2.3.1 1644 | 1645 | argparse@2.0.1: {} 1646 | 1647 | array-union@2.1.0: {} 1648 | 1649 | balanced-match@1.0.2: {} 1650 | 1651 | binary-extensions@2.2.0: {} 1652 | 1653 | brace-expansion@1.1.11: 1654 | dependencies: 1655 | balanced-match: 1.0.2 1656 | concat-map: 0.0.1 1657 | 1658 | brace-expansion@2.0.1: 1659 | dependencies: 1660 | balanced-match: 1.0.2 1661 | 1662 | braces@3.0.2: 1663 | dependencies: 1664 | fill-range: 7.0.1 1665 | 1666 | browser-stdout@1.3.1: {} 1667 | 1668 | builtin-modules@3.3.0: {} 1669 | 1670 | callsites@3.1.0: {} 1671 | 1672 | camelcase@6.3.0: {} 1673 | 1674 | chalk@2.4.2: 1675 | dependencies: 1676 | ansi-styles: 3.2.1 1677 | escape-string-regexp: 1.0.5 1678 | supports-color: 5.5.0 1679 | optional: true 1680 | 1681 | chalk@4.1.2: 1682 | dependencies: 1683 | ansi-styles: 4.3.0 1684 | supports-color: 7.2.0 1685 | 1686 | chokidar@3.5.3: 1687 | dependencies: 1688 | anymatch: 3.1.3 1689 | braces: 3.0.2 1690 | glob-parent: 5.1.2 1691 | is-binary-path: 2.1.0 1692 | is-glob: 4.0.3 1693 | normalize-path: 3.0.0 1694 | readdirp: 3.6.0 1695 | optionalDependencies: 1696 | fsevents: 2.3.2 1697 | 1698 | cliui@7.0.4: 1699 | dependencies: 1700 | string-width: 4.2.3 1701 | strip-ansi: 6.0.1 1702 | wrap-ansi: 7.0.0 1703 | 1704 | color-convert@1.9.3: 1705 | dependencies: 1706 | color-name: 1.1.3 1707 | optional: true 1708 | 1709 | color-convert@2.0.1: 1710 | dependencies: 1711 | color-name: 1.1.4 1712 | 1713 | color-name@1.1.3: 1714 | optional: true 1715 | 1716 | color-name@1.1.4: {} 1717 | 1718 | concat-map@0.0.1: {} 1719 | 1720 | core-util-is@1.0.3: {} 1721 | 1722 | crelt@1.0.6: {} 1723 | 1724 | cross-spawn@7.0.3: 1725 | dependencies: 1726 | path-key: 3.1.1 1727 | shebang-command: 2.0.0 1728 | which: 2.0.2 1729 | 1730 | debug@2.6.9: 1731 | dependencies: 1732 | ms: 2.0.0 1733 | 1734 | debug@4.3.4(supports-color@8.1.1): 1735 | dependencies: 1736 | ms: 2.1.2 1737 | optionalDependencies: 1738 | supports-color: 8.1.1 1739 | 1740 | decamelize@4.0.0: {} 1741 | 1742 | deep-is@0.1.4: {} 1743 | 1744 | depd@2.0.0: {} 1745 | 1746 | destroy@1.2.0: {} 1747 | 1748 | diff@5.0.0: {} 1749 | 1750 | dir-glob@3.0.1: 1751 | dependencies: 1752 | path-type: 4.0.0 1753 | 1754 | doctrine@3.0.0: 1755 | dependencies: 1756 | esutils: 2.0.3 1757 | 1758 | ee-first@1.1.1: {} 1759 | 1760 | emoji-regex@8.0.0: {} 1761 | 1762 | encodeurl@1.0.2: {} 1763 | 1764 | esbuild-android-64@0.14.47: 1765 | optional: true 1766 | 1767 | esbuild-android-arm64@0.14.47: 1768 | optional: true 1769 | 1770 | esbuild-darwin-64@0.14.47: 1771 | optional: true 1772 | 1773 | esbuild-darwin-arm64@0.14.47: 1774 | optional: true 1775 | 1776 | esbuild-freebsd-64@0.14.47: 1777 | optional: true 1778 | 1779 | esbuild-freebsd-arm64@0.14.47: 1780 | optional: true 1781 | 1782 | esbuild-linux-32@0.14.47: 1783 | optional: true 1784 | 1785 | esbuild-linux-64@0.14.47: 1786 | optional: true 1787 | 1788 | esbuild-linux-arm64@0.14.47: 1789 | optional: true 1790 | 1791 | esbuild-linux-arm@0.14.47: 1792 | optional: true 1793 | 1794 | esbuild-linux-mips64le@0.14.47: 1795 | optional: true 1796 | 1797 | esbuild-linux-ppc64le@0.14.47: 1798 | optional: true 1799 | 1800 | esbuild-linux-riscv64@0.14.47: 1801 | optional: true 1802 | 1803 | esbuild-linux-s390x@0.14.47: 1804 | optional: true 1805 | 1806 | esbuild-netbsd-64@0.14.47: 1807 | optional: true 1808 | 1809 | esbuild-openbsd-64@0.14.47: 1810 | optional: true 1811 | 1812 | esbuild-sunos-64@0.14.47: 1813 | optional: true 1814 | 1815 | esbuild-windows-32@0.14.47: 1816 | optional: true 1817 | 1818 | esbuild-windows-64@0.14.47: 1819 | optional: true 1820 | 1821 | esbuild-windows-arm64@0.14.47: 1822 | optional: true 1823 | 1824 | esbuild@0.14.47: 1825 | optionalDependencies: 1826 | esbuild-android-64: 0.14.47 1827 | esbuild-android-arm64: 0.14.47 1828 | esbuild-darwin-64: 0.14.47 1829 | esbuild-darwin-arm64: 0.14.47 1830 | esbuild-freebsd-64: 0.14.47 1831 | esbuild-freebsd-arm64: 0.14.47 1832 | esbuild-linux-32: 0.14.47 1833 | esbuild-linux-64: 0.14.47 1834 | esbuild-linux-arm: 0.14.47 1835 | esbuild-linux-arm64: 0.14.47 1836 | esbuild-linux-mips64le: 0.14.47 1837 | esbuild-linux-ppc64le: 0.14.47 1838 | esbuild-linux-riscv64: 0.14.47 1839 | esbuild-linux-s390x: 0.14.47 1840 | esbuild-netbsd-64: 0.14.47 1841 | esbuild-openbsd-64: 0.14.47 1842 | esbuild-sunos-64: 0.14.47 1843 | esbuild-windows-32: 0.14.47 1844 | esbuild-windows-64: 0.14.47 1845 | esbuild-windows-arm64: 0.14.47 1846 | 1847 | escalade@3.1.1: {} 1848 | 1849 | escape-html@1.0.3: {} 1850 | 1851 | escape-string-regexp@1.0.5: 1852 | optional: true 1853 | 1854 | escape-string-regexp@4.0.0: {} 1855 | 1856 | eslint-scope@5.1.1: 1857 | dependencies: 1858 | esrecurse: 4.3.0 1859 | estraverse: 4.3.0 1860 | 1861 | eslint-scope@7.2.2: 1862 | dependencies: 1863 | esrecurse: 4.3.0 1864 | estraverse: 5.3.0 1865 | 1866 | eslint-utils@3.0.0(eslint@8.46.0): 1867 | dependencies: 1868 | eslint: 8.46.0 1869 | eslint-visitor-keys: 2.1.0 1870 | 1871 | eslint-visitor-keys@2.1.0: {} 1872 | 1873 | eslint-visitor-keys@3.4.2: {} 1874 | 1875 | eslint@8.46.0: 1876 | dependencies: 1877 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) 1878 | '@eslint-community/regexpp': 4.6.2 1879 | '@eslint/eslintrc': 2.1.1 1880 | '@eslint/js': 8.46.0 1881 | '@humanwhocodes/config-array': 0.11.10 1882 | '@humanwhocodes/module-importer': 1.0.1 1883 | '@nodelib/fs.walk': 1.2.8 1884 | ajv: 6.12.6 1885 | chalk: 4.1.2 1886 | cross-spawn: 7.0.3 1887 | debug: 4.3.4(supports-color@8.1.1) 1888 | doctrine: 3.0.0 1889 | escape-string-regexp: 4.0.0 1890 | eslint-scope: 7.2.2 1891 | eslint-visitor-keys: 3.4.2 1892 | espree: 9.6.1 1893 | esquery: 1.5.0 1894 | esutils: 2.0.3 1895 | fast-deep-equal: 3.1.3 1896 | file-entry-cache: 6.0.1 1897 | find-up: 5.0.0 1898 | glob-parent: 6.0.2 1899 | globals: 13.20.0 1900 | graphemer: 1.4.0 1901 | ignore: 5.2.4 1902 | imurmurhash: 0.1.4 1903 | is-glob: 4.0.3 1904 | is-path-inside: 3.0.3 1905 | js-yaml: 4.1.0 1906 | json-stable-stringify-without-jsonify: 1.0.1 1907 | levn: 0.4.1 1908 | lodash.merge: 4.6.2 1909 | minimatch: 3.1.2 1910 | natural-compare: 1.4.0 1911 | optionator: 0.9.3 1912 | strip-ansi: 6.0.1 1913 | text-table: 0.2.0 1914 | transitivePeerDependencies: 1915 | - supports-color 1916 | 1917 | esmoduleserve@0.2.0: 1918 | dependencies: 1919 | acorn: 8.10.0 1920 | acorn-walk: 8.2.0 1921 | resolve: 1.22.2 1922 | serve-static: 1.15.0 1923 | transitivePeerDependencies: 1924 | - supports-color 1925 | 1926 | espree@9.6.1: 1927 | dependencies: 1928 | acorn: 8.10.0 1929 | acorn-jsx: 5.3.2(acorn@8.10.0) 1930 | eslint-visitor-keys: 3.4.2 1931 | 1932 | esquery@1.5.0: 1933 | dependencies: 1934 | estraverse: 5.3.0 1935 | 1936 | esrecurse@4.3.0: 1937 | dependencies: 1938 | estraverse: 5.3.0 1939 | 1940 | estraverse@4.3.0: {} 1941 | 1942 | estraverse@5.3.0: {} 1943 | 1944 | esutils@2.0.3: {} 1945 | 1946 | etag@1.8.1: {} 1947 | 1948 | fast-deep-equal@3.1.3: {} 1949 | 1950 | fast-glob@3.3.1: 1951 | dependencies: 1952 | '@nodelib/fs.stat': 2.0.5 1953 | '@nodelib/fs.walk': 1.2.8 1954 | glob-parent: 5.1.2 1955 | merge2: 1.4.1 1956 | micromatch: 4.0.5 1957 | 1958 | fast-json-stable-stringify@2.1.0: {} 1959 | 1960 | fast-levenshtein@2.0.6: {} 1961 | 1962 | fastq@1.15.0: 1963 | dependencies: 1964 | reusify: 1.0.4 1965 | 1966 | file-entry-cache@6.0.1: 1967 | dependencies: 1968 | flat-cache: 3.0.4 1969 | 1970 | fill-range@7.0.1: 1971 | dependencies: 1972 | to-regex-range: 5.0.1 1973 | 1974 | find-up@5.0.0: 1975 | dependencies: 1976 | locate-path: 6.0.0 1977 | path-exists: 4.0.0 1978 | 1979 | flat-cache@3.0.4: 1980 | dependencies: 1981 | flatted: 3.2.7 1982 | rimraf: 3.0.2 1983 | 1984 | flat@5.0.2: {} 1985 | 1986 | flatted@3.2.7: {} 1987 | 1988 | fresh@0.5.2: {} 1989 | 1990 | fs.realpath@1.0.0: {} 1991 | 1992 | fsevents@2.3.2: 1993 | optional: true 1994 | 1995 | function-bind@1.1.1: {} 1996 | 1997 | functional-red-black-tree@1.0.1: {} 1998 | 1999 | get-caller-file@2.0.5: {} 2000 | 2001 | glob-parent@5.1.2: 2002 | dependencies: 2003 | is-glob: 4.0.3 2004 | 2005 | glob-parent@6.0.2: 2006 | dependencies: 2007 | is-glob: 4.0.3 2008 | 2009 | glob@7.2.0: 2010 | dependencies: 2011 | fs.realpath: 1.0.0 2012 | inflight: 1.0.6 2013 | inherits: 2.0.4 2014 | minimatch: 3.1.2 2015 | once: 1.4.0 2016 | path-is-absolute: 1.0.1 2017 | 2018 | glob@7.2.3: 2019 | dependencies: 2020 | fs.realpath: 1.0.0 2021 | inflight: 1.0.6 2022 | inherits: 2.0.4 2023 | minimatch: 3.1.2 2024 | once: 1.4.0 2025 | path-is-absolute: 1.0.1 2026 | 2027 | globals@13.20.0: 2028 | dependencies: 2029 | type-fest: 0.20.2 2030 | 2031 | globby@11.1.0: 2032 | dependencies: 2033 | array-union: 2.1.0 2034 | dir-glob: 3.0.1 2035 | fast-glob: 3.3.1 2036 | ignore: 5.2.4 2037 | merge2: 1.4.1 2038 | slash: 3.0.0 2039 | 2040 | graphemer@1.4.0: {} 2041 | 2042 | has-flag@3.0.0: 2043 | optional: true 2044 | 2045 | has-flag@4.0.0: {} 2046 | 2047 | has@1.0.3: 2048 | dependencies: 2049 | function-bind: 1.1.1 2050 | 2051 | he@1.2.0: {} 2052 | 2053 | http-errors@2.0.0: 2054 | dependencies: 2055 | depd: 2.0.0 2056 | inherits: 2.0.4 2057 | setprototypeof: 1.2.0 2058 | statuses: 2.0.1 2059 | toidentifier: 1.0.1 2060 | 2061 | ignore@5.2.4: {} 2062 | 2063 | immediate@3.0.6: {} 2064 | 2065 | import-fresh@3.3.0: 2066 | dependencies: 2067 | parent-module: 1.0.1 2068 | resolve-from: 4.0.0 2069 | 2070 | imurmurhash@0.1.4: {} 2071 | 2072 | inflight@1.0.6: 2073 | dependencies: 2074 | once: 1.4.0 2075 | wrappy: 1.0.2 2076 | 2077 | inherits@2.0.4: {} 2078 | 2079 | is-binary-path@2.1.0: 2080 | dependencies: 2081 | binary-extensions: 2.2.0 2082 | 2083 | is-core-module@2.12.1: 2084 | dependencies: 2085 | has: 1.0.3 2086 | 2087 | is-extglob@2.1.1: {} 2088 | 2089 | is-fullwidth-code-point@3.0.0: {} 2090 | 2091 | is-glob@4.0.3: 2092 | dependencies: 2093 | is-extglob: 2.1.1 2094 | 2095 | is-number@7.0.0: {} 2096 | 2097 | is-path-inside@3.0.3: {} 2098 | 2099 | is-plain-obj@2.1.0: {} 2100 | 2101 | is-unicode-supported@0.1.0: {} 2102 | 2103 | isarray@1.0.0: {} 2104 | 2105 | isexe@2.0.0: {} 2106 | 2107 | ist@1.1.7: {} 2108 | 2109 | js-tokens@4.0.0: 2110 | optional: true 2111 | 2112 | js-yaml@4.1.0: 2113 | dependencies: 2114 | argparse: 2.0.1 2115 | 2116 | json-schema-traverse@0.4.1: {} 2117 | 2118 | json-stable-stringify-without-jsonify@1.0.1: {} 2119 | 2120 | jszip@3.10.1: 2121 | dependencies: 2122 | lie: 3.3.0 2123 | pako: 1.0.11 2124 | readable-stream: 2.3.8 2125 | setimmediate: 1.0.5 2126 | 2127 | levn@0.4.1: 2128 | dependencies: 2129 | prelude-ls: 1.2.1 2130 | type-check: 0.4.0 2131 | 2132 | lie@3.3.0: 2133 | dependencies: 2134 | immediate: 3.0.6 2135 | 2136 | locate-path@6.0.0: 2137 | dependencies: 2138 | p-locate: 5.0.0 2139 | 2140 | lodash.merge@4.6.2: {} 2141 | 2142 | lodash@4.17.21: {} 2143 | 2144 | log-symbols@4.1.0: 2145 | dependencies: 2146 | chalk: 4.1.2 2147 | is-unicode-supported: 0.1.0 2148 | 2149 | lru-cache@6.0.0: 2150 | dependencies: 2151 | yallist: 4.0.0 2152 | 2153 | magic-string@0.25.9: 2154 | dependencies: 2155 | sourcemap-codec: 1.4.8 2156 | 2157 | merge2@1.4.1: {} 2158 | 2159 | micromatch@4.0.5: 2160 | dependencies: 2161 | braces: 3.0.2 2162 | picomatch: 2.3.1 2163 | 2164 | mime@1.6.0: {} 2165 | 2166 | minimatch@3.1.2: 2167 | dependencies: 2168 | brace-expansion: 1.1.11 2169 | 2170 | minimatch@5.0.1: 2171 | dependencies: 2172 | brace-expansion: 2.0.1 2173 | 2174 | mocha@10.2.0: 2175 | dependencies: 2176 | ansi-colors: 4.1.1 2177 | browser-stdout: 1.3.1 2178 | chokidar: 3.5.3 2179 | debug: 4.3.4(supports-color@8.1.1) 2180 | diff: 5.0.0 2181 | escape-string-regexp: 4.0.0 2182 | find-up: 5.0.0 2183 | glob: 7.2.0 2184 | he: 1.2.0 2185 | js-yaml: 4.1.0 2186 | log-symbols: 4.1.0 2187 | minimatch: 5.0.1 2188 | ms: 2.1.3 2189 | nanoid: 3.3.3 2190 | serialize-javascript: 6.0.0 2191 | strip-json-comments: 3.1.1 2192 | supports-color: 8.1.1 2193 | workerpool: 6.2.1 2194 | yargs: 16.2.0 2195 | yargs-parser: 20.2.4 2196 | yargs-unparser: 2.0.0 2197 | 2198 | moment@2.29.4: {} 2199 | 2200 | monkey-around@3.0.0: {} 2201 | 2202 | ms@2.0.0: {} 2203 | 2204 | ms@2.1.2: {} 2205 | 2206 | ms@2.1.3: {} 2207 | 2208 | nanoid@3.3.3: {} 2209 | 2210 | natural-compare@1.4.0: {} 2211 | 2212 | normalize-path@3.0.0: {} 2213 | 2214 | obsidian@1.8.7(@codemirror/state@6.2.1)(@codemirror/view@6.15.0): 2215 | dependencies: 2216 | '@codemirror/state': 6.2.1 2217 | '@codemirror/view': 6.15.0 2218 | '@types/codemirror': 5.60.8 2219 | moment: 2.29.4 2220 | 2221 | on-finished@2.4.1: 2222 | dependencies: 2223 | ee-first: 1.1.1 2224 | 2225 | once@1.4.0: 2226 | dependencies: 2227 | wrappy: 1.0.2 2228 | 2229 | optionator@0.9.3: 2230 | dependencies: 2231 | '@aashutoshrathi/word-wrap': 1.2.6 2232 | deep-is: 0.1.4 2233 | fast-levenshtein: 2.0.6 2234 | levn: 0.4.1 2235 | prelude-ls: 1.2.1 2236 | type-check: 0.4.0 2237 | 2238 | p-limit@3.1.0: 2239 | dependencies: 2240 | yocto-queue: 0.1.0 2241 | 2242 | p-locate@5.0.0: 2243 | dependencies: 2244 | p-limit: 3.1.0 2245 | 2246 | pako@1.0.11: {} 2247 | 2248 | parent-module@1.0.1: 2249 | dependencies: 2250 | callsites: 3.1.0 2251 | 2252 | parseurl@1.3.3: {} 2253 | 2254 | path-exists@4.0.0: {} 2255 | 2256 | path-is-absolute@1.0.1: {} 2257 | 2258 | path-key@3.1.1: {} 2259 | 2260 | path-parse@1.0.7: {} 2261 | 2262 | path-type@4.0.0: {} 2263 | 2264 | picomatch@2.3.1: {} 2265 | 2266 | prelude-ls@1.2.1: {} 2267 | 2268 | process-nextick-args@2.0.1: {} 2269 | 2270 | punycode@2.3.0: {} 2271 | 2272 | queue-microtask@1.2.3: {} 2273 | 2274 | randombytes@2.1.0: 2275 | dependencies: 2276 | safe-buffer: 5.2.1 2277 | 2278 | range-parser@1.2.1: {} 2279 | 2280 | readable-stream@2.3.8: 2281 | dependencies: 2282 | core-util-is: 1.0.3 2283 | inherits: 2.0.4 2284 | isarray: 1.0.0 2285 | process-nextick-args: 2.0.1 2286 | safe-buffer: 5.1.2 2287 | string_decoder: 1.1.1 2288 | util-deprecate: 1.0.2 2289 | 2290 | readdirp@3.6.0: 2291 | dependencies: 2292 | picomatch: 2.3.1 2293 | 2294 | regexpp@3.2.0: {} 2295 | 2296 | require-directory@2.1.1: {} 2297 | 2298 | resolve-from@4.0.0: {} 2299 | 2300 | resolve@1.22.2: 2301 | dependencies: 2302 | is-core-module: 2.12.1 2303 | path-parse: 1.0.7 2304 | supports-preserve-symlinks-flag: 1.0.0 2305 | 2306 | reusify@1.0.4: {} 2307 | 2308 | rimraf@3.0.2: 2309 | dependencies: 2310 | glob: 7.2.3 2311 | 2312 | rollup-plugin-dts@3.0.2(rollup@2.79.1)(typescript@4.7.4): 2313 | dependencies: 2314 | magic-string: 0.25.9 2315 | rollup: 2.79.1 2316 | typescript: 4.7.4 2317 | optionalDependencies: 2318 | '@babel/code-frame': 7.22.5 2319 | 2320 | rollup@2.79.1: 2321 | optionalDependencies: 2322 | fsevents: 2.3.2 2323 | 2324 | run-parallel@1.2.0: 2325 | dependencies: 2326 | queue-microtask: 1.2.3 2327 | 2328 | safe-buffer@5.1.2: {} 2329 | 2330 | safe-buffer@5.2.1: {} 2331 | 2332 | selenium-webdriver@4.10.0: 2333 | dependencies: 2334 | jszip: 3.10.1 2335 | tmp: 0.2.1 2336 | ws: 8.13.0 2337 | transitivePeerDependencies: 2338 | - bufferutil 2339 | - utf-8-validate 2340 | 2341 | semver@7.5.4: 2342 | dependencies: 2343 | lru-cache: 6.0.0 2344 | 2345 | send@0.18.0: 2346 | dependencies: 2347 | debug: 2.6.9 2348 | depd: 2.0.0 2349 | destroy: 1.2.0 2350 | encodeurl: 1.0.2 2351 | escape-html: 1.0.3 2352 | etag: 1.8.1 2353 | fresh: 0.5.2 2354 | http-errors: 2.0.0 2355 | mime: 1.6.0 2356 | ms: 2.1.3 2357 | on-finished: 2.4.1 2358 | range-parser: 1.2.1 2359 | statuses: 2.0.1 2360 | transitivePeerDependencies: 2361 | - supports-color 2362 | 2363 | serialize-javascript@6.0.0: 2364 | dependencies: 2365 | randombytes: 2.1.0 2366 | 2367 | serve-static@1.15.0: 2368 | dependencies: 2369 | encodeurl: 1.0.2 2370 | escape-html: 1.0.3 2371 | parseurl: 1.3.3 2372 | send: 0.18.0 2373 | transitivePeerDependencies: 2374 | - supports-color 2375 | 2376 | setimmediate@1.0.5: {} 2377 | 2378 | setprototypeof@1.2.0: {} 2379 | 2380 | shebang-command@2.0.0: 2381 | dependencies: 2382 | shebang-regex: 3.0.0 2383 | 2384 | shebang-regex@3.0.0: {} 2385 | 2386 | slash@3.0.0: {} 2387 | 2388 | sourcemap-codec@1.4.8: {} 2389 | 2390 | statuses@2.0.1: {} 2391 | 2392 | string-width@4.2.3: 2393 | dependencies: 2394 | emoji-regex: 8.0.0 2395 | is-fullwidth-code-point: 3.0.0 2396 | strip-ansi: 6.0.1 2397 | 2398 | string_decoder@1.1.1: 2399 | dependencies: 2400 | safe-buffer: 5.1.2 2401 | 2402 | strip-ansi@6.0.1: 2403 | dependencies: 2404 | ansi-regex: 5.0.1 2405 | 2406 | strip-json-comments@3.1.1: {} 2407 | 2408 | style-mod@4.0.3: {} 2409 | 2410 | supports-color@5.5.0: 2411 | dependencies: 2412 | has-flag: 3.0.0 2413 | optional: true 2414 | 2415 | supports-color@7.2.0: 2416 | dependencies: 2417 | has-flag: 4.0.0 2418 | 2419 | supports-color@8.1.1: 2420 | dependencies: 2421 | has-flag: 4.0.0 2422 | 2423 | supports-preserve-symlinks-flag@1.0.0: {} 2424 | 2425 | text-table@0.2.0: {} 2426 | 2427 | tmp@0.2.1: 2428 | dependencies: 2429 | rimraf: 3.0.2 2430 | 2431 | to-regex-range@5.0.1: 2432 | dependencies: 2433 | is-number: 7.0.0 2434 | 2435 | toidentifier@1.0.1: {} 2436 | 2437 | tslib@1.14.1: {} 2438 | 2439 | tslib@2.4.0: {} 2440 | 2441 | tsutils@3.21.0(typescript@4.7.4): 2442 | dependencies: 2443 | tslib: 1.14.1 2444 | typescript: 4.7.4 2445 | 2446 | type-check@0.4.0: 2447 | dependencies: 2448 | prelude-ls: 1.2.1 2449 | 2450 | type-fest@0.20.2: {} 2451 | 2452 | typescript@4.7.4: {} 2453 | 2454 | uri-js@4.4.1: 2455 | dependencies: 2456 | punycode: 2.3.0 2457 | 2458 | util-deprecate@1.0.2: {} 2459 | 2460 | w3c-keyname@2.2.8: {} 2461 | 2462 | which@2.0.2: 2463 | dependencies: 2464 | isexe: 2.0.0 2465 | 2466 | workerpool@6.2.1: {} 2467 | 2468 | wrap-ansi@7.0.0: 2469 | dependencies: 2470 | ansi-styles: 4.3.0 2471 | string-width: 4.2.3 2472 | strip-ansi: 6.0.1 2473 | 2474 | wrappy@1.0.2: {} 2475 | 2476 | ws@8.13.0: {} 2477 | 2478 | y18n@5.0.8: {} 2479 | 2480 | yallist@4.0.0: {} 2481 | 2482 | yargs-parser@20.2.4: {} 2483 | 2484 | yargs-unparser@2.0.0: 2485 | dependencies: 2486 | camelcase: 6.3.0 2487 | decamelize: 4.0.0 2488 | flat: 5.0.2 2489 | is-plain-obj: 2.1.0 2490 | 2491 | yargs@16.2.0: 2492 | dependencies: 2493 | cliui: 7.0.4 2494 | escalade: 3.1.1 2495 | get-caller-file: 2.0.5 2496 | require-directory: 2.1.1 2497 | string-width: 4.2.3 2498 | y18n: 5.0.8 2499 | yargs-parser: 20.2.4 2500 | 2501 | yocto-queue@0.1.0: {} 2502 | -------------------------------------------------------------------------------- /src/foldAnyWhereIndex.ts: -------------------------------------------------------------------------------- 1 | import { 2 | addIcon, 3 | App, 4 | ButtonComponent, 5 | debounce, 6 | Editor, 7 | editorInfoField, 8 | MarkdownView, 9 | Menu, 10 | MenuItem, 11 | Modal, 12 | Notice, 13 | Plugin, 14 | PluginSettingTab, 15 | Setting, 16 | TFile, 17 | } from "obsidian"; 18 | import { EditorView } from "@codemirror/view"; 19 | import FoldingExtension, { 20 | foldAll, 21 | unfoldAll, 22 | foldAllRegions, 23 | foldAllLineRegions, 24 | reconfigureFoldAnywhere, 25 | loadFoldAnyWhereSettings, 26 | foldRangesStateField, 27 | } from "./widgets/foldService"; 28 | import { foldAllPlugin } from "./widgets/foldMarkerWidget"; 29 | import { dealWithSelection, insertMark } from "./utils/line"; 30 | import { around } from "monkey-around"; 31 | import { foldEffect } from "@codemirror/language"; 32 | 33 | export interface FoldAnyWhereSettings { 34 | startMarker: string; 35 | endMarker: string; 36 | lineFoldMarker: string; 37 | lineFoldEndMarker: string; 38 | autoFoldOnLoad: boolean; 39 | } 40 | 41 | const DEFAULT_SETTINGS: FoldAnyWhereSettings = { 42 | startMarker: "%% REGION %%", 43 | endMarker: "%% ENDREGION %%", 44 | lineFoldMarker: "%% LINEFOLDSTART %%", 45 | lineFoldEndMarker: "%% LINEFOLDEND %%", 46 | autoFoldOnLoad: true, 47 | }; 48 | 49 | // Define interfaces for the fold info structure 50 | interface FoldRange { 51 | from: number; // line number 52 | to: number; // line number 53 | } 54 | 55 | interface AwFoldRange { 56 | awFoldFrom: number; 57 | awFoldTo: number; 58 | } 59 | 60 | interface FoldInfo { 61 | folds: FoldRange[]; 62 | lines: number; 63 | } 64 | 65 | interface FoldInfoWithAwFolds extends FoldInfo { 66 | awFolds: (AwFoldRange | FoldRange)[]; 67 | } 68 | 69 | // Type for editor view with showEditor method 70 | interface EditableView { 71 | editable: boolean; 72 | showEditor: () => void; 73 | unload: () => void; 74 | editMode: any; 75 | } 76 | 77 | export default class FoldAnyWherePlugin extends Plugin { 78 | settings: FoldAnyWhereSettings; 79 | private editorPatcher: (() => void) | null = null; 80 | 81 | async onload() { 82 | await this.loadSettings(); 83 | this.addSettingTab(new FoldAnywhereSettingTab(this.app, this)); 84 | this.registerIcons(); 85 | this.registerCommands(); 86 | this.registerContextMenu(); 87 | this.registerEditorExtension([ 88 | FoldingExtension, 89 | foldAllPlugin(this.app, this), 90 | loadFoldAnyWhereSettings(this.settings), 91 | ]); 92 | 93 | // Patch Obsidian's native folding methods 94 | this.patchObsidianFoldMethods(); 95 | 96 | this.app.workspace.onLayoutReady(() => { 97 | this.iterateCM6((view) => { 98 | view.dispatch({ 99 | effects: reconfigureFoldAnywhere(this.settings), 100 | }); 101 | 102 | // Auto-fold all regions on load if enabled 103 | if (this.settings.autoFoldOnLoad) { 104 | const currentSavedFolds = 105 | this.app.loadLocalStorage(`aw-folds`); 106 | 107 | if (currentSavedFolds) { 108 | const parsedFolds = JSON.parse(currentSavedFolds); 109 | 110 | const file = view.state.field(editorInfoField).file; 111 | 112 | console.log(parsedFolds, file); 113 | if (!file) return; 114 | const foldsOfFile = parsedFolds[file.path]; 115 | if (foldsOfFile) { 116 | for (const fold of foldsOfFile) { 117 | const realFold = { 118 | from: fold.awFoldFrom, 119 | to: fold.awFoldTo, 120 | }; 121 | view.dispatch({ 122 | effects: foldEffect.of(realFold), 123 | }); 124 | } 125 | } 126 | } else { 127 | foldAllRegions(view); 128 | } 129 | } 130 | }); 131 | 132 | // Also register an event to auto-fold regions when opening new files 133 | this.registerEvent( 134 | this.app.workspace.on("file-open", () => { 135 | // Only auto-fold if the setting is enabled 136 | if (this.settings.autoFoldOnLoad) { 137 | // Small delay to ensure editor is fully loaded 138 | setTimeout(() => { 139 | this.iterateCM6((view) => { 140 | foldAllRegions(view); 141 | }); 142 | }, 200); 143 | } 144 | }) 145 | ); 146 | }); 147 | } 148 | 149 | onunload() { 150 | // Uninstall any patches 151 | if (this.editorPatcher) { 152 | this.editorPatcher = null; 153 | } 154 | } 155 | 156 | /** 157 | * Patches Obsidian's native folding methods to handle inline folding 158 | */ 159 | patchObsidianFoldMethods() { 160 | try { 161 | // Create a temporary MarkdownView to access the editor prototype 162 | const tempViewEl = document.createElement("div"); 163 | // Using private Obsidian API - must use `any` type to access private properties 164 | const app = this.app as any; 165 | if (!app.embedRegistry) { 166 | console.warn( 167 | "Cannot patch folding methods: embedRegistry not found" 168 | ); 169 | return; 170 | } 171 | const tempView = app.embedRegistry.embedByExtension.md( 172 | { app: this.app, containerEl: tempViewEl }, 173 | null as unknown as TFile, 174 | "" 175 | ) as unknown as EditableView; 176 | // Ensure the view is editable 177 | if (tempView) { 178 | tempView.editable = true; 179 | tempView.showEditor(); 180 | // Get the editor prototype 181 | const editorPrototype = Object.getPrototypeOf( 182 | Object.getPrototypeOf(tempView.editMode) 183 | ); 184 | // Now patch the getFoldInfo and applyFoldInfo methods 185 | this.editorPatcher = around( 186 | editorPrototype.constructor.prototype, 187 | { 188 | getFoldInfo: (next) => { 189 | return function () { 190 | try { 191 | // Call the original method 192 | const foldInfo = next.apply(this); 193 | 194 | // Get awFolds from localStorage 195 | const awFolds: AwFoldRange[] = []; 196 | if (this.cm) { 197 | try { 198 | // Get current file path to use as key 199 | const currentFile = 200 | this.owner?.file?.path; 201 | const currentFoldRanges = 202 | this.cm.state.field( 203 | foldRangesStateField 204 | ); 205 | for (const fold of currentFoldRanges) { 206 | awFolds.push({ 207 | awFoldFrom: fold.from, 208 | awFoldTo: fold.to, 209 | }); 210 | } 211 | if (currentFile) { 212 | // First read existing fold data 213 | let allFolds = {}; 214 | const storedFolds = 215 | app.loadLocalStorage( 216 | `aw-folds` 217 | ); 218 | if (storedFolds) { 219 | try { 220 | allFolds = JSON.parse( 221 | storedFolds 222 | ) as Record< 223 | string, 224 | AwFoldRange[] 225 | >; 226 | } catch (e) { 227 | console.warn( 228 | "Error parsing stored folds:", 229 | e 230 | ); 231 | } 232 | } 233 | // Create fold data for current file 234 | const fileFolds = awFolds.map( 235 | (fold) => ({ 236 | awFoldFrom: 237 | fold.awFoldFrom, 238 | awFoldTo: fold.awFoldTo, 239 | }) 240 | ); 241 | 242 | // Update the map with current file's folds 243 | ( 244 | allFolds as Record< 245 | string, 246 | AwFoldRange[] 247 | > 248 | )[currentFile] = fileFolds; 249 | 250 | // Save all folds back to localStorage 251 | app.saveLocalStorage( 252 | `aw-folds`, 253 | JSON.stringify(allFolds) 254 | ); 255 | } 256 | } catch (storageError) { 257 | console.warn( 258 | "Error loading fold data from localStorage:", 259 | storageError 260 | ); 261 | } 262 | } 263 | 264 | // If we have any custom folds, add them to the result 265 | if (foldInfo && awFolds.length > 0) { 266 | // Filter out any folds that match our awFolds to avoid duplicates 267 | const newFolds = foldInfo.folds.filter( 268 | (fold: FoldRange) => { 269 | return !awFolds.some( 270 | (awFold) => { 271 | return ( 272 | this.cm.state.doc.lineAt( 273 | awFold.awFoldFrom 274 | ).number - 275 | 1 === 276 | fold.from && 277 | this.cm.state.doc.lineAt( 278 | awFold.awFoldTo 279 | ).number - 280 | 1 === 281 | fold.to 282 | ); 283 | } 284 | ); 285 | } 286 | ); 287 | // Add our awFolds to the final result 288 | foldInfo.folds = [...newFolds]; 289 | } 290 | 291 | return foldInfo; 292 | } catch (error) { 293 | console.warn( 294 | "Error in getFoldInfo, providing fallback:", 295 | error 296 | ); 297 | // Return null as a fallback when an error occurs 298 | return null; 299 | } 300 | }; 301 | }, 302 | applyFoldInfo: (next) => { 303 | return function (e: FoldInfoWithAwFolds | null) { 304 | // Only proceed if we have valid fold info 305 | if (!e) return; 306 | try { 307 | // Call the original method with our sanitized data 308 | const result = next.apply(this, [ 309 | e.folds.filter((fold) => { 310 | return !("awFoldFrom" in fold); 311 | }), 312 | ]); 313 | 314 | const codemirror: EditorView = this.cm; 315 | 316 | // After applying folds, also collect all active awFolds 317 | try { 318 | if (codemirror) { 319 | try { 320 | // Save the fold data to localStorage 321 | const currentFile = 322 | this.owner?.file?.path; 323 | if (currentFile) { 324 | // First read existing fold data 325 | 326 | const storedFolds = 327 | app.loadLocalStorage( 328 | `aw-folds` 329 | ); 330 | 331 | if (storedFolds) { 332 | try { 333 | const parsedFolds = 334 | JSON.parse( 335 | storedFolds 336 | ); 337 | 338 | // Check if the file exists in the stored folds 339 | if ( 340 | parsedFolds[ 341 | currentFile 342 | ] 343 | ) { 344 | // Get the folds for the current file 345 | const fileFolds = 346 | parsedFolds[ 347 | currentFile 348 | ]; 349 | for (const fold of fileFolds) { 350 | this.cm.dispatch( 351 | { 352 | effects: 353 | [ 354 | foldEffect.of( 355 | { 356 | from: fold.awFoldFrom as number, 357 | to: fold.awFoldTo as number, 358 | } 359 | ), 360 | ], 361 | } 362 | ); 363 | } 364 | } 365 | } catch (parseError) { 366 | console.warn( 367 | "Error parsing fold data:", 368 | parseError 369 | ); 370 | } 371 | } 372 | } 373 | } catch (rangeError) { 374 | console.warn( 375 | "Error applying plugin fold ranges:", 376 | rangeError 377 | ); 378 | } 379 | } 380 | } catch (awError) { 381 | console.warn( 382 | "Error handling awFolds:", 383 | awError 384 | ); 385 | } 386 | 387 | return result; 388 | } catch (error) { 389 | console.warn( 390 | "Error in applyFoldInfo:", 391 | error 392 | ); 393 | // Don't proceed when an error occurs 394 | return; 395 | } 396 | }; 397 | }, 398 | } 399 | ); 400 | // Clean up the temporary view 401 | tempView.unload(); 402 | tempViewEl.remove(); 403 | this.register(this.editorPatcher); 404 | } 405 | } catch (error) { 406 | console.error("Failed to patch Obsidian folding methods:", error); 407 | } 408 | } 409 | 410 | registerIcons() { 411 | addIcon( 412 | "fold-horizontal", 413 | `` 414 | ); 415 | } 416 | 417 | registerCommands() { 418 | this.addCommand({ 419 | id: "fold-current-range", 420 | name: "Fold between start and end marks", 421 | editorCallback: (editor: Editor) => { 422 | const editorView = (editor as any).cm; 423 | foldAll(editorView); 424 | }, 425 | }); 426 | 427 | this.addCommand({ 428 | id: "unfold-current-range", 429 | name: "Unfold between start and end marks", 430 | editorCallback: (editor: Editor) => { 431 | const editorView = (editor as any).cm; 432 | unfoldAll(editorView); 433 | }, 434 | }); 435 | 436 | this.addCommand({ 437 | id: "fold-all-regions", 438 | name: "Fold all regions in file", 439 | editorCallback: (editor: Editor) => { 440 | const editorView = (editor as any).cm; 441 | foldAllRegions(editorView); 442 | }, 443 | }); 444 | 445 | this.addCommand({ 446 | id: "fold-selected-text", 447 | name: "Fold selected text", 448 | editorCallback: (editor: Editor) => 449 | dealWithSelection(this.settings, editor), 450 | }); 451 | 452 | this.addCommand({ 453 | id: "mark-as-start", 454 | name: "Mark as start", 455 | editorCallback: (editor: Editor) => 456 | insertMark(editor, this.settings.startMarker), 457 | }); 458 | 459 | this.addCommand({ 460 | id: "mark-as-line-fold", 461 | name: "Mark as line fold", 462 | editorCallback: (editor: Editor) => 463 | insertMark(editor, this.settings.lineFoldMarker), 464 | }); 465 | 466 | this.addCommand({ 467 | id: "mark-as-end", 468 | name: "Mark as end", 469 | editorCallback: (editor: Editor) => 470 | insertMark(editor, this.settings.endMarker), 471 | }); 472 | 473 | this.addCommand({ 474 | id: "remove-all-markers", 475 | name: "Remove All Markers In Current File", 476 | // Using callback instead of checkCallback because we want to using async/await 477 | callback: async () => { 478 | const markdownView = 479 | this.app.workspace.getActiveViewOfType(MarkdownView); 480 | if (markdownView) { 481 | const file = markdownView.file; 482 | if (!file) return; 483 | let ready = false; 484 | new AskModal(this.app, async (already: boolean) => { 485 | ready = already; 486 | if (ready) { 487 | const fileContent = await this.app.vault.cachedRead( 488 | file 489 | ); 490 | const startMarker = this.settings.startMarker; 491 | const endMarker = this.settings.endMarker; 492 | 493 | const regex = new RegExp( 494 | `(\\s)?${startMarker}|(\\s)?${endMarker}`, 495 | "g" 496 | ); 497 | const newFileContent = fileContent.replace( 498 | regex, 499 | "" 500 | ); 501 | await this.app.vault.modify(file, newFileContent); 502 | } 503 | }).open(); 504 | return; 505 | } 506 | new Notice("No active file open"); 507 | }, 508 | }); 509 | 510 | this.addCommand({ 511 | id: "fold-anywhere-fold-all-line-regions", 512 | name: "Fold all line regions", 513 | editorCallback: (editor: Editor) => { 514 | const view = (editor as any).cm as EditorView; 515 | foldAllLineRegions(view); 516 | }, 517 | }); 518 | } 519 | 520 | registerContextMenu() { 521 | this.registerEvent( 522 | this.app.workspace.on( 523 | "editor-menu", 524 | (menu: Menu, editor: Editor) => { 525 | if (!editor) { 526 | return; 527 | } 528 | const selection = editor.getSelection(); 529 | 530 | menu.addItem((item: MenuItem) => { 531 | // Create a submenu 532 | const subMenu = new Menu(); 533 | 534 | // Add items to the submenu 535 | if (selection) { 536 | subMenu.addItem((subItem: MenuItem) => 537 | subItem 538 | .setTitle("Fold selected text") 539 | .setIcon("fold-horizontal") 540 | .onClick(async () => { 541 | dealWithSelection( 542 | this.settings, 543 | editor 544 | ); 545 | }) 546 | ); 547 | } 548 | 549 | subMenu.addItem((subItem: MenuItem) => 550 | subItem 551 | .setTitle("Mark as start") 552 | .setIcon("fold-horizontal") 553 | .onClick(async () => { 554 | insertMark( 555 | editor, 556 | this.settings.startMarker 557 | ); 558 | }) 559 | ); 560 | 561 | subMenu.addItem((subItem: MenuItem) => 562 | subItem 563 | .setTitle("Mark as line fold") 564 | .setIcon("fold-horizontal") 565 | .onClick(async () => { 566 | insertMark( 567 | editor, 568 | this.settings.lineFoldMarker 569 | ); 570 | }) 571 | ); 572 | 573 | subMenu.addItem((subItem: MenuItem) => 574 | subItem 575 | .setTitle("Mark as end") 576 | .setIcon("fold-horizontal") 577 | .onClick(async () => { 578 | insertMark(editor, this.settings.endMarker); 579 | }) 580 | ); 581 | 582 | // Set up the main menu item to show the submenu 583 | item.setSection("action") 584 | .setTitle(`Fold anywhere`) 585 | .setIcon("chevrons-right-left") 586 | .onClick(() => { 587 | // Just show the submenu at a default position 588 | const position = { x: 0, y: 0 }; 589 | 590 | // Get mouse position if possible 591 | const mouseEvent = 592 | this.app.workspace.containerEl 593 | .querySelector(".menu") 594 | ?.getBoundingClientRect(); 595 | if (mouseEvent) { 596 | position.x = mouseEvent.left; 597 | position.y = mouseEvent.bottom; 598 | } 599 | 600 | subMenu.showAtPosition(position); 601 | }); 602 | }); 603 | } 604 | ) 605 | ); 606 | } 607 | 608 | // Iterate through all MarkdownView leaves and execute a callback function on each 609 | iterateCM6(callback: (editor: EditorView) => unknown) { 610 | this.app.workspace.iterateAllLeaves((leaf) => { 611 | leaf?.view instanceof MarkdownView && 612 | (leaf.view.editor as any)?.cm instanceof EditorView && 613 | callback((leaf.view.editor as any).cm); 614 | }); 615 | } 616 | 617 | public async loadSettings() { 618 | this.settings = Object.assign( 619 | {}, 620 | DEFAULT_SETTINGS, 621 | await this.loadData() 622 | ); 623 | } 624 | 625 | async saveSettings() { 626 | await this.saveData(this.settings); 627 | 628 | // Update settings in all editor instances using the state effect 629 | this.iterateCM6((view) => { 630 | view.dispatch({ 631 | effects: reconfigureFoldAnywhere(this.settings), 632 | }); 633 | }); 634 | } 635 | } 636 | 637 | class AskModal extends Modal { 638 | private cb: (ready: boolean) => Promise; 639 | 640 | constructor(app: App, cb: (ready: boolean) => Promise) { 641 | super(app); 642 | this.cb = cb; 643 | } 644 | 645 | onOpen() { 646 | let { contentEl } = this; 647 | contentEl.toggleClass("fold-anywhere-ask-modal", true); 648 | contentEl.createEl("div", { text: "Are you sure?" }); 649 | const buttonContainer = contentEl.createDiv({ 650 | cls: "button-container", 651 | }); 652 | 653 | new ButtonComponent(buttonContainer) 654 | .setClass("remove-ready") 655 | .setWarning() 656 | .setButtonText("Yes") 657 | .onClick(async () => { 658 | await this.cb(true); 659 | this.close(); 660 | }); 661 | new ButtonComponent(buttonContainer) 662 | .setClass("do-not-remove") 663 | .setButtonText("No") 664 | .onClick(async () => { 665 | await this.cb(false); 666 | this.close(); 667 | }); 668 | } 669 | } 670 | 671 | export class FoldAnywhereSettingTab extends PluginSettingTab { 672 | plugin: FoldAnyWherePlugin; 673 | 674 | constructor(app: App, plugin: FoldAnyWherePlugin) { 675 | super(app, plugin); 676 | this.plugin = plugin; 677 | } 678 | 679 | debounceApplySettingsUpdate = debounce( 680 | async () => { 681 | await this.plugin.saveSettings(); 682 | }, 683 | 200, 684 | true 685 | ); 686 | 687 | debounceDisplay = debounce( 688 | async () => { 689 | await this.display(); 690 | }, 691 | 400, 692 | true 693 | ); 694 | 695 | applySettingsUpdate() { 696 | this.debounceApplySettingsUpdate(); 697 | } 698 | 699 | async display() { 700 | await this.plugin.loadSettings(); 701 | 702 | const { containerEl } = this; 703 | const settings = this.plugin.settings; 704 | 705 | containerEl.empty(); 706 | 707 | new Setting(containerEl) 708 | .setName("Fold anywhere start marker") 709 | .addText((text) => 710 | text.setValue(settings.startMarker).onChange(async (value) => { 711 | settings.startMarker = value; 712 | this.applySettingsUpdate(); 713 | }) 714 | ); 715 | 716 | new Setting(containerEl) 717 | .setName("Fold anywhere end marker") 718 | .addText((text) => 719 | text.setValue(settings.endMarker).onChange(async (value) => { 720 | settings.endMarker = value; 721 | this.applySettingsUpdate(); 722 | }) 723 | ); 724 | 725 | new Setting(containerEl) 726 | .setName("Line fold start marker") 727 | .addText((text) => 728 | text 729 | .setValue(settings.lineFoldMarker) 730 | .onChange(async (value) => { 731 | settings.lineFoldMarker = value; 732 | this.applySettingsUpdate(); 733 | }) 734 | ); 735 | 736 | new Setting(containerEl) 737 | .setName("Line fold end marker") 738 | .addText((text) => 739 | text 740 | .setValue(settings.lineFoldEndMarker) 741 | .onChange(async (value) => { 742 | settings.lineFoldEndMarker = value; 743 | this.applySettingsUpdate(); 744 | }) 745 | ); 746 | 747 | new Setting(containerEl) 748 | .setName("Auto-fold regions on load") 749 | .setDesc("Automatically fold all regions when opening files") 750 | .addToggle((toggle) => 751 | toggle 752 | .setValue(settings.autoFoldOnLoad) 753 | .onChange(async (value) => { 754 | settings.autoFoldOnLoad = value; 755 | this.applySettingsUpdate(); 756 | }) 757 | ); 758 | } 759 | } 760 | -------------------------------------------------------------------------------- /src/types/obsidian.d.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 2 | import * as obsidian from 'obsidian'; 3 | 4 | declare module "obsidian" { 5 | interface Editor { 6 | cm: any; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/typings/lodash.d.ts: -------------------------------------------------------------------------------- 1 | declare module "lodash" { 2 | export function cloneDeep(value: T): T; 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/line.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from "obsidian"; 2 | import { foldAll } from "../widgets/foldService"; 3 | import { FoldAnyWhereSettings } from "../foldAnyWhereIndex"; 4 | 5 | type InsertMarkType = "start" | "end"; 6 | 7 | const MARKLIST = { 8 | start: "%% REGION %%", 9 | end: "%% ENDREGION %%", 10 | }; 11 | const BLOCK_ID_REGEX = /\^[a-zA-Z0-9\-]{1,6}$/g; 12 | 13 | const checkStartOrEnd = (editor: Editor) => { 14 | const fromCursor = editor.getCursor("from"); 15 | const toCursor = editor.getCursor("to"); 16 | 17 | const lineStart = 18 | fromCursor.ch === 0 || 19 | editor.getLine(fromCursor.line).charAt(fromCursor.ch - 1) === " "; 20 | const lineEnd = 21 | toCursor.ch === editor.getLine(toCursor.line).length || 22 | editor.getLine(toCursor.line).charAt(toCursor.ch) === " "; 23 | 24 | return { lineStart, lineEnd, toCursor }; 25 | }; 26 | 27 | const insertEndMarkBeforeBlockID = (content: string, end: string) => { 28 | const match = content.match(BLOCK_ID_REGEX); 29 | if (match) { 30 | return content.replace(BLOCK_ID_REGEX, `${end} ${match[0]}`); 31 | } else { 32 | return content + ` ${end}`; 33 | } 34 | }; 35 | 36 | export const dealWithSelection = ( 37 | insert: FoldAnyWhereSettings, 38 | editor: Editor 39 | ) => { 40 | const selection = editor.getSelection(); 41 | if (selection.trim().length === 0) return; 42 | 43 | const { lineStart, lineEnd, toCursor } = checkStartOrEnd(editor); 44 | 45 | editor.replaceSelection( 46 | (lineStart ? `` : ` `) + 47 | `${insert.startMarker} ${insertEndMarkBeforeBlockID( 48 | selection.trim(), 49 | insert.endMarker 50 | )}` + 51 | (lineEnd ? `` : ` `) 52 | ); 53 | editor.setCursor(toCursor.line, toCursor.ch + 14); 54 | 55 | foldAll((editor as any).cm); 56 | }; 57 | 58 | export const insertMark = (editor: Editor, marker: string) => { 59 | const selection = editor.getSelection(); 60 | if (selection.trim().length > 0) return; 61 | 62 | const { lineStart, lineEnd } = checkStartOrEnd(editor); 63 | editor.replaceSelection( 64 | (lineStart ? `` : ` `) + marker + (lineEnd ? ` ` : ` `) 65 | ); 66 | }; 67 | -------------------------------------------------------------------------------- /src/widgets/foldMarkerWidget.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Decoration, 3 | DecorationSet, 4 | EditorView, 5 | MatchDecorator, 6 | ViewPlugin, 7 | ViewUpdate, 8 | WidgetType, 9 | } from "@codemirror/view"; 10 | import { App, editorLivePreviewField, Menu, setIcon } from "obsidian"; 11 | import { foldAll } from "./foldService"; 12 | import FoldAnyWherePlugin from "../foldAnyWhereIndex"; 13 | 14 | type MarkType = "fold" | "unfold"; 15 | 16 | class FoldMarkWidget extends WidgetType { 17 | isFolded: boolean; 18 | 19 | constructor( 20 | readonly app: App, 21 | readonly view: EditorView, 22 | readonly from: number, 23 | readonly to: number, 24 | readonly markType: MarkType = "fold", 25 | isFolded: boolean = false 26 | ) { 27 | super(); 28 | this.isFolded = isFolded; 29 | } 30 | 31 | eq(other: FoldMarkWidget) { 32 | return ( 33 | other.view === this.view && 34 | other.from === this.from && 35 | other.to === this.to 36 | ); 37 | } 38 | 39 | toDOM() { 40 | const creaseEl = createSpan("cm-fold-anywhere-icon"); 41 | const iconEl = creaseEl.createSpan( 42 | this.markType === "fold" ? "fold-start" : "fold-end" 43 | ); 44 | 45 | let title: string, icon: string; 46 | if (this.markType === "fold") { 47 | title = "Remove fold start mark"; 48 | icon = this.isFolded ? "goal" : "chevron-last"; 49 | } else { 50 | title = "Remove fold end mark"; 51 | icon = "chevron-first"; 52 | } 53 | setIcon(iconEl, icon); 54 | 55 | creaseEl.addEventListener("click", (evt) => { 56 | if (evt.ctrlKey || evt.metaKey) { 57 | const menu = new Menu(); 58 | menu.addItem((item) => 59 | item 60 | .setTitle(title) 61 | .setIcon("x") 62 | .onClick(() => { 63 | this.view.dispatch({ 64 | changes: { 65 | from: this.from, 66 | to: this.to, 67 | insert: "", 68 | }, 69 | }); 70 | }) 71 | ).showAtMouseEvent(evt); 72 | return; 73 | } 74 | this.view.dispatch({ 75 | selection: { 76 | anchor: 77 | (this.markType === "fold" ? this.to : this.from) || 0, 78 | head: (this.markType === "fold" ? this.to : this.from) || 0, 79 | }, 80 | }); 81 | foldAll(this.view); 82 | }); 83 | 84 | return creaseEl; 85 | } 86 | 87 | ignoreEvent(event: Event) { 88 | return false; 89 | } 90 | } 91 | 92 | export function foldAllPlugin(app: App, plugin: FoldAnyWherePlugin) { 93 | return ViewPlugin.fromClass( 94 | class { 95 | decorations: DecorationSet = Decoration.none; 96 | allDecos: DecorationSet = Decoration.none; 97 | decorator: MatchDecorator; 98 | 99 | constructor(public view: EditorView) { 100 | const regex = new RegExp( 101 | `((?${plugin.settings.startMarker})|(?${plugin.settings.endMarker}))`, 102 | "g" 103 | ); 104 | this.decorator = new MatchDecorator({ 105 | regexp: regex, 106 | decoration: this.getDeco.bind(this), 107 | }); 108 | this.decorations = this.decorator.createDeco(view); 109 | } 110 | 111 | getDeco(match: RegExpExecArray, _view: EditorView, pos: number) { 112 | const from = pos; 113 | const to = pos + match[0].length; 114 | 115 | return Decoration.replace({ 116 | widget: new FoldMarkWidget( 117 | app, 118 | this.view, 119 | from, 120 | to, 121 | match.groups?.START ? "fold" : "unfold" 122 | ), 123 | }); 124 | } 125 | 126 | update(update: ViewUpdate) { 127 | if (!update.state.field(editorLivePreviewField)) { 128 | this.decorations = Decoration.none; 129 | return; 130 | } 131 | 132 | this.decorations = this.decorator.updateDeco( 133 | update, 134 | this.decorations 135 | ); 136 | } 137 | }, 138 | { 139 | decorations: (v) => v.decorations, 140 | provide: (plugin) => 141 | EditorView.atomicRanges.of((view) => { 142 | return view.plugin(plugin)?.decorations || Decoration.none; 143 | }), 144 | } 145 | ); 146 | } 147 | -------------------------------------------------------------------------------- /src/widgets/foldService.ts: -------------------------------------------------------------------------------- 1 | import { 2 | codeFolding, 3 | foldEffect, 4 | foldService, 5 | unfoldEffect, 6 | foldState, 7 | } from "@codemirror/language"; 8 | import { 9 | combineConfig, 10 | Compartment, 11 | EditorState, 12 | Extension, 13 | Facet, 14 | StateEffect, 15 | StateField, 16 | } from "@codemirror/state"; 17 | import { EditorView } from "@codemirror/view"; 18 | import { FoldAnyWhereSettings } from "../foldAnyWhereIndex"; 19 | import { cloneDeep } from "lodash"; 20 | 21 | // Define the Facet for plugin settings 22 | export const FoldAnywhereConfigFacet = Facet.define< 23 | FoldAnyWhereSettings, 24 | Required 25 | >({ 26 | combine(settings: readonly FoldAnyWhereSettings[]) { 27 | const defaultSettings: FoldAnyWhereSettings = { 28 | startMarker: "%% REGION %%", 29 | endMarker: "%% ENDREGION %%", 30 | lineFoldMarker: "%% LINEFOLDSTART %%", 31 | lineFoldEndMarker: "%% LINEFOLDEND %%", 32 | autoFoldOnLoad: true, 33 | }; 34 | 35 | return combineConfig(settings, defaultSettings, { 36 | startMarker: (a, b) => b || a, 37 | endMarker: (a, b) => b || a, 38 | lineFoldMarker: (a, b) => b || a, 39 | lineFoldEndMarker: (a, b) => b || a, 40 | }); 41 | }, 42 | }); 43 | 44 | export const foldRangesStateField = StateField.define< 45 | { from: number; to: number }[] 46 | >({ 47 | create: () => [], 48 | update(value, tr) { 49 | // If document changed, recalculate all fold ranges 50 | if ( 51 | !tr.effects.some((effect) => effect.is(foldEffect)) && 52 | !tr.effects.some((effect) => effect.is(unfoldEffect)) 53 | ) { 54 | return value; 55 | } 56 | 57 | // Check for fold/unfold effects and update accordingly 58 | for (const effect of tr.effects) { 59 | if (effect.is(foldEffect)) { 60 | // Add new fold range if it doesn't already exist 61 | const range = effect.value; 62 | 63 | // Check if this range exists in the foldable ranges 64 | const allFoldableRanges = getAllFoldableRanges(tr.state); 65 | const isValidRange = allFoldableRanges.some( 66 | (r) => r.from === range.from && r.to === range.to 67 | ); 68 | 69 | if ( 70 | isValidRange && 71 | !value.some( 72 | (r) => r.from === range.from && r.to === range.to 73 | ) 74 | ) { 75 | value = [...value, range]; 76 | } 77 | } else if (effect.is(unfoldEffect)) { 78 | // Remove fold range if it exists 79 | const range = effect.value; 80 | value = value.filter( 81 | (r) => !(r.from === range.from && r.to === range.to) 82 | ); 83 | } 84 | } 85 | 86 | return value; 87 | }, 88 | }); 89 | 90 | // Create a Compartment for reconfiguration 91 | export const FoldAnywhereCompartment = new Compartment(); 92 | 93 | // Helper function to reconfigure the extension with new settings 94 | export function reconfigureFoldAnywhere(settings: FoldAnyWhereSettings) { 95 | return FoldAnywhereCompartment.reconfigure( 96 | FoldAnywhereConfigFacet.of(cloneDeep(settings)) 97 | ); 98 | } 99 | 100 | function createFoldRangesFromCurrentPOS( 101 | state: EditorState, 102 | currentPos: number 103 | ): { 104 | from: number; 105 | to: number; 106 | }[] { 107 | // Get settings from the state using the Facet 108 | const settings = state.facet(FoldAnywhereConfigFacet); 109 | 110 | const startRegex = new RegExp(settings.startMarker, "g"); 111 | const endRegex = new RegExp(settings.endMarker, "g"); 112 | const lineFoldStartRegex = new RegExp( 113 | settings.lineFoldMarker + "\\s*$", 114 | "g" 115 | ); 116 | const lineFoldEndRegex = new RegExp( 117 | settings.lineFoldEndMarker + "\\s*$", 118 | "g" 119 | ); 120 | 121 | let ranges: { from: number; to: number }[] = []; 122 | let startStack: { pos: number; depth: number; isLineFold: boolean }[] = []; 123 | let depth = 0; 124 | 125 | // Check if cursor is on a line with line fold marker 126 | const currentLine = state.doc.lineAt(currentPos); 127 | lineFoldStartRegex.lastIndex = 0; 128 | lineFoldEndRegex.lastIndex = 0; 129 | const lineFoldStartMatch = lineFoldStartRegex.exec(currentLine.text); 130 | const lineFoldEndMatch = lineFoldEndRegex.exec(currentLine.text); 131 | 132 | if (lineFoldStartMatch) { 133 | // Calculate the position of the marker 134 | const markerPos = currentLine.from + lineFoldStartMatch.index; 135 | 136 | // Find the next line with a line fold marker 137 | for (let i = currentLine.number + 1; i <= state.doc.lines; i++) { 138 | const nextLine = state.doc.line(i); 139 | lineFoldStartRegex.lastIndex = 0; 140 | lineFoldEndRegex.lastIndex = 0; 141 | let nextLineFoldStartMatch = lineFoldStartRegex.exec(nextLine.text); 142 | let nextLineFoldEndMatch = lineFoldEndRegex.exec(nextLine.text); 143 | if (nextLineFoldStartMatch && nextLineFoldEndMatch) { 144 | // Found matching line fold marker 145 | ranges.push({ 146 | from: markerPos, // From the position of the first marker 147 | to: nextLine.to, // To the end of the line with the second marker 148 | }); 149 | return ranges; 150 | } 151 | } 152 | } 153 | 154 | // Find all regular fold regions in the document 155 | for (let i = 1; i <= state.doc.lines; i++) { 156 | const line = state.doc.line(i); 157 | 158 | // Reset regular expressions 159 | startRegex.lastIndex = 0; 160 | endRegex.lastIndex = 0; 161 | 162 | // First, collect all markers in this line in order 163 | interface Marker { 164 | type: "start" | "end"; 165 | pos: number; 166 | length: number; 167 | } 168 | 169 | let markers: Marker[] = []; 170 | 171 | // Get start markers 172 | let startMatch; 173 | while ((startMatch = startRegex.exec(line.text)) !== null) { 174 | markers.push({ 175 | type: "start", 176 | pos: line.from + startMatch.index, 177 | length: startMatch[0].length, 178 | }); 179 | } 180 | 181 | // Get end markers 182 | let endMatch; 183 | while ((endMatch = endRegex.exec(line.text)) !== null) { 184 | markers.push({ 185 | type: "end", 186 | pos: line.from + endMatch.index, 187 | length: endMatch[0].length, 188 | }); 189 | } 190 | 191 | // Sort markers by position 192 | markers.sort((a, b) => a.pos - b.pos); 193 | 194 | // Process markers in order 195 | for (const marker of markers) { 196 | if (marker.type === "start") { 197 | // Push start position onto stack with current depth 198 | startStack.push({ 199 | pos: marker.pos, 200 | depth: depth, 201 | isLineFold: false, 202 | }); 203 | depth++; 204 | } else if (marker.type === "end" && startStack.length > 0) { 205 | // Decrement depth 206 | depth--; 207 | 208 | // Find the matching start with the current depth 209 | const startIndex = startStack.findIndex( 210 | (item) => item.depth === depth 211 | ); 212 | 213 | if (startIndex !== -1) { 214 | const startInfo = startStack[startIndex]; 215 | 216 | // Add range only if cursor is within this range 217 | const endPos = marker.pos + marker.length; 218 | 219 | // Regular fold - check if cursor is within range 220 | if (startInfo.pos < currentPos && endPos > currentPos) { 221 | ranges.push({ from: startInfo.pos, to: endPos }); 222 | } 223 | 224 | // Remove this start marker and any after it (which would be unpaired) 225 | startStack.splice(startIndex); 226 | } 227 | } 228 | } 229 | } 230 | 231 | // Sort ranges by size (smallest first) 232 | ranges.sort((a, b) => a.to - a.from - (b.to - b.from)); 233 | 234 | // Return the smallest range that contains the cursor 235 | return ranges.length > 0 ? [ranges[0]] : []; 236 | } 237 | 238 | function findMatchingFoldRange( 239 | state: EditorState, 240 | currentPos: number 241 | ): { from: number; to: number } | null { 242 | // Get settings from the state using the Facet 243 | const settings = state.facet(FoldAnywhereConfigFacet); 244 | 245 | const startRegex = new RegExp(settings.startMarker, "g"); 246 | const endRegex = new RegExp(settings.endMarker, "g"); 247 | const lineFoldStartRegex = new RegExp( 248 | settings.lineFoldMarker + "\\s*$", 249 | "g" 250 | ); 251 | const lineFoldEndRegex = new RegExp( 252 | settings.lineFoldEndMarker + "\\s*$", 253 | "g" 254 | ); 255 | 256 | let startStack: { pos: number; isLineFold: boolean }[] = []; 257 | let cursorStartPos: number | null = null; 258 | let isLineFold = false; 259 | let currentLine = state.doc.lineAt(currentPos); 260 | 261 | // Check if cursor is on a start marker 262 | startRegex.lastIndex = 0; 263 | let startMatch; 264 | let cursorOnStartMark = false; 265 | while ((startMatch = startRegex.exec(currentLine.text)) !== null) { 266 | const startPos = currentLine.from + startMatch.index; 267 | if ( 268 | startPos <= currentPos && 269 | currentPos <= startPos + startMatch[0].length 270 | ) { 271 | cursorStartPos = startPos; 272 | cursorOnStartMark = true; 273 | isLineFold = false; 274 | break; 275 | } 276 | } 277 | 278 | // Check if cursor is on a line with a lineFold marker at the end 279 | if (!cursorOnStartMark) { 280 | lineFoldStartRegex.lastIndex = 0; 281 | let lineFoldMatch = lineFoldStartRegex.exec(currentLine.text); 282 | if (lineFoldMatch) { 283 | // Calculate the position of the marker 284 | const markerPos = currentLine.from + lineFoldMatch.index; 285 | 286 | // Find the next line with a line fold end marker 287 | for (let i = currentLine.number + 1; i <= state.doc.lines; i++) { 288 | const nextLine = state.doc.line(i); 289 | lineFoldEndRegex.lastIndex = 0; 290 | let nextMatch = lineFoldEndRegex.exec(nextLine.text); 291 | if (nextMatch) { 292 | // Found matching line fold end marker 293 | return { 294 | from: markerPos, // Start from the marker position, not end of line 295 | to: nextLine.to, // End at the end of the matched line, not the beginning 296 | }; 297 | } 298 | } 299 | } 300 | } 301 | 302 | // If cursor isn't on a start marker, no fold can be done 303 | if (!cursorOnStartMark || cursorStartPos === null) { 304 | return null; 305 | } 306 | 307 | // Initialize stack with our current start marker 308 | startStack.push({ pos: cursorStartPos, isLineFold }); 309 | 310 | // Start from the current line and search for matching end marker 311 | for (let i = currentLine.number; i <= state.doc.lines; i++) { 312 | const line = state.doc.line(i); 313 | 314 | // Check for additional start markers (including the rest on the current line) 315 | startRegex.lastIndex = 0; 316 | if (i === currentLine.number) { 317 | // On the current line, only consider start markers after our cursor position 318 | while ((startMatch = startRegex.exec(line.text)) !== null) { 319 | const startPos = line.from + startMatch.index; 320 | if (startPos > cursorStartPos) { 321 | startStack.push({ pos: startPos, isLineFold: false }); 322 | } 323 | } 324 | } else { 325 | // On subsequent lines, consider all start markers 326 | while ((startMatch = startRegex.exec(line.text)) !== null) { 327 | startStack.push({ 328 | pos: line.from + startMatch.index, 329 | isLineFold: false, 330 | }); 331 | } 332 | } 333 | 334 | // Check for EndMark 335 | endRegex.lastIndex = 0; 336 | let endMatch; 337 | while ((endMatch = endRegex.exec(line.text)) !== null) { 338 | let endPosition = line.from + endMatch.index + endMatch[0].length; 339 | 340 | // If there's a start in the stack, match it 341 | if (startStack.length > 0) { 342 | // Get the most recent start position 343 | const startInfo = startStack.pop()!; 344 | 345 | // If this was our cursor's start position, we've found our match 346 | if (startInfo.pos === cursorStartPos) { 347 | return { from: startInfo.pos, to: endPosition }; 348 | } 349 | } 350 | } 351 | } 352 | 353 | return null; // If no matching range is found, return null 354 | } 355 | 356 | export function getAllFoldableRanges( 357 | state: EditorState 358 | ): { from: number; to: number }[] { 359 | // Get settings from the state using the Facet 360 | const settings = state.facet(FoldAnywhereConfigFacet); 361 | 362 | const startRegex = new RegExp(settings.startMarker, "g"); 363 | const endRegex = new RegExp(settings.endMarker, "g"); 364 | const lineFoldStartRegex = new RegExp( 365 | settings.lineFoldMarker + "\\s*$", 366 | "g" 367 | ); 368 | const lineFoldEndRegex = new RegExp( 369 | settings.lineFoldEndMarker + "\\s*$", 370 | "g" 371 | ); 372 | 373 | let ranges: { from: number; to: number }[] = []; 374 | let startStack: { pos: number; depth: number; isLineFold: boolean }[] = []; 375 | let lineFoldMarkerPositions: { lineNum: number; pos: number }[] = []; // Track line numbers and positions with line fold markers 376 | let depth = 0; 377 | 378 | for (let i = 1; i <= state.doc.lines; i++) { 379 | const line = state.doc.line(i); 380 | 381 | // Reset regular expressions 382 | startRegex.lastIndex = 0; 383 | endRegex.lastIndex = 0; 384 | lineFoldStartRegex.lastIndex = 0; 385 | lineFoldEndRegex.lastIndex = 0; 386 | 387 | // Check for lineFold start marker at the end of the line 388 | let lineFoldStartMatch = lineFoldStartRegex.exec(line.text); 389 | if (lineFoldStartMatch) { 390 | // Calculate the actual position of the marker 391 | const markerPos = line.from + lineFoldStartMatch.index; 392 | 393 | // Add to stack of line fold markers 394 | lineFoldMarkerPositions.push({ lineNum: i, pos: markerPos }); 395 | } 396 | 397 | // Check for lineFold end marker 398 | let lineFoldEndMatch = lineFoldEndRegex.exec(line.text); 399 | if (lineFoldEndMatch && lineFoldMarkerPositions.length > 0) { 400 | // Get the most recent line fold start marker 401 | const startInfo = lineFoldMarkerPositions.pop()!; 402 | 403 | // Add range from the start marker position to the end of the current line 404 | ranges.push({ 405 | from: startInfo.pos, 406 | to: line.to, 407 | }); 408 | } 409 | 410 | // First, collect all regular markers in this line 411 | interface Marker { 412 | type: "start" | "end"; 413 | pos: number; 414 | length: number; 415 | } 416 | 417 | let markers: Marker[] = []; 418 | 419 | // Get start markers 420 | let startMatch; 421 | while ((startMatch = startRegex.exec(line.text)) !== null) { 422 | markers.push({ 423 | type: "start", 424 | pos: line.from + startMatch.index, 425 | length: startMatch[0].length, 426 | }); 427 | } 428 | 429 | // Get end markers 430 | let endMatch; 431 | while ((endMatch = endRegex.exec(line.text)) !== null) { 432 | markers.push({ 433 | type: "end", 434 | pos: line.from + endMatch.index, 435 | length: endMatch[0].length, 436 | }); 437 | } 438 | 439 | // Sort markers by position 440 | markers.sort((a, b) => a.pos - b.pos); 441 | 442 | // Process markers in order 443 | for (const marker of markers) { 444 | if (marker.type === "start") { 445 | // Push start position onto stack with current depth 446 | startStack.push({ 447 | pos: marker.pos, 448 | depth: depth, 449 | isLineFold: false, 450 | }); 451 | depth++; 452 | } else if (marker.type === "end" && startStack.length > 0) { 453 | // Decrement depth 454 | depth--; 455 | 456 | // Find the matching start with the current depth 457 | const startIndex = startStack.findIndex( 458 | (item) => item.depth === depth 459 | ); 460 | 461 | if (startIndex !== -1) { 462 | const startInfo = startStack[startIndex]; 463 | const endPos = marker.pos + marker.length; 464 | 465 | // Regular fold - use marker positions 466 | ranges.push({ from: startInfo.pos, to: endPos }); 467 | 468 | // Remove this start marker and any after it (which would be unpaired) 469 | startStack.splice(startIndex); 470 | } 471 | } 472 | } 473 | } 474 | 475 | return ranges; 476 | } 477 | 478 | function foldServiceFunc( 479 | state: EditorState, 480 | lineStart: number, 481 | lineEnd: number 482 | ): { from: number; to: number } | null { 483 | let range = findMatchingFoldRange(state, lineStart); 484 | if (!range) return null; 485 | 486 | return range; 487 | } 488 | 489 | // export const foldRanges = StateField.define<{ from: number; to: number }[]>({ 490 | // create: () => [], 491 | // update(value, tr) { 492 | // return value; 493 | // }, 494 | // }); 495 | 496 | const FoldingExtension: Extension = [ 497 | codeFolding({ 498 | placeholderDOM(view, onclick) { 499 | const placeholder = createEl("span", { 500 | text: "...", 501 | cls: "cm-foldPlaceholder", 502 | }); 503 | placeholder.onclick = (event) => { 504 | const pos = view.posAtDOM(event.target as Node); 505 | if (pos) { 506 | const effects = unfoldEffect.of({ 507 | from: pos - 2, 508 | to: pos + 2, 509 | }); 510 | view.dispatch({ 511 | effects, 512 | selection: { 513 | anchor: pos + 2, 514 | head: pos + 2, 515 | }, 516 | }); 517 | } 518 | }; 519 | return placeholder; 520 | }, 521 | }), 522 | // foldRanges, 523 | foldService.of(foldServiceFunc), 524 | foldRangesStateField, 525 | // Add the Compartment with default settings 526 | ]; 527 | 528 | export const loadFoldAnyWhereSettings = (settings: FoldAnyWhereSettings) => { 529 | return FoldAnywhereCompartment.of( 530 | FoldAnywhereConfigFacet.of({ 531 | startMarker: settings.startMarker, 532 | endMarker: settings.endMarker, 533 | lineFoldMarker: settings.lineFoldMarker, 534 | lineFoldEndMarker: settings.lineFoldEndMarker, 535 | autoFoldOnLoad: settings.autoFoldOnLoad, 536 | }) 537 | ); 538 | }; 539 | 540 | export function foldAll(view: EditorView) { 541 | const ranges = createFoldRangesFromCurrentPOS( 542 | view.state, 543 | view.state.selection.main.head 544 | ); 545 | if (ranges.length > 0) { 546 | const effects = ranges.map((range) => foldEffect.of(range)); 547 | view.dispatch({ effects }); 548 | 549 | view.dispatch({ 550 | selection: { 551 | anchor: ranges.last()?.to || 0, 552 | head: ranges.last()?.to || 0, 553 | }, 554 | }); 555 | } 556 | } 557 | 558 | export function foldAllRegions(view: EditorView) { 559 | const ranges = getAllFoldableRanges(view.state); 560 | if (ranges.length > 0) { 561 | const effects = ranges.map((range) => foldEffect.of(range)); 562 | view.dispatch({ effects }); 563 | } 564 | } 565 | 566 | export function unfoldAll(view: EditorView) { 567 | const ranges = createFoldRangesFromCurrentPOS( 568 | view.state, 569 | view.state.selection.main.head 570 | ); 571 | if (ranges.length > 0) { 572 | const effects = ranges.map((range) => unfoldEffect.of(range)); 573 | view.dispatch({ effects }); 574 | } 575 | } 576 | 577 | export function foldAllLineRegions(view: EditorView) { 578 | const state = view.state; 579 | const settings = state.facet(FoldAnywhereConfigFacet); 580 | 581 | const lineFoldStartRegex = new RegExp( 582 | settings.lineFoldMarker + "\\s*$", 583 | "g" 584 | ); 585 | const lineFoldEndRegex = new RegExp( 586 | settings.lineFoldEndMarker + "\\s*$", 587 | "g" 588 | ); 589 | 590 | let lineFoldRanges: { from: number; to: number }[] = []; 591 | let lineFoldStack: { lineNum: number; pos: number }[] = []; // Track lines with line fold markers 592 | 593 | // Find all line fold regions 594 | for (let i = 1; i <= state.doc.lines; i++) { 595 | const line = state.doc.line(i); 596 | 597 | // Reset regular expressions 598 | lineFoldStartRegex.lastIndex = 0; 599 | lineFoldEndRegex.lastIndex = 0; 600 | 601 | // Find line fold start markers at the end of this line 602 | let lineFoldStartMatch = lineFoldStartRegex.exec(line.text); 603 | if (lineFoldStartMatch) { 604 | // Calculate the position of the marker 605 | const markerPos = line.from + lineFoldStartMatch.index; 606 | 607 | // This is a start marker in a pair 608 | lineFoldStack.push({ lineNum: i, pos: markerPos }); 609 | } 610 | 611 | // Find line fold end markers 612 | let lineFoldEndMatch = lineFoldEndRegex.exec(line.text); 613 | if (lineFoldEndMatch && lineFoldStack.length > 0) { 614 | // We found a matching pair - get the start marker 615 | const startInfo = lineFoldStack.pop()!; 616 | 617 | // Add range from the marker position to the end of the current line 618 | lineFoldRanges.push({ 619 | from: startInfo.pos, 620 | to: line.to, 621 | }); 622 | } 623 | } 624 | 625 | // Apply all line fold ranges 626 | if (lineFoldRanges.length > 0) { 627 | const effects = lineFoldRanges.map((range) => foldEffect.of(range)); 628 | view.dispatch({ effects }); 629 | } 630 | } 631 | 632 | export default FoldingExtension; 633 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | .cm-fold-anywhere-icon { 2 | cursor: pointer; 3 | opacity: 0; 4 | color: var(--color-red); 5 | transition: opacity 0.1s ease-in; 6 | } 7 | 8 | .cm-contentContainer:hover .cm-fold-anywhere-icon { 9 | opacity: 0.1; 10 | } 11 | 12 | .cm-line:hover .cm-fold-anywhere-icon, 13 | .cm-line.cm-active .cm-fold-anywhere-icon { 14 | opacity: 0.5; 15 | } 16 | 17 | .cm-line:hover .cm-fold-anywhere-icon:hover { 18 | opacity: 1; 19 | } 20 | 21 | .cm-fold-anywhere-icon span.fold-start, 22 | .cm-fold-anywhere-icon span.fold-end { 23 | vertical-align: middle; 24 | height: 22px; 25 | display: inline-flex; 26 | } 27 | 28 | .button-container { 29 | display: flex; 30 | justify-content: space-between; 31 | margin-top: 2rem; 32 | } 33 | 34 | .fold-anywhere-ask-modal div { 35 | font-size: 20px; 36 | text-align: center; 37 | } 38 | 39 | .fold-anywhere-ask-modal button { 40 | width: 4rem; 41 | margin-left: 3rem; 42 | margin-right: 3rem; 43 | } 44 | 45 | .rendered-markdown .cm-time-mark-icon { 46 | position: inherit; 47 | display: inline-block; 48 | opacity: 1; 49 | color: var(--color-red); 50 | } 51 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "module": "ESNext", 7 | "target": "es2018", 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 | "es2018" 20 | ] 21 | }, 22 | "include": [ 23 | "**/*.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /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 | "1.1.0": "0.15.0", 4 | "1.2.0": "0.15.0", 5 | "1.2.1": "0.15.0", 6 | "1.3.0": "0.15.0", 7 | "2.0.0": "0.15.0", 8 | "2.0.1": "0.15.0", 9 | "2.0.2": "0.15.0", 10 | "2.1.0": "0.15.0", 11 | "2.1.1": "0.15.0" 12 | } --------------------------------------------------------------------------------