├── .npmrc ├── .eslintignore ├── docs ├── UAT.png └── example.gif ├── src ├── ocr-provider.ts ├── TexifyResponse.ts ├── SimpleTexResponse.ts ├── tex-wrapper.ts ├── editor-interact.ts ├── texify.ts ├── pic2tex.ts ├── simple-tex.ts ├── main.ts └── settings.ts ├── styles.css ├── .editorconfig ├── versions.json ├── manifest.json ├── .gitignore ├── tsconfig.json ├── CHANGELOG.md ├── scripts └── do-release.sh ├── version-bump.mjs ├── .eslintrc ├── package.json ├── .github └── workflows │ └── release.yml ├── LICENSE ├── esbuild.config.mjs ├── README.md └── pnpm-lock.yaml /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix="" -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | main.js 4 | -------------------------------------------------------------------------------- /docs/UAT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hugo-Persson/obsidian-ocrlatex/HEAD/docs/UAT.png -------------------------------------------------------------------------------- /docs/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hugo-Persson/obsidian-ocrlatex/HEAD/docs/example.gif -------------------------------------------------------------------------------- /src/ocr-provider.ts: -------------------------------------------------------------------------------- 1 | export default interface OCRProvider { 2 | sendRequest(image: Uint8Array): Promise; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /src/TexifyResponse.ts: -------------------------------------------------------------------------------- 1 | export interface TexifyResponse { 2 | message: string 3 | results: string[] 4 | success: boolean 5 | } 6 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This CSS file will be included with your plugin, and 4 | available in the app when your plugin is enabled. 5 | 6 | If your plugin does not need CSS, delete this file. 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /src/SimpleTexResponse.ts: -------------------------------------------------------------------------------- 1 | export interface SimpleTexResponse { 2 | status: boolean; 3 | res: Res; 4 | request_id: string; 5 | } 6 | 7 | export interface Res { 8 | conf: number; 9 | latex: string; 10 | } 11 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.0": "0.15.0", 3 | "1.0.1": "0.15.0", 4 | "1.0.2": "0.15.0", 5 | "1.0.3": "0.15.0", 6 | "1.0.4": "0.15.0", 7 | "1.0.5": "0.15.0", 8 | "1.1.0": "0.15.0", 9 | "1.1.1": "0.15.0", 10 | "1.1.2": "0.15.0" 11 | } 12 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "image2latex", 3 | "name": "Image2LaTEX", 4 | "version": "1.1.2", 5 | "minAppVersion": "0.15.0", 6 | "description": "Convert your images to Markdown and MathJax", 7 | "author": "Hugo Persson", 8 | "authorUrl": "https://github.com/Hugo-Persson", 9 | "isDesktopOnly": true 10 | } 11 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "sourceRoot": "./src", 5 | "inlineSourceMap": true, 6 | "inlineSources": true, 7 | "module": "ESNext", 8 | "target": "ES6", 9 | "allowJs": true, 10 | "noImplicitAny": true, 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "isolatedModules": true, 14 | "allowSyntheticDefaultImports": true, 15 | "strictNullChecks": true, 16 | "lib": ["DOM", "ES5", "ES6", "ES7"] 17 | }, 18 | "include": ["**/*.ts"] 19 | } 20 | -------------------------------------------------------------------------------- /src/tex-wrapper.ts: -------------------------------------------------------------------------------- 1 | import OCRProvider from "./ocr-provider"; 2 | 3 | export default abstract class TexWrapper implements OCRProvider { 4 | private isMultiline = false; 5 | constructor(isMultiline: boolean) { 6 | this.isMultiline = isMultiline; 7 | } 8 | 9 | abstract getTex(image: Uint8Array): Promise; 10 | 11 | async sendRequest(image: Uint8Array): Promise { 12 | const res = await this.getTex(image); 13 | if (this.isMultiline) return `$$ ${res}$$`; 14 | return `$${res}$`; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.1.2 - 2023-04-04 2 | - Fixed bug with Texify settings 3 | # 1.1.1 - 2023-04-04 4 | - Fixed: https://github.com/Hugo-Persson/obsidian-ocrlatex/issues/12 5 | # 1.1.0 - 2023-04-01 6 | ## New 🚀 7 | - Added Texify for image → markdown 8 | ## ⚠️ Breaking changes 9 | - Updated settings and documentation to be more intuitive with multiple providers 10 | 11 | # 1.0.5 - 2023-03-10 12 | ## New 🚀 13 | - Ability to use pix2tex for local OCR https://github.com/lukas-blecher/LaTeX-OCR 14 | ## Special thanks ❤️ 15 | - @Marlon154 16 | # 1.0.4 - 2023-02-22 17 | ## New 🚀 18 | - Added option between inline and block equation 19 | 20 | ## Special Thanks ❤️ 21 | - @Mideks 22 | -------------------------------------------------------------------------------- /scripts/do-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | echo "Have you updated CHANGELOG.md, versions.json, manifest.json and package.json?" 5 | read -p "Press any key to continue, or press Ctrl+C to cancel." 6 | 7 | 8 | last_tag=$(git describe --tags --abbrev=0) 9 | echo "Last tag: $last_tag" 10 | # Prompt the user for a version number 11 | read -p "Enter the version number: " version_number 12 | 13 | # Tag the last git commit with the provided version number 14 | git tag -a "$version_number" -m "$version_number" 15 | 16 | # Push the tagged commit to the remote repository 17 | git push origin "$version_number" 18 | 19 | echo "Tagged and pushed commit with version $version_number successfully." 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "image2latex", 3 | "version": "1.1.2", 4 | "description": "Convert your images to Markdown and MathJax", 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 | "devDependencies": { 15 | "@types/node": "^16.11.6", 16 | "@typescript-eslint/eslint-plugin": "5.29.0", 17 | "@typescript-eslint/parser": "5.29.0", 18 | "builtin-modules": "3.3.0", 19 | "esbuild": "0.17.3", 20 | "obsidian": "latest", 21 | "tslib": "2.4.0", 22 | "typescript": "4.7.4" 23 | }, 24 | "dependencies": { 25 | "form-data": "^4.0.0", 26 | "node-fetch": "^3.3.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/editor-interact.ts: -------------------------------------------------------------------------------- 1 | import { Editor, EditorPosition, MarkdownView } from "obsidian"; 2 | 3 | const loadingText = `Loading latex...`; 4 | export default class EditorInteract { 5 | view: MarkdownView; 6 | cursor: EditorPosition; 7 | editor: Editor; 8 | 9 | constructor(view: MarkdownView) { 10 | this.view = view; 11 | this.cursor = view.editor.getCursor(); 12 | this.editor = view.editor; 13 | } 14 | 15 | insertLoadingText() { 16 | this.editor.replaceRange(loadingText, this.cursor); 17 | this.editor.setCursor({ 18 | line: this.cursor.line, 19 | ch: this.cursor.ch + loadingText.length, 20 | }); 21 | } 22 | 23 | insertResponseToEditor(res: string) { 24 | this.view.editor.replaceRange(res, this.cursor, { 25 | // Insert the response 26 | ch: this.cursor.ch + loadingText.length, // We replace the loading text 27 | line: this.cursor.line, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Obsidian plugin 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | repository_dispatch: 8 | 9 | jobs: 10 | build: 11 | permissions: write-all 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: Use Node.js 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: "18.x" 21 | 22 | - name: Build plugin 23 | run: | 24 | npm install 25 | npm run build 26 | - name: Create release 27 | uses: "marvinpinto/action-automatic-releases@latest" 28 | with: 29 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 30 | prerelease: false 31 | files: | 32 | main.js 33 | manifest.json 34 | styles.css 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2023] [Hugo Persson] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/texify.ts: -------------------------------------------------------------------------------- 1 | import OCRProvider from "./ocr-provider"; 2 | import fetch from "node-fetch"; 3 | import FormData from "form-data"; 4 | import { TexifyResponse } from "./TexifyResponse"; 5 | import { SelfHostedSettings } from "./settings"; 6 | 7 | export default class Texify implements OCRProvider { 8 | settings: SelfHostedSettings; 9 | 10 | constructor(settings: SelfHostedSettings) { 11 | this.settings = settings; 12 | } 13 | 14 | async sendRequest(image: Uint8Array): Promise { 15 | const formData = new FormData(); 16 | 17 | formData.append("image", image, { 18 | filename: "image.png", 19 | contentType: "image/png", 20 | }); 21 | 22 | let options: any = { 23 | method: "POST", 24 | body: formData, 25 | }; 26 | if (this.settings.username && this.settings.password) { 27 | options.headers = { 28 | Authorization: `Basic ${btoa(`${this.settings.username}:${this.settings.password}`) 29 | }`, 30 | }; 31 | } 32 | const response = await fetch(this.settings.url, options); 33 | const parsed: TexifyResponse = await response.json() as TexifyResponse; 34 | console.log(parsed); 35 | return parsed.results[0]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /esbuild.config.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import process from "process"; 3 | import builtins from "builtin-modules"; 4 | 5 | const banner = `/* 6 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 7 | if you want to view the source, please visit the github repository of this plugin 8 | */ 9 | `; 10 | 11 | const prod = process.argv[2] === "production"; 12 | 13 | const context = await esbuild.context({ 14 | banner: { 15 | js: banner, 16 | }, 17 | entryPoints: ["./src/main.ts"], 18 | bundle: true, 19 | external: [ 20 | "obsidian", 21 | "electron", 22 | "@codemirror/autocomplete", 23 | "@codemirror/collab", 24 | "@codemirror/commands", 25 | "@codemirror/language", 26 | "@codemirror/lint", 27 | "@codemirror/search", 28 | "@codemirror/state", 29 | "@codemirror/view", 30 | "@lezer/common", 31 | "@lezer/highlight", 32 | "@lezer/lr", 33 | ...builtins, 34 | ], 35 | format: "cjs", 36 | target: "es2018", 37 | logLevel: "info", 38 | platform: "node", 39 | sourcemap: prod ? false : "inline", 40 | treeShaking: true, 41 | outfile: "main.js", 42 | }); 43 | 44 | if (prod) { 45 | await context.rebuild(); 46 | process.exit(0); 47 | } else { 48 | await context.watch(); 49 | } 50 | -------------------------------------------------------------------------------- /src/pic2tex.ts: -------------------------------------------------------------------------------- 1 | 2 | import fetch from "node-fetch"; 3 | import FormData from "form-data"; 4 | import TexWrapper from "./tex-wrapper"; 5 | import { OCRLatexPluginSettings } from "./settings"; 6 | 7 | export default class Pic2Tex extends TexWrapper{ 8 | settings: OCRLatexPluginSettings; 9 | 10 | constructor(isMultiline: boolean, settings: OCRLatexPluginSettings) { 11 | super(isMultiline); 12 | this.settings = settings; 13 | } 14 | 15 | async getTex(image: Uint8Array): Promise { 16 | const formData = new FormData(); 17 | 18 | formData.append("file", image, { 19 | filename: "test.png", 20 | contentType: "image/png", 21 | }); 22 | 23 | let response; 24 | let options: any = { 25 | method: "POST", 26 | body: formData, 27 | }; 28 | if (this.settings.pix2tex.username && this.settings.pix2tex.password) { 29 | options.headers = { 30 | Authorization: `Basic ${btoa(`${this.settings.pix2tex.username}:${this.settings.pix2tex.password}`) 31 | }`, 32 | }; 33 | } 34 | response = await fetch(this.settings.pix2tex.url, options); 35 | 36 | if (!response.ok) throw response; // Not a ok response, we throw here and let method calling to show error message 37 | 38 | const jsonString = await response.text(); 39 | // Remove the quotes at the start and end of the string 40 | let latexText = jsonString.substring(1, jsonString.length - 1); 41 | // Replace all occurrences of \\ with \ 42 | latexText = latexText.replace(/\\\\/g, "\\"); 43 | return latexText; 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/simple-tex.ts: -------------------------------------------------------------------------------- 1 | import OCRProvider from "./ocr-provider"; 2 | import fetch from "node-fetch"; 3 | import FormData from "form-data"; 4 | import { TexifyResponse } from "./TexifyResponse"; 5 | import TexWrapper from "./tex-wrapper"; 6 | import { SimpleTexResponse } from "./SimpleTexResponse"; 7 | import { OCRLatexPluginSettings } from "./settings"; 8 | 9 | // Simpletex is web service that converts images to latex 10 | export default class SimpleTex extends TexWrapper { 11 | settings: OCRLatexPluginSettings; 12 | 13 | constructor(isMultiline: boolean, settings: OCRLatexPluginSettings) { 14 | super(isMultiline); 15 | this.settings = settings; 16 | } 17 | 18 | async getTex(image: Uint8Array): Promise { 19 | const formData = new FormData(); 20 | 21 | formData.append("file", image, { 22 | filename: "test.png", 23 | contentType: "image/png", 24 | }); 25 | 26 | let response; 27 | response = await fetch("https://server.simpletex.cn/api/latex_ocr_turbo", { 28 | method: "POST", 29 | headers: { 30 | token: this.settings.simpleTexToken, 31 | }, 32 | body: formData, 33 | }); 34 | 35 | if (!response.ok) { 36 | console.error("Simpletext response", response); // Not a ok response, we throw here and let method calling to show error message 37 | alert("Simple TEX not working properly, see logs.") 38 | } 39 | const resText = await response.text(); 40 | console.log("Simple tex response", resText); 41 | const data: SimpleTexResponse = (JSON.parse(resText)) as SimpleTexResponse; 42 | console.log("Simple tex data"); 43 | return data.res.latex; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { App, MarkdownView, Plugin, PluginManifest } from "obsidian"; 2 | 3 | // @ts-ignore "electron" is installed. 4 | import { clipboard } from "electron"; 5 | 6 | import OCRProvider from "./ocr-provider"; 7 | import Pic2Tex from "./pic2tex"; 8 | import SimpleTex from "./simple-tex"; 9 | import Texify from "./texify"; 10 | import OCRLatexSettings, { 11 | DEFAULT_SETTINGS, 12 | OCRLatexPluginSettings, 13 | } from "./settings"; 14 | import EditorInteract from "./editor-interact"; 15 | 16 | const loadingText = `Loading latex...`; 17 | 18 | function getLatexProvider( 19 | isMultiline: boolean, 20 | settings: OCRLatexPluginSettings, 21 | ): OCRProvider { 22 | if (settings.latexProvider === "SimpleTex") { 23 | return new SimpleTex(isMultiline, settings); 24 | } else { 25 | return new Pic2Tex(isMultiline, settings); 26 | } 27 | } 28 | 29 | export default class OCRLatexPlugin extends Plugin { 30 | settings: OCRLatexPluginSettings; 31 | 32 | private getClipboardImage(): Uint8Array | null { 33 | const hasImageCopied = clipboard.availableFormats().includes("image/png") || 34 | clipboard.availableFormats().includes("image/jpeg"); 35 | if (!hasImageCopied) { 36 | alert( 37 | "No image found in clipboard, please copy an image then run command again.", 38 | ); 39 | return null; 40 | } 41 | return clipboard.readImage().toPNG(); 42 | } 43 | 44 | private async insert(provider: OCRProvider) { 45 | try { 46 | const view = this.app.workspace.getActiveViewOfType(MarkdownView); 47 | if (!view) { 48 | alert("No markdown view found, please open a markdown file."); 49 | return; 50 | } 51 | 52 | const editorInteract = new EditorInteract(view); 53 | const image = this.getClipboardImage(); 54 | if (!image) return; 55 | editorInteract.insertLoadingText(); 56 | const parsedLatex = await provider.sendRequest(image); 57 | console.log(parsedLatex); 58 | editorInteract.insertResponseToEditor(parsedLatex); 59 | } catch (error) { 60 | console.error(error); 61 | alert( 62 | "Error while fetching latex, please check the console for more information.", 63 | ); 64 | } 65 | } 66 | 67 | async onload() { 68 | await this.loadSettings(); 69 | 70 | this.addCommand({ 71 | id: "generate-latex-from-last-image-multiline", 72 | name: "Generate multiline LaTeX from last image to clipboard", 73 | callback: () => { 74 | this.insert( 75 | getLatexProvider(true, this.settings), 76 | ); 77 | }, 78 | }); 79 | 80 | this.addCommand({ 81 | id: "generate-latex-from-last-image-inline", 82 | name: "Generate inline LaTeX from last image to clipboard", 83 | callback: () => { 84 | this.insert( 85 | getLatexProvider(false, this.settings), 86 | ); 87 | }, 88 | }); 89 | 90 | this.addCommand({ 91 | id: "generate-markdown-from-last-image", 92 | name: "Generate markdown from last image to clipboard using Texify", 93 | callback: async () => { 94 | this.insert(new Texify(this.settings.texify)); 95 | }, 96 | }); 97 | 98 | // This adds a settings tab so the user can configure various aspects of the plugin 99 | this.addSettingTab(new OCRLatexSettings(this.app, this)); 100 | } 101 | 102 | onunload() { } 103 | 104 | async loadSettings() { 105 | this.settings = Object.assign( 106 | {}, 107 | DEFAULT_SETTINGS, 108 | await this.loadData(), 109 | ); 110 | } 111 | 112 | async saveSettings() { 113 | await this.saveData(this.settings); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 🗞️ 2 | 3 | This extension takes your latest copied image from your clipboard and either converts it to Markdown or MathJax. The extensions have three different OCR providers that you can pick between 4 | 1. [Texify](https://github.com/VikParuchuri/texify) (Recomended) - Self Hosted service that convert your image to Markdown 5 | 2. [SimpleTex](https://update.simpletex.cn/) - Hosted service that converts converts your image to Latex wrapped in Math Block 6 | 3. [pix2tex](https://github.com/lukas-blecher/LaTeX-OCR) - Self Hosted service that converts your image to Latex wrapped in Math Block 7 | 8 | See GIF below for example of usage with a keybinding: 9 | ![](docs/example.gif) 10 | A couple of things happen here 11 | 12 | 1. I take a screenshot of the formula on the left 13 | 2. I use a keybinding to trigger the OCRToLatex 14 | 3. A loading indicator is inserted 15 | 16 | # Setup 🚀 17 | 18 | To get started first get an api token, see below. Then go to settings and insert it. After this you are ready to use the plugin. Try to snip a math formula to your clipboard and run the command `Generate latex from last image to clipboard 19 | ## Texify ⭐ 20 | This provider requires you to self host it, if you don't have a server or a computer that can run the model I would recomend using SimpleTex instead. 21 | 22 | To setup this project clone the repo [texify-wep-api](https://github.com/Hugo-Persson/texify-wep-api) and follow the setup for that project. Now a web service will be exposed and you can paste the URL into the field `url` in Obsidian settings. If you run on localhost this will be ´localhost:5000` but you could host this on your own server and you would then use the appropiate URL. 23 | 24 | 25 | **Note:** The first request to Texify will be slow because the model needs to be loaded, after the first request the API will much faster. 26 | ## SimpleTex 27 | ### Getting API Token 🔐 28 | 29 | To use this plugin you need to create a developer account at https://simpletex.cn. Below I describe how to do this 30 | 31 | 1. Go to https://simpletex.cn/api 32 | 2. Click "Go to API Dashboard" 33 | 3. Create an account 34 | 4. After this go to `User Access Token` and click `Create token` 35 | 5. Copy the token and paste into Obsidian settings ![](docs/UAT.png) 36 | 6. Now you are ready to use the addon 🥳 37 | 38 | ## Pix2Tex 39 | This is an self hosted alternative to SimpleTex. There are two main way to host it, either your run through Docker or host directly with python. 40 | **Note:** Docker does not work on ARM, for example M series MacBooks, use Python instead. 41 | ### Docker 🐳 42 | You can host Pix2Tex in Obsidian by using Docker. This is well explained in their docs https://hub.docker.com/r/lukasblecher/pix2tex 43 | 44 | ### Python 🐍 45 | You can run the project directly with Python by 46 | 1. Installing the package with `pip install pix2tex[api]` 47 | 2. Running the Web Api with: `python -m pix2tex.api.run` 48 | 49 | 50 | ### Configuring Obsidian 51 | 52 | Enter the URL to the container, you need to postfix `/predict/` e.g. `http://localhost:8502/predict/` 53 | **Optional**: add username and password, if container is behind a basic auth proxy (e.g. [nginx](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html)) 54 | 55 | 56 | # Future improvements ✅ 57 | 58 | - [ ] Convert already pasted images 59 | 60 | # Contributing or requesting feature 😍 61 | - If you are missing something from the Plugin, please open an Issue 62 | - If you wish to contribute, please open a PR 63 | 64 | 65 | # Attribution 🙏 66 | 67 | Thanks to these libraries and services for making this plugin possible 68 | 69 | - https://www.npmjs.com/package/node-fetch 70 | - https://www.npmjs.com/package/form-data 71 | - https://simpletex.cn/ 72 | - https://github.com/Hugo-Persson/texify-wep-api 73 | - https://github.com/VikParuchuri/texify 74 | - https://github.com/lukas-blecher/LaTeX-OCR 75 | -------------------------------------------------------------------------------- /src/settings.ts: -------------------------------------------------------------------------------- 1 | 2 | import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian"; 3 | 4 | type LatexProvider = "SimpleTex" | "Pix2Tex"; 5 | export interface OCRLatexPluginSettings { 6 | simpleTexToken: string; 7 | texify:{ 8 | url: string; 9 | username: string; 10 | password: string; 11 | }, 12 | pix2tex:{ 13 | url: string; 14 | username: string; 15 | password: string; 16 | }, 17 | latexProvider: LatexProvider; 18 | } 19 | 20 | export interface SelfHostedSettings { 21 | url: string; 22 | username: string; 23 | password: string; 24 | } 25 | 26 | export const DEFAULT_SETTINGS: OCRLatexPluginSettings = { 27 | simpleTexToken: "", 28 | latexProvider: "SimpleTex", 29 | texify:{ 30 | url: "http://127.0.0.1:5000/predict", 31 | username: "", 32 | password: "", 33 | }, 34 | pix2tex:{ 35 | url: "http://127.0.0.1:8502/predict/", 36 | username: "", 37 | password: "", 38 | }, 39 | 40 | }; 41 | 42 | import OCRLatexPlugin from "./main"; 43 | export default class OCRLatexSettings extends PluginSettingTab { 44 | plugin: OCRLatexPlugin; 45 | 46 | renderSelfHostedOptions(obj: SelfHostedSettings, containerEl:HTMLElement, endWithSlash: boolean) { 47 | new Setting(containerEl) 48 | .setName("URL") 49 | .setDesc( 50 | "The URL for the API endpoint, only active when self-hosted is enabled.", 51 | ) 52 | .addText((text) => 53 | text 54 | .setPlaceholder("Enter your URL") 55 | .setValue(obj.url) 56 | .onChange(async (value) => { 57 | if (!value.endsWith("/") && endWithSlash) value += "/"; 58 | if(value.endsWith("/") && !endWithSlash) value = value.slice(0, -1); 59 | obj.url = value; 60 | await this.plugin.saveSettings(); 61 | }) 62 | ); 63 | 64 | new Setting(containerEl) 65 | .setName("Username (self-hosted optional)") 66 | .setDesc( 67 | "Your username for authentication. If you use self-hosted and a basic auth proxy before the container.", 68 | ) 69 | .addText((text) => 70 | text 71 | .setPlaceholder("Enter your username") 72 | .setValue(obj.username) 73 | .onChange(async (value) => { 74 | obj.username = value; 75 | await this.plugin.saveSettings(); 76 | }) 77 | ); 78 | 79 | new Setting(containerEl) 80 | .setName("Password (self-hosted optional)") 81 | .setDesc( 82 | "Your password for authentication. If you use self-hosted and a basic auth proxy before the container.", 83 | ) 84 | .addText((text) => 85 | text 86 | .setPlaceholder("Enter your password") 87 | .setValue(obj.password) 88 | .onChange(async (value) => { 89 | obj.password = value; 90 | await this.plugin.saveSettings(); 91 | }) 92 | ); 93 | 94 | } 95 | 96 | constructor(app: App, plugin: OCRLatexPlugin) { 97 | super(app, plugin); 98 | this.plugin = plugin; 99 | } 100 | 101 | display(): void { 102 | const { containerEl } = this; 103 | 104 | containerEl.empty(); 105 | const readmeURL= "https://github.com/Hugo-Persson/obsidian-ocrlatex/blob/master/README.md" 106 | containerEl.createEl("h1", { text: "Image2Latex" }); 107 | containerEl.createEl("div", {text: "Please see the README.md for info on how to configure the extension"}) 108 | containerEl.createEl("a", {href:readmeURL, text: readmeURL}) 109 | containerEl.createEl("h2", { text: "General" }); 110 | new Setting(containerEl).setName("Latex provider").setDesc("Choose which provider to use for OCR and Latex conversion").addDropdown((dropdown) => { 111 | dropdown.addOptions({ 112 | "SimpleTex": "SimpleTex", 113 | "Pix2Tex": "Pix2Tex", 114 | }).setValue(this.plugin.settings.latexProvider).onChange(async (value) => { 115 | 116 | this.plugin.settings.latexProvider = value as LatexProvider; 117 | await this.plugin.saveSettings(); 118 | }); 119 | }); 120 | 121 | containerEl.createEl("h2", { text: "Texify" }); 122 | this.renderSelfHostedOptions(this.plugin.settings.texify, containerEl, false); 123 | 124 | containerEl.createEl("h2", { text: "Pix2Tex" }); 125 | this.renderSelfHostedOptions(this.plugin.settings.pix2tex, containerEl, true); 126 | 127 | 128 | containerEl.createEl("h2", { text: "SimpleTex" }); 129 | new Setting(containerEl) 130 | .setName("Token") 131 | .setDesc( 132 | "Your SimpleTexToken, see README.md for more info.", 133 | ) 134 | .addText((text) => 135 | text 136 | .setPlaceholder("Enter token...") 137 | .setValue(this.plugin.settings.simpleTexToken) 138 | .onChange(async (value) => { 139 | this.plugin.settings.simpleTexToken = value; 140 | await this.plugin.saveSettings(); 141 | }) 142 | ); 143 | 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | form-data: 9 | specifier: ^4.0.0 10 | version: 4.0.0 11 | node-fetch: 12 | specifier: ^3.3.2 13 | version: 3.3.2 14 | 15 | devDependencies: 16 | '@types/node': 17 | specifier: ^16.11.6 18 | version: 16.18.48 19 | '@typescript-eslint/eslint-plugin': 20 | specifier: 5.29.0 21 | version: 5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.48.0)(typescript@4.7.4) 22 | '@typescript-eslint/parser': 23 | specifier: 5.29.0 24 | version: 5.29.0(eslint@8.48.0)(typescript@4.7.4) 25 | builtin-modules: 26 | specifier: 3.3.0 27 | version: 3.3.0 28 | esbuild: 29 | specifier: 0.17.3 30 | version: 0.17.3 31 | obsidian: 32 | specifier: latest 33 | version: 1.4.4(@codemirror/state@6.2.1)(@codemirror/view@6.17.1) 34 | tslib: 35 | specifier: 2.4.0 36 | version: 2.4.0 37 | typescript: 38 | specifier: 4.7.4 39 | version: 4.7.4 40 | 41 | packages: 42 | 43 | /@aashutoshrathi/word-wrap@1.2.6: 44 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} 45 | engines: {node: '>=0.10.0'} 46 | dev: true 47 | 48 | /@codemirror/state@6.2.1: 49 | resolution: {integrity: sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==} 50 | dev: true 51 | 52 | /@codemirror/view@6.17.1: 53 | resolution: {integrity: sha512-I5KVxsLbm1f56n9SUajLW0/AzMXYEZVvkiYahMw/yGl5gUjT2WquuKO39xUtiT4z/hNhGD7YuAEVPI8u0mncaQ==} 54 | dependencies: 55 | '@codemirror/state': 6.2.1 56 | style-mod: 4.1.0 57 | w3c-keyname: 2.2.8 58 | dev: true 59 | 60 | /@esbuild/android-arm64@0.17.3: 61 | resolution: {integrity: sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==} 62 | engines: {node: '>=12'} 63 | cpu: [arm64] 64 | os: [android] 65 | requiresBuild: true 66 | dev: true 67 | optional: true 68 | 69 | /@esbuild/android-arm@0.17.3: 70 | resolution: {integrity: sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==} 71 | engines: {node: '>=12'} 72 | cpu: [arm] 73 | os: [android] 74 | requiresBuild: true 75 | dev: true 76 | optional: true 77 | 78 | /@esbuild/android-x64@0.17.3: 79 | resolution: {integrity: sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==} 80 | engines: {node: '>=12'} 81 | cpu: [x64] 82 | os: [android] 83 | requiresBuild: true 84 | dev: true 85 | optional: true 86 | 87 | /@esbuild/darwin-arm64@0.17.3: 88 | resolution: {integrity: sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==} 89 | engines: {node: '>=12'} 90 | cpu: [arm64] 91 | os: [darwin] 92 | requiresBuild: true 93 | dev: true 94 | optional: true 95 | 96 | /@esbuild/darwin-x64@0.17.3: 97 | resolution: {integrity: sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==} 98 | engines: {node: '>=12'} 99 | cpu: [x64] 100 | os: [darwin] 101 | requiresBuild: true 102 | dev: true 103 | optional: true 104 | 105 | /@esbuild/freebsd-arm64@0.17.3: 106 | resolution: {integrity: sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==} 107 | engines: {node: '>=12'} 108 | cpu: [arm64] 109 | os: [freebsd] 110 | requiresBuild: true 111 | dev: true 112 | optional: true 113 | 114 | /@esbuild/freebsd-x64@0.17.3: 115 | resolution: {integrity: sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==} 116 | engines: {node: '>=12'} 117 | cpu: [x64] 118 | os: [freebsd] 119 | requiresBuild: true 120 | dev: true 121 | optional: true 122 | 123 | /@esbuild/linux-arm64@0.17.3: 124 | resolution: {integrity: sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==} 125 | engines: {node: '>=12'} 126 | cpu: [arm64] 127 | os: [linux] 128 | requiresBuild: true 129 | dev: true 130 | optional: true 131 | 132 | /@esbuild/linux-arm@0.17.3: 133 | resolution: {integrity: sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==} 134 | engines: {node: '>=12'} 135 | cpu: [arm] 136 | os: [linux] 137 | requiresBuild: true 138 | dev: true 139 | optional: true 140 | 141 | /@esbuild/linux-ia32@0.17.3: 142 | resolution: {integrity: sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==} 143 | engines: {node: '>=12'} 144 | cpu: [ia32] 145 | os: [linux] 146 | requiresBuild: true 147 | dev: true 148 | optional: true 149 | 150 | /@esbuild/linux-loong64@0.17.3: 151 | resolution: {integrity: sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==} 152 | engines: {node: '>=12'} 153 | cpu: [loong64] 154 | os: [linux] 155 | requiresBuild: true 156 | dev: true 157 | optional: true 158 | 159 | /@esbuild/linux-mips64el@0.17.3: 160 | resolution: {integrity: sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==} 161 | engines: {node: '>=12'} 162 | cpu: [mips64el] 163 | os: [linux] 164 | requiresBuild: true 165 | dev: true 166 | optional: true 167 | 168 | /@esbuild/linux-ppc64@0.17.3: 169 | resolution: {integrity: sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==} 170 | engines: {node: '>=12'} 171 | cpu: [ppc64] 172 | os: [linux] 173 | requiresBuild: true 174 | dev: true 175 | optional: true 176 | 177 | /@esbuild/linux-riscv64@0.17.3: 178 | resolution: {integrity: sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==} 179 | engines: {node: '>=12'} 180 | cpu: [riscv64] 181 | os: [linux] 182 | requiresBuild: true 183 | dev: true 184 | optional: true 185 | 186 | /@esbuild/linux-s390x@0.17.3: 187 | resolution: {integrity: sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==} 188 | engines: {node: '>=12'} 189 | cpu: [s390x] 190 | os: [linux] 191 | requiresBuild: true 192 | dev: true 193 | optional: true 194 | 195 | /@esbuild/linux-x64@0.17.3: 196 | resolution: {integrity: sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==} 197 | engines: {node: '>=12'} 198 | cpu: [x64] 199 | os: [linux] 200 | requiresBuild: true 201 | dev: true 202 | optional: true 203 | 204 | /@esbuild/netbsd-x64@0.17.3: 205 | resolution: {integrity: sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==} 206 | engines: {node: '>=12'} 207 | cpu: [x64] 208 | os: [netbsd] 209 | requiresBuild: true 210 | dev: true 211 | optional: true 212 | 213 | /@esbuild/openbsd-x64@0.17.3: 214 | resolution: {integrity: sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==} 215 | engines: {node: '>=12'} 216 | cpu: [x64] 217 | os: [openbsd] 218 | requiresBuild: true 219 | dev: true 220 | optional: true 221 | 222 | /@esbuild/sunos-x64@0.17.3: 223 | resolution: {integrity: sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==} 224 | engines: {node: '>=12'} 225 | cpu: [x64] 226 | os: [sunos] 227 | requiresBuild: true 228 | dev: true 229 | optional: true 230 | 231 | /@esbuild/win32-arm64@0.17.3: 232 | resolution: {integrity: sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==} 233 | engines: {node: '>=12'} 234 | cpu: [arm64] 235 | os: [win32] 236 | requiresBuild: true 237 | dev: true 238 | optional: true 239 | 240 | /@esbuild/win32-ia32@0.17.3: 241 | resolution: {integrity: sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==} 242 | engines: {node: '>=12'} 243 | cpu: [ia32] 244 | os: [win32] 245 | requiresBuild: true 246 | dev: true 247 | optional: true 248 | 249 | /@esbuild/win32-x64@0.17.3: 250 | resolution: {integrity: sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==} 251 | engines: {node: '>=12'} 252 | cpu: [x64] 253 | os: [win32] 254 | requiresBuild: true 255 | dev: true 256 | optional: true 257 | 258 | /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): 259 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 260 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 261 | peerDependencies: 262 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 263 | dependencies: 264 | eslint: 8.48.0 265 | eslint-visitor-keys: 3.4.3 266 | dev: true 267 | 268 | /@eslint-community/regexpp@4.8.0: 269 | resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==} 270 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 271 | dev: true 272 | 273 | /@eslint/eslintrc@2.1.2: 274 | resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} 275 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 276 | dependencies: 277 | ajv: 6.12.6 278 | debug: 4.3.4 279 | espree: 9.6.1 280 | globals: 13.21.0 281 | ignore: 5.2.4 282 | import-fresh: 3.3.0 283 | js-yaml: 4.1.0 284 | minimatch: 3.1.2 285 | strip-json-comments: 3.1.1 286 | transitivePeerDependencies: 287 | - supports-color 288 | dev: true 289 | 290 | /@eslint/js@8.48.0: 291 | resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} 292 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 293 | dev: true 294 | 295 | /@humanwhocodes/config-array@0.11.11: 296 | resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} 297 | engines: {node: '>=10.10.0'} 298 | dependencies: 299 | '@humanwhocodes/object-schema': 1.2.1 300 | debug: 4.3.4 301 | minimatch: 3.1.2 302 | transitivePeerDependencies: 303 | - supports-color 304 | dev: true 305 | 306 | /@humanwhocodes/module-importer@1.0.1: 307 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 308 | engines: {node: '>=12.22'} 309 | dev: true 310 | 311 | /@humanwhocodes/object-schema@1.2.1: 312 | resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} 313 | dev: true 314 | 315 | /@nodelib/fs.scandir@2.1.5: 316 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 317 | engines: {node: '>= 8'} 318 | dependencies: 319 | '@nodelib/fs.stat': 2.0.5 320 | run-parallel: 1.2.0 321 | dev: true 322 | 323 | /@nodelib/fs.stat@2.0.5: 324 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 325 | engines: {node: '>= 8'} 326 | dev: true 327 | 328 | /@nodelib/fs.walk@1.2.8: 329 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 330 | engines: {node: '>= 8'} 331 | dependencies: 332 | '@nodelib/fs.scandir': 2.1.5 333 | fastq: 1.15.0 334 | dev: true 335 | 336 | /@types/codemirror@5.60.8: 337 | resolution: {integrity: sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==} 338 | dependencies: 339 | '@types/tern': 0.23.4 340 | dev: true 341 | 342 | /@types/estree@1.0.1: 343 | resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} 344 | dev: true 345 | 346 | /@types/json-schema@7.0.12: 347 | resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} 348 | dev: true 349 | 350 | /@types/node@16.18.48: 351 | resolution: {integrity: sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q==} 352 | dev: true 353 | 354 | /@types/tern@0.23.4: 355 | resolution: {integrity: sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==} 356 | dependencies: 357 | '@types/estree': 1.0.1 358 | dev: true 359 | 360 | /@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0)(eslint@8.48.0)(typescript@4.7.4): 361 | resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==} 362 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 363 | peerDependencies: 364 | '@typescript-eslint/parser': ^5.0.0 365 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 366 | typescript: '*' 367 | peerDependenciesMeta: 368 | typescript: 369 | optional: true 370 | dependencies: 371 | '@typescript-eslint/parser': 5.29.0(eslint@8.48.0)(typescript@4.7.4) 372 | '@typescript-eslint/scope-manager': 5.29.0 373 | '@typescript-eslint/type-utils': 5.29.0(eslint@8.48.0)(typescript@4.7.4) 374 | '@typescript-eslint/utils': 5.29.0(eslint@8.48.0)(typescript@4.7.4) 375 | debug: 4.3.4 376 | eslint: 8.48.0 377 | functional-red-black-tree: 1.0.1 378 | ignore: 5.2.4 379 | regexpp: 3.2.0 380 | semver: 7.5.4 381 | tsutils: 3.21.0(typescript@4.7.4) 382 | typescript: 4.7.4 383 | transitivePeerDependencies: 384 | - supports-color 385 | dev: true 386 | 387 | /@typescript-eslint/parser@5.29.0(eslint@8.48.0)(typescript@4.7.4): 388 | resolution: {integrity: sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==} 389 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 390 | peerDependencies: 391 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 392 | typescript: '*' 393 | peerDependenciesMeta: 394 | typescript: 395 | optional: true 396 | dependencies: 397 | '@typescript-eslint/scope-manager': 5.29.0 398 | '@typescript-eslint/types': 5.29.0 399 | '@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4) 400 | debug: 4.3.4 401 | eslint: 8.48.0 402 | typescript: 4.7.4 403 | transitivePeerDependencies: 404 | - supports-color 405 | dev: true 406 | 407 | /@typescript-eslint/scope-manager@5.29.0: 408 | resolution: {integrity: sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==} 409 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 410 | dependencies: 411 | '@typescript-eslint/types': 5.29.0 412 | '@typescript-eslint/visitor-keys': 5.29.0 413 | dev: true 414 | 415 | /@typescript-eslint/type-utils@5.29.0(eslint@8.48.0)(typescript@4.7.4): 416 | resolution: {integrity: sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==} 417 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 418 | peerDependencies: 419 | eslint: '*' 420 | typescript: '*' 421 | peerDependenciesMeta: 422 | typescript: 423 | optional: true 424 | dependencies: 425 | '@typescript-eslint/utils': 5.29.0(eslint@8.48.0)(typescript@4.7.4) 426 | debug: 4.3.4 427 | eslint: 8.48.0 428 | tsutils: 3.21.0(typescript@4.7.4) 429 | typescript: 4.7.4 430 | transitivePeerDependencies: 431 | - supports-color 432 | dev: true 433 | 434 | /@typescript-eslint/types@5.29.0: 435 | resolution: {integrity: sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==} 436 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 437 | dev: true 438 | 439 | /@typescript-eslint/typescript-estree@5.29.0(typescript@4.7.4): 440 | resolution: {integrity: sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==} 441 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 442 | peerDependencies: 443 | typescript: '*' 444 | peerDependenciesMeta: 445 | typescript: 446 | optional: true 447 | dependencies: 448 | '@typescript-eslint/types': 5.29.0 449 | '@typescript-eslint/visitor-keys': 5.29.0 450 | debug: 4.3.4 451 | globby: 11.1.0 452 | is-glob: 4.0.3 453 | semver: 7.5.4 454 | tsutils: 3.21.0(typescript@4.7.4) 455 | typescript: 4.7.4 456 | transitivePeerDependencies: 457 | - supports-color 458 | dev: true 459 | 460 | /@typescript-eslint/utils@5.29.0(eslint@8.48.0)(typescript@4.7.4): 461 | resolution: {integrity: sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==} 462 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 463 | peerDependencies: 464 | eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 465 | dependencies: 466 | '@types/json-schema': 7.0.12 467 | '@typescript-eslint/scope-manager': 5.29.0 468 | '@typescript-eslint/types': 5.29.0 469 | '@typescript-eslint/typescript-estree': 5.29.0(typescript@4.7.4) 470 | eslint: 8.48.0 471 | eslint-scope: 5.1.1 472 | eslint-utils: 3.0.0(eslint@8.48.0) 473 | transitivePeerDependencies: 474 | - supports-color 475 | - typescript 476 | dev: true 477 | 478 | /@typescript-eslint/visitor-keys@5.29.0: 479 | resolution: {integrity: sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==} 480 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 481 | dependencies: 482 | '@typescript-eslint/types': 5.29.0 483 | eslint-visitor-keys: 3.4.3 484 | dev: true 485 | 486 | /acorn-jsx@5.3.2(acorn@8.10.0): 487 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 488 | peerDependencies: 489 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 490 | dependencies: 491 | acorn: 8.10.0 492 | dev: true 493 | 494 | /acorn@8.10.0: 495 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} 496 | engines: {node: '>=0.4.0'} 497 | hasBin: true 498 | dev: true 499 | 500 | /ajv@6.12.6: 501 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 502 | dependencies: 503 | fast-deep-equal: 3.1.3 504 | fast-json-stable-stringify: 2.1.0 505 | json-schema-traverse: 0.4.1 506 | uri-js: 4.4.1 507 | dev: true 508 | 509 | /ansi-regex@5.0.1: 510 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 511 | engines: {node: '>=8'} 512 | dev: true 513 | 514 | /ansi-styles@4.3.0: 515 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 516 | engines: {node: '>=8'} 517 | dependencies: 518 | color-convert: 2.0.1 519 | dev: true 520 | 521 | /argparse@2.0.1: 522 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 523 | dev: true 524 | 525 | /array-union@2.1.0: 526 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 527 | engines: {node: '>=8'} 528 | dev: true 529 | 530 | /asynckit@0.4.0: 531 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} 532 | dev: false 533 | 534 | /balanced-match@1.0.2: 535 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 536 | dev: true 537 | 538 | /brace-expansion@1.1.11: 539 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 540 | dependencies: 541 | balanced-match: 1.0.2 542 | concat-map: 0.0.1 543 | dev: true 544 | 545 | /braces@3.0.2: 546 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 547 | engines: {node: '>=8'} 548 | dependencies: 549 | fill-range: 7.0.1 550 | dev: true 551 | 552 | /builtin-modules@3.3.0: 553 | resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} 554 | engines: {node: '>=6'} 555 | dev: true 556 | 557 | /callsites@3.1.0: 558 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 559 | engines: {node: '>=6'} 560 | dev: true 561 | 562 | /chalk@4.1.2: 563 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 564 | engines: {node: '>=10'} 565 | dependencies: 566 | ansi-styles: 4.3.0 567 | supports-color: 7.2.0 568 | dev: true 569 | 570 | /color-convert@2.0.1: 571 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 572 | engines: {node: '>=7.0.0'} 573 | dependencies: 574 | color-name: 1.1.4 575 | dev: true 576 | 577 | /color-name@1.1.4: 578 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 579 | dev: true 580 | 581 | /combined-stream@1.0.8: 582 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} 583 | engines: {node: '>= 0.8'} 584 | dependencies: 585 | delayed-stream: 1.0.0 586 | dev: false 587 | 588 | /concat-map@0.0.1: 589 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 590 | dev: true 591 | 592 | /cross-spawn@7.0.3: 593 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 594 | engines: {node: '>= 8'} 595 | dependencies: 596 | path-key: 3.1.1 597 | shebang-command: 2.0.0 598 | which: 2.0.2 599 | dev: true 600 | 601 | /data-uri-to-buffer@4.0.1: 602 | resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} 603 | engines: {node: '>= 12'} 604 | dev: false 605 | 606 | /debug@4.3.4: 607 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 608 | engines: {node: '>=6.0'} 609 | peerDependencies: 610 | supports-color: '*' 611 | peerDependenciesMeta: 612 | supports-color: 613 | optional: true 614 | dependencies: 615 | ms: 2.1.2 616 | dev: true 617 | 618 | /deep-is@0.1.4: 619 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 620 | dev: true 621 | 622 | /delayed-stream@1.0.0: 623 | resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} 624 | engines: {node: '>=0.4.0'} 625 | dev: false 626 | 627 | /dir-glob@3.0.1: 628 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 629 | engines: {node: '>=8'} 630 | dependencies: 631 | path-type: 4.0.0 632 | dev: true 633 | 634 | /doctrine@3.0.0: 635 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} 636 | engines: {node: '>=6.0.0'} 637 | dependencies: 638 | esutils: 2.0.3 639 | dev: true 640 | 641 | /esbuild@0.17.3: 642 | resolution: {integrity: sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==} 643 | engines: {node: '>=12'} 644 | hasBin: true 645 | requiresBuild: true 646 | optionalDependencies: 647 | '@esbuild/android-arm': 0.17.3 648 | '@esbuild/android-arm64': 0.17.3 649 | '@esbuild/android-x64': 0.17.3 650 | '@esbuild/darwin-arm64': 0.17.3 651 | '@esbuild/darwin-x64': 0.17.3 652 | '@esbuild/freebsd-arm64': 0.17.3 653 | '@esbuild/freebsd-x64': 0.17.3 654 | '@esbuild/linux-arm': 0.17.3 655 | '@esbuild/linux-arm64': 0.17.3 656 | '@esbuild/linux-ia32': 0.17.3 657 | '@esbuild/linux-loong64': 0.17.3 658 | '@esbuild/linux-mips64el': 0.17.3 659 | '@esbuild/linux-ppc64': 0.17.3 660 | '@esbuild/linux-riscv64': 0.17.3 661 | '@esbuild/linux-s390x': 0.17.3 662 | '@esbuild/linux-x64': 0.17.3 663 | '@esbuild/netbsd-x64': 0.17.3 664 | '@esbuild/openbsd-x64': 0.17.3 665 | '@esbuild/sunos-x64': 0.17.3 666 | '@esbuild/win32-arm64': 0.17.3 667 | '@esbuild/win32-ia32': 0.17.3 668 | '@esbuild/win32-x64': 0.17.3 669 | dev: true 670 | 671 | /escape-string-regexp@4.0.0: 672 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 673 | engines: {node: '>=10'} 674 | dev: true 675 | 676 | /eslint-scope@5.1.1: 677 | resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} 678 | engines: {node: '>=8.0.0'} 679 | dependencies: 680 | esrecurse: 4.3.0 681 | estraverse: 4.3.0 682 | dev: true 683 | 684 | /eslint-scope@7.2.2: 685 | resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} 686 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 687 | dependencies: 688 | esrecurse: 4.3.0 689 | estraverse: 5.3.0 690 | dev: true 691 | 692 | /eslint-utils@3.0.0(eslint@8.48.0): 693 | resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} 694 | engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} 695 | peerDependencies: 696 | eslint: '>=5' 697 | dependencies: 698 | eslint: 8.48.0 699 | eslint-visitor-keys: 2.1.0 700 | dev: true 701 | 702 | /eslint-visitor-keys@2.1.0: 703 | resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} 704 | engines: {node: '>=10'} 705 | dev: true 706 | 707 | /eslint-visitor-keys@3.4.3: 708 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 709 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 710 | dev: true 711 | 712 | /eslint@8.48.0: 713 | resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} 714 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 715 | hasBin: true 716 | dependencies: 717 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) 718 | '@eslint-community/regexpp': 4.8.0 719 | '@eslint/eslintrc': 2.1.2 720 | '@eslint/js': 8.48.0 721 | '@humanwhocodes/config-array': 0.11.11 722 | '@humanwhocodes/module-importer': 1.0.1 723 | '@nodelib/fs.walk': 1.2.8 724 | ajv: 6.12.6 725 | chalk: 4.1.2 726 | cross-spawn: 7.0.3 727 | debug: 4.3.4 728 | doctrine: 3.0.0 729 | escape-string-regexp: 4.0.0 730 | eslint-scope: 7.2.2 731 | eslint-visitor-keys: 3.4.3 732 | espree: 9.6.1 733 | esquery: 1.5.0 734 | esutils: 2.0.3 735 | fast-deep-equal: 3.1.3 736 | file-entry-cache: 6.0.1 737 | find-up: 5.0.0 738 | glob-parent: 6.0.2 739 | globals: 13.21.0 740 | graphemer: 1.4.0 741 | ignore: 5.2.4 742 | imurmurhash: 0.1.4 743 | is-glob: 4.0.3 744 | is-path-inside: 3.0.3 745 | js-yaml: 4.1.0 746 | json-stable-stringify-without-jsonify: 1.0.1 747 | levn: 0.4.1 748 | lodash.merge: 4.6.2 749 | minimatch: 3.1.2 750 | natural-compare: 1.4.0 751 | optionator: 0.9.3 752 | strip-ansi: 6.0.1 753 | text-table: 0.2.0 754 | transitivePeerDependencies: 755 | - supports-color 756 | dev: true 757 | 758 | /espree@9.6.1: 759 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} 760 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 761 | dependencies: 762 | acorn: 8.10.0 763 | acorn-jsx: 5.3.2(acorn@8.10.0) 764 | eslint-visitor-keys: 3.4.3 765 | dev: true 766 | 767 | /esquery@1.5.0: 768 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} 769 | engines: {node: '>=0.10'} 770 | dependencies: 771 | estraverse: 5.3.0 772 | dev: true 773 | 774 | /esrecurse@4.3.0: 775 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 776 | engines: {node: '>=4.0'} 777 | dependencies: 778 | estraverse: 5.3.0 779 | dev: true 780 | 781 | /estraverse@4.3.0: 782 | resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} 783 | engines: {node: '>=4.0'} 784 | dev: true 785 | 786 | /estraverse@5.3.0: 787 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 788 | engines: {node: '>=4.0'} 789 | dev: true 790 | 791 | /esutils@2.0.3: 792 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 793 | engines: {node: '>=0.10.0'} 794 | dev: true 795 | 796 | /fast-deep-equal@3.1.3: 797 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 798 | dev: true 799 | 800 | /fast-glob@3.3.1: 801 | resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} 802 | engines: {node: '>=8.6.0'} 803 | dependencies: 804 | '@nodelib/fs.stat': 2.0.5 805 | '@nodelib/fs.walk': 1.2.8 806 | glob-parent: 5.1.2 807 | merge2: 1.4.1 808 | micromatch: 4.0.5 809 | dev: true 810 | 811 | /fast-json-stable-stringify@2.1.0: 812 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 813 | dev: true 814 | 815 | /fast-levenshtein@2.0.6: 816 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 817 | dev: true 818 | 819 | /fastq@1.15.0: 820 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 821 | dependencies: 822 | reusify: 1.0.4 823 | dev: true 824 | 825 | /fetch-blob@3.2.0: 826 | resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} 827 | engines: {node: ^12.20 || >= 14.13} 828 | dependencies: 829 | node-domexception: 1.0.0 830 | web-streams-polyfill: 3.2.1 831 | dev: false 832 | 833 | /file-entry-cache@6.0.1: 834 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} 835 | engines: {node: ^10.12.0 || >=12.0.0} 836 | dependencies: 837 | flat-cache: 3.1.0 838 | dev: true 839 | 840 | /fill-range@7.0.1: 841 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 842 | engines: {node: '>=8'} 843 | dependencies: 844 | to-regex-range: 5.0.1 845 | dev: true 846 | 847 | /find-up@5.0.0: 848 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 849 | engines: {node: '>=10'} 850 | dependencies: 851 | locate-path: 6.0.0 852 | path-exists: 4.0.0 853 | dev: true 854 | 855 | /flat-cache@3.1.0: 856 | resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} 857 | engines: {node: '>=12.0.0'} 858 | dependencies: 859 | flatted: 3.2.7 860 | keyv: 4.5.3 861 | rimraf: 3.0.2 862 | dev: true 863 | 864 | /flatted@3.2.7: 865 | resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} 866 | dev: true 867 | 868 | /form-data@4.0.0: 869 | resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} 870 | engines: {node: '>= 6'} 871 | dependencies: 872 | asynckit: 0.4.0 873 | combined-stream: 1.0.8 874 | mime-types: 2.1.35 875 | dev: false 876 | 877 | /formdata-polyfill@4.0.10: 878 | resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} 879 | engines: {node: '>=12.20.0'} 880 | dependencies: 881 | fetch-blob: 3.2.0 882 | dev: false 883 | 884 | /fs.realpath@1.0.0: 885 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 886 | dev: true 887 | 888 | /functional-red-black-tree@1.0.1: 889 | resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} 890 | dev: true 891 | 892 | /glob-parent@5.1.2: 893 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 894 | engines: {node: '>= 6'} 895 | dependencies: 896 | is-glob: 4.0.3 897 | dev: true 898 | 899 | /glob-parent@6.0.2: 900 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 901 | engines: {node: '>=10.13.0'} 902 | dependencies: 903 | is-glob: 4.0.3 904 | dev: true 905 | 906 | /glob@7.2.3: 907 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 908 | dependencies: 909 | fs.realpath: 1.0.0 910 | inflight: 1.0.6 911 | inherits: 2.0.4 912 | minimatch: 3.1.2 913 | once: 1.4.0 914 | path-is-absolute: 1.0.1 915 | dev: true 916 | 917 | /globals@13.21.0: 918 | resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} 919 | engines: {node: '>=8'} 920 | dependencies: 921 | type-fest: 0.20.2 922 | dev: true 923 | 924 | /globby@11.1.0: 925 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 926 | engines: {node: '>=10'} 927 | dependencies: 928 | array-union: 2.1.0 929 | dir-glob: 3.0.1 930 | fast-glob: 3.3.1 931 | ignore: 5.2.4 932 | merge2: 1.4.1 933 | slash: 3.0.0 934 | dev: true 935 | 936 | /graphemer@1.4.0: 937 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 938 | dev: true 939 | 940 | /has-flag@4.0.0: 941 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 942 | engines: {node: '>=8'} 943 | dev: true 944 | 945 | /ignore@5.2.4: 946 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 947 | engines: {node: '>= 4'} 948 | dev: true 949 | 950 | /import-fresh@3.3.0: 951 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 952 | engines: {node: '>=6'} 953 | dependencies: 954 | parent-module: 1.0.1 955 | resolve-from: 4.0.0 956 | dev: true 957 | 958 | /imurmurhash@0.1.4: 959 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 960 | engines: {node: '>=0.8.19'} 961 | dev: true 962 | 963 | /inflight@1.0.6: 964 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 965 | dependencies: 966 | once: 1.4.0 967 | wrappy: 1.0.2 968 | dev: true 969 | 970 | /inherits@2.0.4: 971 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 972 | dev: true 973 | 974 | /is-extglob@2.1.1: 975 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 976 | engines: {node: '>=0.10.0'} 977 | dev: true 978 | 979 | /is-glob@4.0.3: 980 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 981 | engines: {node: '>=0.10.0'} 982 | dependencies: 983 | is-extglob: 2.1.1 984 | dev: true 985 | 986 | /is-number@7.0.0: 987 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 988 | engines: {node: '>=0.12.0'} 989 | dev: true 990 | 991 | /is-path-inside@3.0.3: 992 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} 993 | engines: {node: '>=8'} 994 | dev: true 995 | 996 | /isexe@2.0.0: 997 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 998 | dev: true 999 | 1000 | /js-yaml@4.1.0: 1001 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 1002 | hasBin: true 1003 | dependencies: 1004 | argparse: 2.0.1 1005 | dev: true 1006 | 1007 | /json-buffer@3.0.1: 1008 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 1009 | dev: true 1010 | 1011 | /json-schema-traverse@0.4.1: 1012 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 1013 | dev: true 1014 | 1015 | /json-stable-stringify-without-jsonify@1.0.1: 1016 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 1017 | dev: true 1018 | 1019 | /keyv@4.5.3: 1020 | resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} 1021 | dependencies: 1022 | json-buffer: 3.0.1 1023 | dev: true 1024 | 1025 | /levn@0.4.1: 1026 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 1027 | engines: {node: '>= 0.8.0'} 1028 | dependencies: 1029 | prelude-ls: 1.2.1 1030 | type-check: 0.4.0 1031 | dev: true 1032 | 1033 | /locate-path@6.0.0: 1034 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 1035 | engines: {node: '>=10'} 1036 | dependencies: 1037 | p-locate: 5.0.0 1038 | dev: true 1039 | 1040 | /lodash.merge@4.6.2: 1041 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 1042 | dev: true 1043 | 1044 | /lru-cache@6.0.0: 1045 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 1046 | engines: {node: '>=10'} 1047 | dependencies: 1048 | yallist: 4.0.0 1049 | dev: true 1050 | 1051 | /merge2@1.4.1: 1052 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1053 | engines: {node: '>= 8'} 1054 | dev: true 1055 | 1056 | /micromatch@4.0.5: 1057 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 1058 | engines: {node: '>=8.6'} 1059 | dependencies: 1060 | braces: 3.0.2 1061 | picomatch: 2.3.1 1062 | dev: true 1063 | 1064 | /mime-db@1.52.0: 1065 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 1066 | engines: {node: '>= 0.6'} 1067 | dev: false 1068 | 1069 | /mime-types@2.1.35: 1070 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 1071 | engines: {node: '>= 0.6'} 1072 | dependencies: 1073 | mime-db: 1.52.0 1074 | dev: false 1075 | 1076 | /minimatch@3.1.2: 1077 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1078 | dependencies: 1079 | brace-expansion: 1.1.11 1080 | dev: true 1081 | 1082 | /moment@2.29.4: 1083 | resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} 1084 | dev: true 1085 | 1086 | /ms@2.1.2: 1087 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1088 | dev: true 1089 | 1090 | /natural-compare@1.4.0: 1091 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1092 | dev: true 1093 | 1094 | /node-domexception@1.0.0: 1095 | resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} 1096 | engines: {node: '>=10.5.0'} 1097 | dev: false 1098 | 1099 | /node-fetch@3.3.2: 1100 | resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} 1101 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1102 | dependencies: 1103 | data-uri-to-buffer: 4.0.1 1104 | fetch-blob: 3.2.0 1105 | formdata-polyfill: 4.0.10 1106 | dev: false 1107 | 1108 | /obsidian@1.4.4(@codemirror/state@6.2.1)(@codemirror/view@6.17.1): 1109 | resolution: {integrity: sha512-q2V5GNT/M40uYOENdVw5kovPSoaO6vppiiyBCkIqWgKp4oN654jA/GQ0OaNBA7p5NdfS245QCeRgCFQ42wOZiw==} 1110 | peerDependencies: 1111 | '@codemirror/state': ^6.0.0 1112 | '@codemirror/view': ^6.0.0 1113 | dependencies: 1114 | '@codemirror/state': 6.2.1 1115 | '@codemirror/view': 6.17.1 1116 | '@types/codemirror': 5.60.8 1117 | moment: 2.29.4 1118 | dev: true 1119 | 1120 | /once@1.4.0: 1121 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1122 | dependencies: 1123 | wrappy: 1.0.2 1124 | dev: true 1125 | 1126 | /optionator@0.9.3: 1127 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} 1128 | engines: {node: '>= 0.8.0'} 1129 | dependencies: 1130 | '@aashutoshrathi/word-wrap': 1.2.6 1131 | deep-is: 0.1.4 1132 | fast-levenshtein: 2.0.6 1133 | levn: 0.4.1 1134 | prelude-ls: 1.2.1 1135 | type-check: 0.4.0 1136 | dev: true 1137 | 1138 | /p-limit@3.1.0: 1139 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1140 | engines: {node: '>=10'} 1141 | dependencies: 1142 | yocto-queue: 0.1.0 1143 | dev: true 1144 | 1145 | /p-locate@5.0.0: 1146 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1147 | engines: {node: '>=10'} 1148 | dependencies: 1149 | p-limit: 3.1.0 1150 | dev: true 1151 | 1152 | /parent-module@1.0.1: 1153 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1154 | engines: {node: '>=6'} 1155 | dependencies: 1156 | callsites: 3.1.0 1157 | dev: true 1158 | 1159 | /path-exists@4.0.0: 1160 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1161 | engines: {node: '>=8'} 1162 | dev: true 1163 | 1164 | /path-is-absolute@1.0.1: 1165 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1166 | engines: {node: '>=0.10.0'} 1167 | dev: true 1168 | 1169 | /path-key@3.1.1: 1170 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1171 | engines: {node: '>=8'} 1172 | dev: true 1173 | 1174 | /path-type@4.0.0: 1175 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1176 | engines: {node: '>=8'} 1177 | dev: true 1178 | 1179 | /picomatch@2.3.1: 1180 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1181 | engines: {node: '>=8.6'} 1182 | dev: true 1183 | 1184 | /prelude-ls@1.2.1: 1185 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1186 | engines: {node: '>= 0.8.0'} 1187 | dev: true 1188 | 1189 | /punycode@2.3.0: 1190 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 1191 | engines: {node: '>=6'} 1192 | dev: true 1193 | 1194 | /queue-microtask@1.2.3: 1195 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1196 | dev: true 1197 | 1198 | /regexpp@3.2.0: 1199 | resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} 1200 | engines: {node: '>=8'} 1201 | dev: true 1202 | 1203 | /resolve-from@4.0.0: 1204 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1205 | engines: {node: '>=4'} 1206 | dev: true 1207 | 1208 | /reusify@1.0.4: 1209 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1210 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1211 | dev: true 1212 | 1213 | /rimraf@3.0.2: 1214 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 1215 | hasBin: true 1216 | dependencies: 1217 | glob: 7.2.3 1218 | dev: true 1219 | 1220 | /run-parallel@1.2.0: 1221 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1222 | dependencies: 1223 | queue-microtask: 1.2.3 1224 | dev: true 1225 | 1226 | /semver@7.5.4: 1227 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 1228 | engines: {node: '>=10'} 1229 | hasBin: true 1230 | dependencies: 1231 | lru-cache: 6.0.0 1232 | dev: true 1233 | 1234 | /shebang-command@2.0.0: 1235 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1236 | engines: {node: '>=8'} 1237 | dependencies: 1238 | shebang-regex: 3.0.0 1239 | dev: true 1240 | 1241 | /shebang-regex@3.0.0: 1242 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1243 | engines: {node: '>=8'} 1244 | dev: true 1245 | 1246 | /slash@3.0.0: 1247 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1248 | engines: {node: '>=8'} 1249 | dev: true 1250 | 1251 | /strip-ansi@6.0.1: 1252 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1253 | engines: {node: '>=8'} 1254 | dependencies: 1255 | ansi-regex: 5.0.1 1256 | dev: true 1257 | 1258 | /strip-json-comments@3.1.1: 1259 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1260 | engines: {node: '>=8'} 1261 | dev: true 1262 | 1263 | /style-mod@4.1.0: 1264 | resolution: {integrity: sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==} 1265 | dev: true 1266 | 1267 | /supports-color@7.2.0: 1268 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1269 | engines: {node: '>=8'} 1270 | dependencies: 1271 | has-flag: 4.0.0 1272 | dev: true 1273 | 1274 | /text-table@0.2.0: 1275 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 1276 | dev: true 1277 | 1278 | /to-regex-range@5.0.1: 1279 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1280 | engines: {node: '>=8.0'} 1281 | dependencies: 1282 | is-number: 7.0.0 1283 | dev: true 1284 | 1285 | /tslib@1.14.1: 1286 | resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} 1287 | dev: true 1288 | 1289 | /tslib@2.4.0: 1290 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} 1291 | dev: true 1292 | 1293 | /tsutils@3.21.0(typescript@4.7.4): 1294 | resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} 1295 | engines: {node: '>= 6'} 1296 | peerDependencies: 1297 | 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' 1298 | dependencies: 1299 | tslib: 1.14.1 1300 | typescript: 4.7.4 1301 | dev: true 1302 | 1303 | /type-check@0.4.0: 1304 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1305 | engines: {node: '>= 0.8.0'} 1306 | dependencies: 1307 | prelude-ls: 1.2.1 1308 | dev: true 1309 | 1310 | /type-fest@0.20.2: 1311 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} 1312 | engines: {node: '>=10'} 1313 | dev: true 1314 | 1315 | /typescript@4.7.4: 1316 | resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} 1317 | engines: {node: '>=4.2.0'} 1318 | hasBin: true 1319 | dev: true 1320 | 1321 | /uri-js@4.4.1: 1322 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1323 | dependencies: 1324 | punycode: 2.3.0 1325 | dev: true 1326 | 1327 | /w3c-keyname@2.2.8: 1328 | resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} 1329 | dev: true 1330 | 1331 | /web-streams-polyfill@3.2.1: 1332 | resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} 1333 | engines: {node: '>= 8'} 1334 | dev: false 1335 | 1336 | /which@2.0.2: 1337 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1338 | engines: {node: '>= 8'} 1339 | hasBin: true 1340 | dependencies: 1341 | isexe: 2.0.0 1342 | dev: true 1343 | 1344 | /wrappy@1.0.2: 1345 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1346 | dev: true 1347 | 1348 | /yallist@4.0.0: 1349 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1350 | dev: true 1351 | 1352 | /yocto-queue@0.1.0: 1353 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1354 | engines: {node: '>=10'} 1355 | dev: true 1356 | --------------------------------------------------------------------------------