[
  {
    "path": ".commitlintrc.json",
    "content": "{\n  \"extends\": [\"@commitlint/config-conventional\"]\n}\n"
  },
  {
    "path": ".dockerignore",
    "content": "**/node_modules\n*/node_modules\nnode_modules\nDockerfile\n.*\n*/.*\n!.env\n"
  },
  {
    "path": ".editorconfig",
    "content": "# Editor configuration, see http://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = tab\nindent_size = 2\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n"
  },
  {
    "path": ".eslintignore",
    "content": "docker-compose\nkubernetes\n"
  },
  {
    "path": ".eslintrc.cjs",
    "content": "module.exports = {\n  root: true,\n  extends: ['@antfu'],\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "\"*.vue\"    eol=lf\n\"*.js\"     eol=lf\n\"*.ts\"     eol=lf\n\"*.jsx\"    eol=lf\n\"*.tsx\"    eol=lf\n\"*.cjs\"    eol=lf\n\"*.cts\"    eol=lf\n\"*.mjs\"    eol=lf\n\"*.mts\"    eol=lf\n\"*.json\"   eol=lf\n\"*.html\"   eol=lf\n\"*.css\"    eol=lf\n\"*.less\"   eol=lf\n\"*.scss\"   eol=lf\n\"*.sass\"   eol=lf\n\"*.styl\"   eol=lf\n\"*.md\"     eol=lf\n"
  },
  {
    "path": ".github/workflows/desktop.yml",
    "content": "name: Release Desktop\n\non:\n  workflow_dispatch:\n  release:\n    types: [published]\n\njobs:\n  create-release:\n    permissions:\n      contents: write\n    runs-on: ubuntu-latest\n    outputs:\n      release_id: ${{ steps.create-release.outputs.result }}\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: setup node\n        uses: actions/setup-node@v3\n        with:\n          node-version: 20\n      - name: get version\n        run: echo \"PACKAGE_VERSION=$(node -p \"require('./package.json').version\")\" >> $GITHUB_ENV\n      - name: create release\n        id: create-release\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const { data } = await github.rest.repos.getLatestRelease({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n            })\n            return data.id\n\n  build-tauri:\n    needs: create-release\n    permissions:\n      contents: write\n    strategy:\n      fail-fast: false\n      matrix:\n        config:\n          # - os: ubuntu-latest\n          #   arch: x86_64\n          #   rust_target: x86_64-unknown-linux-gnu\n          - os: macos-latest\n            arch: aarch64\n            rust_target: x86_64-apple-darwin,aarch64-apple-darwin\n          - os: windows-latest\n            arch: x86_64\n            rust_target: x86_64-pc-windows-msvc\n\n    runs-on: ${{ matrix.config.os }}\n    steps:\n      - uses: actions/checkout@v3\n      - name: setup node\n        uses: actions/setup-node@v3\n        with:\n          node-version: 20\n          cache: 'yarn'\n      - name: install Rust stable\n        uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: ${{ matrix.config.rust_target }}\n      - uses: Swatinem/rust-cache@v2\n        with:\n          key: ${{ matrix.config.os }}\n      - name: install dependencies (ubuntu only)\n        if: matrix.config.os == 'ubuntu-latest'\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf\n      - name: install frontend dependencies\n        #run: yarn config set registry https://registry.npmjs.org/ && yarn install\n        #run: yarn install # change this to npm or pnpm or yarn depending on which one you use\n        # run: |\n        #   yarn config set registry https://registry.npmjs.org/\n        #   yarn cache clean\n        #   yarn install\n        run: |\n          npm install -g pnpm\n          pnpm install\n      - uses: tauri-apps/tauri-action@v0\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}\n          TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}\n        with:\n          releaseId: ${{ needs.create-release.outputs.release_id }}\n          args: ${{ matrix.config.os == 'macos-latest' && '--target universal-apple-darwin' || '' }}\n\n  publish-release:\n    permissions:\n      contents: write\n    runs-on: ubuntu-latest\n    needs: [create-release, build-tauri]\n\n    steps:\n      - name: publish release\n        id: publish-release\n        uses: actions/github-script@v6\n        env:\n          release_id: ${{ needs.create-release.outputs.release_id }}\n        with:\n          script: |\n            github.rest.repos.updateRelease({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              release_id: process.env.release_id,\n              draft: false,\n              prerelease: false\n            })\n"
  },
  {
    "path": ".github/workflows/docker-image.yml",
    "content": "name: Publish Docker image\n\non:\n  workflow_dispatch:\n  release:\n    types: [published]\n\njobs:\n  push_to_registry:\n    name: Push Docker image to Docker Hub\n    runs-on: ubuntu-latest\n    steps:\n      -\n        name: Check out the repo\n        uses: actions/checkout@v3\n      - run: |\n          echo 本次构建的版本为：${{ github.ref_name }}\n          echo 账号：${{ secrets.DOCKER_USERNAME }}\n          env\n      -\n        name: Log in to Docker Hub\n        uses: docker/login-action@v2\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n      \n      - \n        name: Extract metadata (tags, labels) for Docker\n        id: meta\n        uses: docker/metadata-action@v4\n        with:\n          images: ydlhero/chatgpt-web-midjourney-proxy\n          tags: |\n            type=raw,value=latest\n            type=ref,event=tag\n      \n      - \n        name: Set up QEMU\n        uses: docker/setup-qemu-action@v2\n\n      - \n        name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v2\n      \n      - \n        name: Build and push Docker image\n        uses: docker/build-push-action@v4\n        with:\n          context: .\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n          cache-from: ${{ inputs.use-cache == 'true' && 'type=gha' || 'type=local,src=/tmp' }}\n          cache-to: ${{ inputs.use-cache == 'true' && 'type=gha, mode=max' || 'type=local,dest=/tmp' }}\n            \n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\n.DS_Store\ndist\ndist-ssr\ncoverage\n*.local\n\n/cypress/videos/\n/cypress/screenshots/\n\n# Editor directories and files\n.vscode/*\n!.vscode/settings.json\n!.vscode/extensions.json\n.idea\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n# Environment variables files\n/service/.env\n/service/uploads"
  },
  {
    "path": ".husky/commit-msg",
    "content": "#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\nnpx --no -- commitlint --edit \n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\nnpx lint-staged\n"
  },
  {
    "path": ".npmrc",
    "content": "strict-peer-dependencies=false\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\"Vue.volar\", \"dbaeumer.vscode-eslint\"]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"prettier.enable\": false,\n  \"editor.formatOnSave\": false,\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\"\n  },\n  \"eslint.validate\": [\n    \"javascript\",\n    \"javascriptreact\",\n    \"typescript\",\n    \"typescriptreact\",\n    \"vue\",\n    \"html\",\n    \"json\",\n    \"jsonc\",\n    \"json5\",\n    \"yaml\",\n    \"yml\",\n    \"markdown\"\n  ],\n  \"cSpell.words\": [\n    \"antfu\",\n    \"axios\",\n    \"bumpp\",\n    \"chatgpt\",\n    \"chenzhaoyu\",\n    \"commitlint\",\n    \"davinci\",\n    \"dockerhub\",\n    \"esno\",\n    \"GPTAPI\",\n    \"highlightjs\",\n    \"hljs\",\n    \"iconify\",\n    \"katex\",\n    \"katexmath\",\n    \"linkify\",\n    \"logprobs\",\n    \"mdhljs\",\n    \"mila\",\n    \"nodata\",\n    \"OPENAI\",\n    \"pinia\",\n    \"Popconfirm\",\n    \"rushstack\",\n    \"Sider\",\n    \"tailwindcss\",\n    \"traptitech\",\n    \"tsup\",\n    \"Typecheck\",\n    \"unplugin\",\n    \"VITE\",\n    \"vueuse\",\n    \"Zhao\"\n  ],\n  \"i18n-ally.enabledParsers\": [\n    \"ts\"\n  ],\n  \"i18n-ally.sortKeys\": true,\n  \"i18n-ally.keepFulfilled\": true,\n  \"i18n-ally.localesPaths\": [\n    \"src/locales\"\n  ],\n  \"i18n-ally.keystyle\": \"nested\"\n}\n"
  },
  {
    "path": "2package-lock.json",
    "content": "{\n  \"name\": \"chatgpt-web\",\n  \"version\": \"2.10.9\",\n  \"lockfileVersion\": 2,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"chatgpt-web\",\n      \"version\": \"2.10.9\",\n      \"dependencies\": {\n        \"@traptitech/markdown-it-katex\": \"^3.6.0\",\n        \"@vueuse/core\": \"^9.13.0\",\n        \"highlight.js\": \"^11.7.0\",\n        \"html2canvas\": \"^1.4.1\",\n        \"katex\": \"^0.16.4\",\n        \"markdown-it\": \"^13.0.1\",\n        \"naive-ui\": \"^2.34.3\",\n        \"pinia\": \"^2.0.33\",\n        \"vue\": \"^3.2.47\",\n        \"vue-i18n\": \"^9.2.2\",\n        \"vue-router\": \"^4.1.6\"\n      },\n      \"devDependencies\": {\n        \"@antfu/eslint-config\": \"^0.35.3\",\n        \"@commitlint/cli\": \"^17.4.4\",\n        \"@commitlint/config-conventional\": \"^17.4.4\",\n        \"@iconify/vue\": \"^4.1.0\",\n        \"@types/crypto-js\": \"^4.1.1\",\n        \"@types/katex\": \"^0.16.0\",\n        \"@types/markdown-it\": \"^12.2.3\",\n        \"@types/markdown-it-link-attributes\": \"^3.0.1\",\n        \"@types/node\": \"^18.14.6\",\n        \"@vitejs/plugin-vue\": \"^4.0.0\",\n        \"autoprefixer\": \"^10.4.13\",\n        \"axios\": \"^1.3.4\",\n        \"crypto-js\": \"^4.1.1\",\n        \"eslint\": \"^8.35.0\",\n        \"husky\": \"^8.0.3\",\n        \"less\": \"^4.1.3\",\n        \"lint-staged\": \"^13.1.2\",\n        \"markdown-it-link-attributes\": \"^4.0.1\",\n        \"npm-run-all\": \"^4.1.5\",\n        \"postcss\": \"^8.4.21\",\n        \"rimraf\": \"^4.2.0\",\n        \"tailwindcss\": \"^3.2.7\",\n        \"typescript\": \"~4.9.5\",\n        \"vite\": \"^4.2.0\",\n        \"vite-plugin-pwa\": \"^0.14.4\",\n        \"vue-tsc\": \"^1.2.0\"\n      }\n    },\n    \"node_modules/@ampproject/remapping\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz\",\n      \"integrity\": \"sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.0\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@antfu/eslint-config\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-0.35.3.tgz\",\n      \"integrity\": \"sha512-wd0ry/TNqaZmniqkKtZKoCvpl55x9YbHgL5Ug3H9rVuUSqaNi9G9AjYlynQqn4/M1EhYYWO597Lu7f/fC+csrg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@antfu/eslint-config-vue\": \"0.35.3\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.53.0\",\n        \"@typescript-eslint/parser\": \"^5.53.0\",\n        \"eslint-plugin-eslint-comments\": \"^3.2.0\",\n        \"eslint-plugin-html\": \"^7.1.0\",\n        \"eslint-plugin-import\": \"^2.27.5\",\n        \"eslint-plugin-jsonc\": \"^2.6.0\",\n        \"eslint-plugin-n\": \"^15.6.1\",\n        \"eslint-plugin-promise\": \"^6.1.1\",\n        \"eslint-plugin-unicorn\": \"^45.0.2\",\n        \"eslint-plugin-vue\": \"^9.9.0\",\n        \"eslint-plugin-yml\": \"^1.5.0\",\n        \"jsonc-eslint-parser\": \"^2.1.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=7.4.0\"\n      }\n    },\n    \"node_modules/@antfu/eslint-config-basic\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-basic/-/eslint-config-basic-0.35.3.tgz\",\n      \"integrity\": \"sha512-NbWJKNgd3Ky3/ok2Z88cXNme/6I9otkiaB+FYLFgQE81sfMAhKpLKXtTSwzdcKMzhKDqUchAijt0BxjE/mcTJg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-plugin-antfu\": \"0.35.3\",\n        \"eslint-plugin-eslint-comments\": \"^3.2.0\",\n        \"eslint-plugin-html\": \"^7.1.0\",\n        \"eslint-plugin-import\": \"^2.27.5\",\n        \"eslint-plugin-jsonc\": \"^2.6.0\",\n        \"eslint-plugin-markdown\": \"^3.0.0\",\n        \"eslint-plugin-n\": \"^15.6.1\",\n        \"eslint-plugin-no-only-tests\": \"^3.1.0\",\n        \"eslint-plugin-promise\": \"^6.1.1\",\n        \"eslint-plugin-unicorn\": \"^45.0.2\",\n        \"eslint-plugin-unused-imports\": \"^2.0.0\",\n        \"eslint-plugin-yml\": \"^1.5.0\",\n        \"jsonc-eslint-parser\": \"^2.1.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=7.4.0\"\n      }\n    },\n    \"node_modules/@antfu/eslint-config-ts\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-ts/-/eslint-config-ts-0.35.3.tgz\",\n      \"integrity\": \"sha512-FS5hir2ghXYlJWAiB2bpT9oAr0kpSNmYbaJWWkztocJG95AORl4tWzxMTkLT+TxaOmhuwJszcrMTHy5RgHL8/w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@antfu/eslint-config-basic\": \"0.35.3\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.53.0\",\n        \"@typescript-eslint/parser\": \"^5.53.0\",\n        \"eslint-plugin-jest\": \"^27.2.1\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=7.4.0\",\n        \"typescript\": \">=3.9\"\n      }\n    },\n    \"node_modules/@antfu/eslint-config-vue\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-vue/-/eslint-config-vue-0.35.3.tgz\",\n      \"integrity\": \"sha512-BA3vGLyuzqtEUb9gfgE7YzBT+a4oUnQuUPasIUfN/BVXaEhRVYlMmUgxN4ekQLuzOgUjUH13lqplXtkLJ62t9g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@antfu/eslint-config-basic\": \"0.35.3\",\n        \"@antfu/eslint-config-ts\": \"0.35.3\",\n        \"eslint-plugin-vue\": \"^9.9.0\",\n        \"local-pkg\": \"^0.4.3\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=7.4.0\"\n      }\n    },\n    \"node_modules/@apideck/better-ajv-errors\": {\n      \"version\": \"0.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz\",\n      \"integrity\": \"sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"json-schema\": \"^0.4.0\",\n        \"jsonpointer\": \"^5.0.0\",\n        \"leven\": \"^3.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"peerDependencies\": {\n        \"ajv\": \">=8\"\n      }\n    },\n    \"node_modules/@babel/code-frame\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz\",\n      \"integrity\": \"sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/highlight\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/compat-data\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz\",\n      \"integrity\": \"sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/core\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz\",\n      \"integrity\": \"sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ampproject/remapping\": \"^2.2.0\",\n        \"@babel/code-frame\": \"^7.21.4\",\n        \"@babel/generator\": \"^7.21.4\",\n        \"@babel/helper-compilation-targets\": \"^7.21.4\",\n        \"@babel/helper-module-transforms\": \"^7.21.2\",\n        \"@babel/helpers\": \"^7.21.0\",\n        \"@babel/parser\": \"^7.21.4\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.4\",\n        \"@babel/types\": \"^7.21.4\",\n        \"convert-source-map\": \"^1.7.0\",\n        \"debug\": \"^4.1.0\",\n        \"gensync\": \"^1.0.0-beta.2\",\n        \"json5\": \"^2.2.2\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/babel\"\n      }\n    },\n    \"node_modules/@babel/core/node_modules/json5\": {\n      \"version\": \"2.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz\",\n      \"integrity\": \"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==\",\n      \"dev\": true,\n      \"bin\": {\n        \"json5\": \"lib/cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@babel/core/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/@babel/generator\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz\",\n      \"integrity\": \"sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.21.4\",\n        \"@jridgewell/gen-mapping\": \"^0.3.2\",\n        \"@jridgewell/trace-mapping\": \"^0.3.17\",\n        \"jsesc\": \"^2.5.1\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/generator/node_modules/jsesc\": {\n      \"version\": \"2.5.2\",\n      \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz\",\n      \"integrity\": \"sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==\",\n      \"dev\": true,\n      \"bin\": {\n        \"jsesc\": \"bin/jsesc\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/helper-annotate-as-pure\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz\",\n      \"integrity\": \"sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-builder-binary-assignment-operator-visitor\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz\",\n      \"integrity\": \"sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-explode-assignable-expression\": \"^7.18.6\",\n        \"@babel/types\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-compilation-targets\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz\",\n      \"integrity\": \"sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/compat-data\": \"^7.21.4\",\n        \"@babel/helper-validator-option\": \"^7.21.0\",\n        \"browserslist\": \"^4.21.3\",\n        \"lru-cache\": \"^5.1.1\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz\",\n      \"integrity\": \"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"yallist\": \"^3.0.2\"\n      }\n    },\n    \"node_modules/@babel/helper-compilation-targets/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/@babel/helper-compilation-targets/node_modules/yallist\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz\",\n      \"integrity\": \"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==\",\n      \"dev\": true\n    },\n    \"node_modules/@babel/helper-create-class-features-plugin\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz\",\n      \"integrity\": \"sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-member-expression-to-functions\": \"^7.21.0\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/helper-replace-supers\": \"^7.20.7\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/helper-create-regexp-features-plugin\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz\",\n      \"integrity\": \"sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"regexpu-core\": \"^5.3.1\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/helper-define-polyfill-provider\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz\",\n      \"integrity\": \"sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-compilation-targets\": \"^7.17.7\",\n        \"@babel/helper-plugin-utils\": \"^7.16.7\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.debounce\": \"^4.0.8\",\n        \"resolve\": \"^1.14.2\",\n        \"semver\": \"^6.1.2\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.4.0-0\"\n      }\n    },\n    \"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/@babel/helper-environment-visitor\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz\",\n      \"integrity\": \"sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-explode-assignable-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-function-name\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz\",\n      \"integrity\": \"sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/types\": \"^7.21.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-hoist-variables\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz\",\n      \"integrity\": \"sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-member-expression-to-functions\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz\",\n      \"integrity\": \"sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.21.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-module-imports\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz\",\n      \"integrity\": \"sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.21.4\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-module-transforms\": {\n      \"version\": \"7.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz\",\n      \"integrity\": \"sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-module-imports\": \"^7.18.6\",\n        \"@babel/helper-simple-access\": \"^7.20.2\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.2\",\n        \"@babel/types\": \"^7.21.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-optimise-call-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-plugin-utils\": {\n      \"version\": \"7.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz\",\n      \"integrity\": \"sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-remap-async-to-generator\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz\",\n      \"integrity\": \"sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-wrap-function\": \"^7.18.9\",\n        \"@babel/types\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/helper-replace-supers\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz\",\n      \"integrity\": \"sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-member-expression-to-functions\": \"^7.20.7\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.20.7\",\n        \"@babel/types\": \"^7.20.7\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-simple-access\": {\n      \"version\": \"7.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz\",\n      \"integrity\": \"sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-skip-transparent-expression-wrappers\": {\n      \"version\": \"7.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz\",\n      \"integrity\": \"sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.20.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-split-export-declaration\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz\",\n      \"integrity\": \"sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/types\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-string-parser\": {\n      \"version\": \"7.19.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz\",\n      \"integrity\": \"sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-validator-identifier\": {\n      \"version\": \"7.19.1\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz\",\n      \"integrity\": \"sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-validator-option\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz\",\n      \"integrity\": \"sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helper-wrap-function\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz\",\n      \"integrity\": \"sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-function-name\": \"^7.19.0\",\n        \"@babel/template\": \"^7.18.10\",\n        \"@babel/traverse\": \"^7.20.5\",\n        \"@babel/types\": \"^7.20.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/helpers\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz\",\n      \"integrity\": \"sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.0\",\n        \"@babel/types\": \"^7.21.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/highlight\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz\",\n      \"integrity\": \"sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-validator-identifier\": \"^7.18.6\",\n        \"chalk\": \"^2.0.0\",\n        \"js-tokens\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/ansi-styles\": {\n      \"version\": \"3.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz\",\n      \"integrity\": \"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-convert\": \"^1.9.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/chalk\": {\n      \"version\": \"2.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz\",\n      \"integrity\": \"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^3.2.1\",\n        \"escape-string-regexp\": \"^1.0.5\",\n        \"supports-color\": \"^5.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/color-convert\": {\n      \"version\": \"1.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz\",\n      \"integrity\": \"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-name\": \"1.1.3\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/color-name\": {\n      \"version\": \"1.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz\",\n      \"integrity\": \"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==\",\n      \"dev\": true\n    },\n    \"node_modules/@babel/highlight/node_modules/escape-string-regexp\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n      \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.8.0\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/has-flag\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz\",\n      \"integrity\": \"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/highlight/node_modules/supports-color\": {\n      \"version\": \"5.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz\",\n      \"integrity\": \"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-flag\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/parser\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz\",\n      \"integrity\": \"sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==\",\n      \"bin\": {\n        \"parser\": \"bin/babel-parser.js\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz\",\n      \"integrity\": \"sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/plugin-proposal-optional-chaining\": \"^7.20.7\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.13.0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-async-generator-functions\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz\",\n      \"integrity\": \"sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-remap-async-to-generator\": \"^7.18.9\",\n        \"@babel/plugin-syntax-async-generators\": \"^7.8.4\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-class-properties\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz\",\n      \"integrity\": \"sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-class-static-block\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz\",\n      \"integrity\": \"sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.21.0\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-class-static-block\": \"^7.14.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.12.0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-dynamic-import\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz\",\n      \"integrity\": \"sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-export-namespace-from\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz\",\n      \"integrity\": \"sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\",\n        \"@babel/plugin-syntax-export-namespace-from\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-json-strings\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz\",\n      \"integrity\": \"sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-json-strings\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-logical-assignment-operators\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz\",\n      \"integrity\": \"sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-logical-assignment-operators\": \"^7.10.4\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-nullish-coalescing-operator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz\",\n      \"integrity\": \"sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-nullish-coalescing-operator\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-numeric-separator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz\",\n      \"integrity\": \"sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-numeric-separator\": \"^7.10.4\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-object-rest-spread\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz\",\n      \"integrity\": \"sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/compat-data\": \"^7.20.5\",\n        \"@babel/helper-compilation-targets\": \"^7.20.7\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-object-rest-spread\": \"^7.8.3\",\n        \"@babel/plugin-transform-parameters\": \"^7.20.7\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-optional-catch-binding\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz\",\n      \"integrity\": \"sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-optional-catch-binding\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-optional-chaining\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz\",\n      \"integrity\": \"sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/plugin-syntax-optional-chaining\": \"^7.8.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-private-methods\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz\",\n      \"integrity\": \"sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-private-property-in-object\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz\",\n      \"integrity\": \"sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-create-class-features-plugin\": \"^7.21.0\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-private-property-in-object\": \"^7.14.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-proposal-unicode-property-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-async-generators\": {\n      \"version\": \"7.8.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz\",\n      \"integrity\": \"sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-class-properties\": {\n      \"version\": \"7.12.13\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz\",\n      \"integrity\": \"sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.12.13\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-class-static-block\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz\",\n      \"integrity\": \"sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-dynamic-import\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz\",\n      \"integrity\": \"sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-export-namespace-from\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz\",\n      \"integrity\": \"sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.3\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-import-assertions\": {\n      \"version\": \"7.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz\",\n      \"integrity\": \"sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.19.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-json-strings\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz\",\n      \"integrity\": \"sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-logical-assignment-operators\": {\n      \"version\": \"7.10.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz\",\n      \"integrity\": \"sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.10.4\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-nullish-coalescing-operator\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz\",\n      \"integrity\": \"sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-numeric-separator\": {\n      \"version\": \"7.10.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz\",\n      \"integrity\": \"sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.10.4\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-object-rest-spread\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz\",\n      \"integrity\": \"sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-optional-catch-binding\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz\",\n      \"integrity\": \"sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-optional-chaining\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz\",\n      \"integrity\": \"sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-private-property-in-object\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz\",\n      \"integrity\": \"sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-syntax-top-level-await\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz\",\n      \"integrity\": \"sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-arrow-functions\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz\",\n      \"integrity\": \"sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-async-to-generator\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz\",\n      \"integrity\": \"sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-module-imports\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-remap-async-to-generator\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-block-scoped-functions\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz\",\n      \"integrity\": \"sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-block-scoping\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz\",\n      \"integrity\": \"sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-classes\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz\",\n      \"integrity\": \"sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-compilation-targets\": \"^7.20.7\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-replace-supers\": \"^7.20.7\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"globals\": \"^11.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-classes/node_modules/globals\": {\n      \"version\": \"11.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/globals/-/globals-11.12.0.tgz\",\n      \"integrity\": \"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-computed-properties\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz\",\n      \"integrity\": \"sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/template\": \"^7.20.7\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-destructuring\": {\n      \"version\": \"7.21.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz\",\n      \"integrity\": \"sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-dotall-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-duplicate-keys\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz\",\n      \"integrity\": \"sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-exponentiation-operator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz\",\n      \"integrity\": \"sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-builder-binary-assignment-operator-visitor\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-for-of\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz\",\n      \"integrity\": \"sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-function-name\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz\",\n      \"integrity\": \"sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-compilation-targets\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.18.9\",\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-literals\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz\",\n      \"integrity\": \"sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-member-expression-literals\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz\",\n      \"integrity\": \"sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-modules-amd\": {\n      \"version\": \"7.20.11\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz\",\n      \"integrity\": \"sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-module-transforms\": \"^7.20.11\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-modules-commonjs\": {\n      \"version\": \"7.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz\",\n      \"integrity\": \"sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-module-transforms\": \"^7.21.2\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-simple-access\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-modules-systemjs\": {\n      \"version\": \"7.20.11\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz\",\n      \"integrity\": \"sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-hoist-variables\": \"^7.18.6\",\n        \"@babel/helper-module-transforms\": \"^7.20.11\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-modules-umd\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz\",\n      \"integrity\": \"sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-module-transforms\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-named-capturing-groups-regex\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz\",\n      \"integrity\": \"sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.20.5\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-new-target\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz\",\n      \"integrity\": \"sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-object-super\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz\",\n      \"integrity\": \"sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/helper-replace-supers\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-parameters\": {\n      \"version\": \"7.21.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz\",\n      \"integrity\": \"sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-property-literals\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz\",\n      \"integrity\": \"sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-regenerator\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz\",\n      \"integrity\": \"sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"regenerator-transform\": \"^0.15.1\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-reserved-words\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz\",\n      \"integrity\": \"sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-shorthand-properties\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz\",\n      \"integrity\": \"sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-spread\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz\",\n      \"integrity\": \"sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-sticky-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-template-literals\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz\",\n      \"integrity\": \"sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-typeof-symbol\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz\",\n      \"integrity\": \"sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-unicode-escapes\": {\n      \"version\": \"7.18.10\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz\",\n      \"integrity\": \"sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/plugin-transform-unicode-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/preset-env\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz\",\n      \"integrity\": \"sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/compat-data\": \"^7.21.4\",\n        \"@babel/helper-compilation-targets\": \"^7.21.4\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-validator-option\": \"^7.21.0\",\n        \"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression\": \"^7.18.6\",\n        \"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining\": \"^7.20.7\",\n        \"@babel/plugin-proposal-async-generator-functions\": \"^7.20.7\",\n        \"@babel/plugin-proposal-class-properties\": \"^7.18.6\",\n        \"@babel/plugin-proposal-class-static-block\": \"^7.21.0\",\n        \"@babel/plugin-proposal-dynamic-import\": \"^7.18.6\",\n        \"@babel/plugin-proposal-export-namespace-from\": \"^7.18.9\",\n        \"@babel/plugin-proposal-json-strings\": \"^7.18.6\",\n        \"@babel/plugin-proposal-logical-assignment-operators\": \"^7.20.7\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\": \"^7.18.6\",\n        \"@babel/plugin-proposal-numeric-separator\": \"^7.18.6\",\n        \"@babel/plugin-proposal-object-rest-spread\": \"^7.20.7\",\n        \"@babel/plugin-proposal-optional-catch-binding\": \"^7.18.6\",\n        \"@babel/plugin-proposal-optional-chaining\": \"^7.21.0\",\n        \"@babel/plugin-proposal-private-methods\": \"^7.18.6\",\n        \"@babel/plugin-proposal-private-property-in-object\": \"^7.21.0\",\n        \"@babel/plugin-proposal-unicode-property-regex\": \"^7.18.6\",\n        \"@babel/plugin-syntax-async-generators\": \"^7.8.4\",\n        \"@babel/plugin-syntax-class-properties\": \"^7.12.13\",\n        \"@babel/plugin-syntax-class-static-block\": \"^7.14.5\",\n        \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\",\n        \"@babel/plugin-syntax-export-namespace-from\": \"^7.8.3\",\n        \"@babel/plugin-syntax-import-assertions\": \"^7.20.0\",\n        \"@babel/plugin-syntax-json-strings\": \"^7.8.3\",\n        \"@babel/plugin-syntax-logical-assignment-operators\": \"^7.10.4\",\n        \"@babel/plugin-syntax-nullish-coalescing-operator\": \"^7.8.3\",\n        \"@babel/plugin-syntax-numeric-separator\": \"^7.10.4\",\n        \"@babel/plugin-syntax-object-rest-spread\": \"^7.8.3\",\n        \"@babel/plugin-syntax-optional-catch-binding\": \"^7.8.3\",\n        \"@babel/plugin-syntax-optional-chaining\": \"^7.8.3\",\n        \"@babel/plugin-syntax-private-property-in-object\": \"^7.14.5\",\n        \"@babel/plugin-syntax-top-level-await\": \"^7.14.5\",\n        \"@babel/plugin-transform-arrow-functions\": \"^7.20.7\",\n        \"@babel/plugin-transform-async-to-generator\": \"^7.20.7\",\n        \"@babel/plugin-transform-block-scoped-functions\": \"^7.18.6\",\n        \"@babel/plugin-transform-block-scoping\": \"^7.21.0\",\n        \"@babel/plugin-transform-classes\": \"^7.21.0\",\n        \"@babel/plugin-transform-computed-properties\": \"^7.20.7\",\n        \"@babel/plugin-transform-destructuring\": \"^7.21.3\",\n        \"@babel/plugin-transform-dotall-regex\": \"^7.18.6\",\n        \"@babel/plugin-transform-duplicate-keys\": \"^7.18.9\",\n        \"@babel/plugin-transform-exponentiation-operator\": \"^7.18.6\",\n        \"@babel/plugin-transform-for-of\": \"^7.21.0\",\n        \"@babel/plugin-transform-function-name\": \"^7.18.9\",\n        \"@babel/plugin-transform-literals\": \"^7.18.9\",\n        \"@babel/plugin-transform-member-expression-literals\": \"^7.18.6\",\n        \"@babel/plugin-transform-modules-amd\": \"^7.20.11\",\n        \"@babel/plugin-transform-modules-commonjs\": \"^7.21.2\",\n        \"@babel/plugin-transform-modules-systemjs\": \"^7.20.11\",\n        \"@babel/plugin-transform-modules-umd\": \"^7.18.6\",\n        \"@babel/plugin-transform-named-capturing-groups-regex\": \"^7.20.5\",\n        \"@babel/plugin-transform-new-target\": \"^7.18.6\",\n        \"@babel/plugin-transform-object-super\": \"^7.18.6\",\n        \"@babel/plugin-transform-parameters\": \"^7.21.3\",\n        \"@babel/plugin-transform-property-literals\": \"^7.18.6\",\n        \"@babel/plugin-transform-regenerator\": \"^7.20.5\",\n        \"@babel/plugin-transform-reserved-words\": \"^7.18.6\",\n        \"@babel/plugin-transform-shorthand-properties\": \"^7.18.6\",\n        \"@babel/plugin-transform-spread\": \"^7.20.7\",\n        \"@babel/plugin-transform-sticky-regex\": \"^7.18.6\",\n        \"@babel/plugin-transform-template-literals\": \"^7.18.9\",\n        \"@babel/plugin-transform-typeof-symbol\": \"^7.18.9\",\n        \"@babel/plugin-transform-unicode-escapes\": \"^7.18.10\",\n        \"@babel/plugin-transform-unicode-regex\": \"^7.18.6\",\n        \"@babel/preset-modules\": \"^0.1.5\",\n        \"@babel/types\": \"^7.21.4\",\n        \"babel-plugin-polyfill-corejs2\": \"^0.3.3\",\n        \"babel-plugin-polyfill-corejs3\": \"^0.6.0\",\n        \"babel-plugin-polyfill-regenerator\": \"^0.4.1\",\n        \"core-js-compat\": \"^3.25.1\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/preset-env/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/@babel/preset-modules\": {\n      \"version\": \"0.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz\",\n      \"integrity\": \"sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-plugin-utils\": \"^7.0.0\",\n        \"@babel/plugin-proposal-unicode-property-regex\": \"^7.4.4\",\n        \"@babel/plugin-transform-dotall-regex\": \"^7.4.4\",\n        \"@babel/types\": \"^7.4.4\",\n        \"esutils\": \"^2.0.2\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/@babel/regjsgen\": {\n      \"version\": \"0.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz\",\n      \"integrity\": \"sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==\",\n      \"dev\": true\n    },\n    \"node_modules/@babel/runtime\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz\",\n      \"integrity\": \"sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"regenerator-runtime\": \"^0.13.11\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/template\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz\",\n      \"integrity\": \"sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/code-frame\": \"^7.18.6\",\n        \"@babel/parser\": \"^7.20.7\",\n        \"@babel/types\": \"^7.20.7\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/traverse\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz\",\n      \"integrity\": \"sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/code-frame\": \"^7.21.4\",\n        \"@babel/generator\": \"^7.21.4\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-hoist-variables\": \"^7.18.6\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"@babel/parser\": \"^7.21.4\",\n        \"@babel/types\": \"^7.21.4\",\n        \"debug\": \"^4.1.0\",\n        \"globals\": \"^11.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@babel/traverse/node_modules/globals\": {\n      \"version\": \"11.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/globals/-/globals-11.12.0.tgz\",\n      \"integrity\": \"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/@babel/types\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz\",\n      \"integrity\": \"sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-string-parser\": \"^7.19.4\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"to-fast-properties\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/@commitlint/cli\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/cli/-/cli-17.6.1.tgz\",\n      \"integrity\": \"sha512-kCnDD9LE2ySiTnj/VPaxy4/oRayRcdv4aCuVxtoum8SxIU7OADHc0nJPQfheE8bHcs3zZdWzDMWltRosuT13bg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/format\": \"^17.4.4\",\n        \"@commitlint/lint\": \"^17.6.1\",\n        \"@commitlint/load\": \"^17.5.0\",\n        \"@commitlint/read\": \"^17.5.1\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"execa\": \"^5.0.0\",\n        \"lodash.isfunction\": \"^3.0.9\",\n        \"resolve-from\": \"5.0.0\",\n        \"resolve-global\": \"1.0.0\",\n        \"yargs\": \"^17.0.0\"\n      },\n      \"bin\": {\n        \"commitlint\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/config-conventional\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.6.1.tgz\",\n      \"integrity\": \"sha512-ng/ybaSLuTCH9F+7uavSOnEQ9EFMl7lHEjfAEgRh1hwmEe8SpLKpQeMo2aT1IWvHaGMuTb+gjfbzoRf2IR23NQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"conventional-changelog-conventionalcommits\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/config-validator\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz\",\n      \"integrity\": \"sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"ajv\": \"^8.11.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/ensure\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.4.tgz\",\n      \"integrity\": \"sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"lodash.camelcase\": \"^4.3.0\",\n        \"lodash.kebabcase\": \"^4.1.1\",\n        \"lodash.snakecase\": \"^4.1.1\",\n        \"lodash.startcase\": \"^4.4.0\",\n        \"lodash.upperfirst\": \"^4.3.1\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/execute-rule\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz\",\n      \"integrity\": \"sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/format\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz\",\n      \"integrity\": \"sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"chalk\": \"^4.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/is-ignored\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.4.tgz\",\n      \"integrity\": \"sha512-Y3eo1SFJ2JQDik4rWkBC4tlRIxlXEFrRWxcyrzb1PUT2k3kZ/XGNuCDfk/u0bU2/yS0tOA/mTjFsV+C4qyACHw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"semver\": \"7.3.8\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/lint\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/lint/-/lint-17.6.1.tgz\",\n      \"integrity\": \"sha512-VARJ9kxH64isgwVnC+ABPafCYzqxpsWJIpDaTuI0gh8aX4GQ0i7cn9tvxtFNfJj4ER2BAJeWJ0vURdNYjK2RQQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/is-ignored\": \"^17.4.4\",\n        \"@commitlint/parse\": \"^17.4.4\",\n        \"@commitlint/rules\": \"^17.6.1\",\n        \"@commitlint/types\": \"^17.4.4\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/load\": {\n      \"version\": \"17.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz\",\n      \"integrity\": \"sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/config-validator\": \"^17.4.4\",\n        \"@commitlint/execute-rule\": \"^17.4.0\",\n        \"@commitlint/resolve-extends\": \"^17.4.4\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"@types/node\": \"*\",\n        \"chalk\": \"^4.1.0\",\n        \"cosmiconfig\": \"^8.0.0\",\n        \"cosmiconfig-typescript-loader\": \"^4.0.0\",\n        \"lodash.isplainobject\": \"^4.0.6\",\n        \"lodash.merge\": \"^4.6.2\",\n        \"lodash.uniq\": \"^4.5.0\",\n        \"resolve-from\": \"^5.0.0\",\n        \"ts-node\": \"^10.8.1\",\n        \"typescript\": \"^4.6.4 || ^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/message\": {\n      \"version\": \"17.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz\",\n      \"integrity\": \"sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/parse\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.4.tgz\",\n      \"integrity\": \"sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"conventional-changelog-angular\": \"^5.0.11\",\n        \"conventional-commits-parser\": \"^3.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/read\": {\n      \"version\": \"17.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz\",\n      \"integrity\": \"sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/top-level\": \"^17.4.0\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"fs-extra\": \"^11.0.0\",\n        \"git-raw-commits\": \"^2.0.11\",\n        \"minimist\": \"^1.2.6\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/resolve-extends\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz\",\n      \"integrity\": \"sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/config-validator\": \"^17.4.4\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"import-fresh\": \"^3.0.0\",\n        \"lodash.mergewith\": \"^4.6.2\",\n        \"resolve-from\": \"^5.0.0\",\n        \"resolve-global\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/rules\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/rules/-/rules-17.6.1.tgz\",\n      \"integrity\": \"sha512-lUdHw6lYQ1RywExXDdLOKxhpp6857/4c95Dc/1BikrHgdysVUXz26yV0vp1GL7Gv+avx9WqZWTIVB7pNouxlfw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@commitlint/ensure\": \"^17.4.4\",\n        \"@commitlint/message\": \"^17.4.2\",\n        \"@commitlint/to-lines\": \"^17.4.0\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"execa\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/to-lines\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz\",\n      \"integrity\": \"sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/top-level\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz\",\n      \"integrity\": \"sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"find-up\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@commitlint/types\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz\",\n      \"integrity\": \"sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"chalk\": \"^4.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=v14\"\n      }\n    },\n    \"node_modules/@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.9\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n      }\n    },\n    \"node_modules/@css-render/plugin-bem\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/@css-render/plugin-bem/-/plugin-bem-0.15.12.tgz\",\n      \"integrity\": \"sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==\",\n      \"peerDependencies\": {\n        \"css-render\": \"~0.15.12\"\n      }\n    },\n    \"node_modules/@css-render/vue3-ssr\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/@css-render/vue3-ssr/-/vue3-ssr-0.15.12.tgz\",\n      \"integrity\": \"sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==\",\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.11\"\n      }\n    },\n    \"node_modules/@emotion/hash\": {\n      \"version\": \"0.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz\",\n      \"integrity\": \"sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==\"\n    },\n    \"node_modules/@esbuild/android-arm\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz\",\n      \"integrity\": \"sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/android-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/android-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"android\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/darwin-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/freebsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz\",\n      \"integrity\": \"sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==\",\n      \"cpu\": [\n        \"arm\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ia32\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz\",\n      \"integrity\": \"sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-loong64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz\",\n      \"integrity\": \"sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==\",\n      \"cpu\": [\n        \"loong64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-mips64el\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz\",\n      \"integrity\": \"sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==\",\n      \"cpu\": [\n        \"mips64el\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-ppc64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz\",\n      \"integrity\": \"sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==\",\n      \"cpu\": [\n        \"ppc64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-riscv64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz\",\n      \"integrity\": \"sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==\",\n      \"cpu\": [\n        \"riscv64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-s390x\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz\",\n      \"integrity\": \"sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==\",\n      \"cpu\": [\n        \"s390x\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/linux-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/netbsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"netbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/openbsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"openbsd\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/sunos-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"sunos\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/win32-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/win32-ia32\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz\",\n      \"integrity\": \"sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@esbuild/win32-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@eslint-community/eslint-utils\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz\",\n      \"integrity\": \"sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-visitor-keys\": \"^3.3.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^6.0.0 || ^7.0.0 || >=8.0.0\"\n      }\n    },\n    \"node_modules/@eslint-community/regexpp\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz\",\n      \"integrity\": \"sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.0.0 || ^14.0.0 || >=16.0.0\"\n      }\n    },\n    \"node_modules/@eslint/eslintrc\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz\",\n      \"integrity\": \"sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ajv\": \"^6.12.4\",\n        \"debug\": \"^4.3.2\",\n        \"espree\": \"^9.5.1\",\n        \"globals\": \"^13.19.0\",\n        \"ignore\": \"^5.2.0\",\n        \"import-fresh\": \"^3.2.1\",\n        \"js-yaml\": \"^4.1.0\",\n        \"minimatch\": \"^3.1.2\",\n        \"strip-json-comments\": \"^3.1.1\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/@eslint/eslintrc/node_modules/ajv\": {\n      \"version\": \"6.12.6\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz\",\n      \"integrity\": \"sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fast-deep-equal\": \"^3.1.1\",\n        \"fast-json-stable-stringify\": \"^2.0.0\",\n        \"json-schema-traverse\": \"^0.4.1\",\n        \"uri-js\": \"^4.2.2\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\n      }\n    },\n    \"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz\",\n      \"integrity\": \"sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==\",\n      \"dev\": true\n    },\n    \"node_modules/@eslint/js\": {\n      \"version\": \"8.39.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz\",\n      \"integrity\": \"sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      }\n    },\n    \"node_modules/@humanwhocodes/config-array\": {\n      \"version\": \"0.11.8\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz\",\n      \"integrity\": \"sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@humanwhocodes/object-schema\": \"^1.2.1\",\n        \"debug\": \"^4.1.1\",\n        \"minimatch\": \"^3.0.5\"\n      },\n      \"engines\": {\n        \"node\": \">=10.10.0\"\n      }\n    },\n    \"node_modules/@humanwhocodes/module-importer\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz\",\n      \"integrity\": \"sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12.22\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/nzakas\"\n      }\n    },\n    \"node_modules/@humanwhocodes/object-schema\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz\",\n      \"integrity\": \"sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==\",\n      \"dev\": true\n    },\n    \"node_modules/@iconify/types\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz\",\n      \"integrity\": \"sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==\",\n      \"dev\": true\n    },\n    \"node_modules/@iconify/vue\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@iconify/vue/-/vue-4.1.1.tgz\",\n      \"integrity\": \"sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@iconify/types\": \"^2.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/cyberalien\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \">=3\"\n      }\n    },\n    \"node_modules/@intlify/core-base\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz\",\n      \"integrity\": \"sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==\",\n      \"dependencies\": {\n        \"@intlify/devtools-if\": \"9.2.2\",\n        \"@intlify/message-compiler\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\",\n        \"@intlify/vue-devtools\": \"9.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/@intlify/devtools-if\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz\",\n      \"integrity\": \"sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==\",\n      \"dependencies\": {\n        \"@intlify/shared\": \"9.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/@intlify/message-compiler\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz\",\n      \"integrity\": \"sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==\",\n      \"dependencies\": {\n        \"@intlify/shared\": \"9.2.2\",\n        \"source-map\": \"0.6.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/@intlify/shared\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz\",\n      \"integrity\": \"sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==\",\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/@intlify/vue-devtools\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz\",\n      \"integrity\": \"sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==\",\n      \"dependencies\": {\n        \"@intlify/core-base\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/@jridgewell/gen-mapping\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz\",\n      \"integrity\": \"sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/set-array\": \"^1.0.1\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/set-array\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz\",\n      \"integrity\": \"sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/source-map\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz\",\n      \"integrity\": \"sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.0\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      }\n    },\n    \"node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.15\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz\",\n      \"integrity\": \"sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==\",\n      \"dev\": true\n    },\n    \"node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.18\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz\",\n      \"integrity\": \"sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"3.1.0\",\n        \"@jridgewell/sourcemap-codec\": \"1.4.14\"\n      }\n    },\n    \"node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.14\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n      \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n      \"dev\": true\n    },\n    \"node_modules/@juggle/resize-observer\": {\n      \"version\": \"3.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz\",\n      \"integrity\": \"sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==\"\n    },\n    \"node_modules/@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@rollup/plugin-replace\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz\",\n      \"integrity\": \"sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@rollup/pluginutils\": \"^5.0.1\",\n        \"magic-string\": \"^0.27.0\"\n      },\n      \"engines\": {\n        \"node\": \">=14.0.0\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^1.20.0||^2.0.0||^3.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"rollup\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@rollup/pluginutils\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz\",\n      \"integrity\": \"sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/estree\": \"^1.0.0\",\n        \"estree-walker\": \"^2.0.2\",\n        \"picomatch\": \"^2.3.1\"\n      },\n      \"engines\": {\n        \"node\": \">=14.0.0\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^1.20.0||^2.0.0||^3.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"rollup\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@surma/rollup-plugin-off-main-thread\": {\n      \"version\": \"2.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz\",\n      \"integrity\": \"sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ejs\": \"^3.1.6\",\n        \"json5\": \"^2.2.0\",\n        \"magic-string\": \"^0.25.0\",\n        \"string.prototype.matchall\": \"^4.0.6\"\n      }\n    },\n    \"node_modules/@surma/rollup-plugin-off-main-thread/node_modules/json5\": {\n      \"version\": \"2.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz\",\n      \"integrity\": \"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==\",\n      \"dev\": true,\n      \"bin\": {\n        \"json5\": \"lib/cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string\": {\n      \"version\": \"0.25.9\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n      \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"sourcemap-codec\": \"^1.4.8\"\n      }\n    },\n    \"node_modules/@traptitech/markdown-it-katex\": {\n      \"version\": \"3.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/@traptitech/markdown-it-katex/-/markdown-it-katex-3.6.0.tgz\",\n      \"integrity\": \"sha512-CnJzTWxsgLGXFdSrWRaGz7GZ1kUUi8g3E9HzJmeveX1YwVJavrKYqysktfHZQsujdnRqV5O7g8FPKEA/aeTkOQ==\",\n      \"dependencies\": {\n        \"katex\": \"^0.16.0\"\n      }\n    },\n    \"node_modules/@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true\n    },\n    \"node_modules/@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true\n    },\n    \"node_modules/@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true\n    },\n    \"node_modules/@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/crypto-js\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz\",\n      \"integrity\": \"sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/estree\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz\",\n      \"integrity\": \"sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/json-schema\": {\n      \"version\": \"7.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz\",\n      \"integrity\": \"sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/json5\": {\n      \"version\": \"0.0.29\",\n      \"resolved\": \"https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz\",\n      \"integrity\": \"sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/katex\": {\n      \"version\": \"0.16.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz\",\n      \"integrity\": \"sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/linkify-it\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz\",\n      \"integrity\": \"sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/lodash\": {\n      \"version\": \"4.14.194\",\n      \"resolved\": \"https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz\",\n      \"integrity\": \"sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==\"\n    },\n    \"node_modules/@types/lodash-es\": {\n      \"version\": \"4.17.7\",\n      \"resolved\": \"https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz\",\n      \"integrity\": \"sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==\",\n      \"dependencies\": {\n        \"@types/lodash\": \"*\"\n      }\n    },\n    \"node_modules/@types/markdown-it\": {\n      \"version\": \"12.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz\",\n      \"integrity\": \"sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/linkify-it\": \"*\",\n        \"@types/mdurl\": \"*\"\n      }\n    },\n    \"node_modules/@types/markdown-it-link-attributes\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.1.tgz\",\n      \"integrity\": \"sha512-K8RnNb1q8j7rDOJbMF7AnlhCC/45BjrQ8z3WZWOrvkBIl8u9RXvmBdG/hfpnmK1JhhEZcmFEKWt+ilW1Mly+2Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/markdown-it\": \"*\"\n      }\n    },\n    \"node_modules/@types/mdast\": {\n      \"version\": \"3.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz\",\n      \"integrity\": \"sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/unist\": \"*\"\n      }\n    },\n    \"node_modules/@types/mdurl\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz\",\n      \"integrity\": \"sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/minimist\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz\",\n      \"integrity\": \"sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"18.16.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz\",\n      \"integrity\": \"sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/normalize-package-data\": {\n      \"version\": \"2.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz\",\n      \"integrity\": \"sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/resolve\": {\n      \"version\": \"1.17.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz\",\n      \"integrity\": \"sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/semver\": {\n      \"version\": \"7.3.13\",\n      \"resolved\": \"https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz\",\n      \"integrity\": \"sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/trusted-types\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz\",\n      \"integrity\": \"sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/unist\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz\",\n      \"integrity\": \"sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/web-bluetooth\": {\n      \"version\": \"0.0.16\",\n      \"resolved\": \"https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz\",\n      \"integrity\": \"sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==\"\n    },\n    \"node_modules/@typescript-eslint/eslint-plugin\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz\",\n      \"integrity\": \"sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@eslint-community/regexpp\": \"^4.4.0\",\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/type-utils\": \"5.59.0\",\n        \"@typescript-eslint/utils\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"grapheme-splitter\": \"^1.0.4\",\n        \"ignore\": \"^5.2.0\",\n        \"natural-compare-lite\": \"^1.4.0\",\n        \"semver\": \"^7.3.7\",\n        \"tsutils\": \"^3.21.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      },\n      \"peerDependencies\": {\n        \"@typescript-eslint/parser\": \"^5.0.0\",\n        \"eslint\": \"^6.0.0 || ^7.0.0 || ^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"typescript\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@typescript-eslint/parser\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz\",\n      \"integrity\": \"sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"debug\": \"^4.3.4\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^6.0.0 || ^7.0.0 || ^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"typescript\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@typescript-eslint/scope-manager\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz\",\n      \"integrity\": \"sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/visitor-keys\": \"5.59.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      }\n    },\n    \"node_modules/@typescript-eslint/type-utils\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz\",\n      \"integrity\": \"sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"@typescript-eslint/utils\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"tsutils\": \"^3.21.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"*\"\n      },\n      \"peerDependenciesMeta\": {\n        \"typescript\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@typescript-eslint/types\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz\",\n      \"integrity\": \"sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      }\n    },\n    \"node_modules/@typescript-eslint/typescript-estree\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz\",\n      \"integrity\": \"sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/visitor-keys\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"globby\": \"^11.1.0\",\n        \"is-glob\": \"^4.0.3\",\n        \"semver\": \"^7.3.7\",\n        \"tsutils\": \"^3.21.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      },\n      \"peerDependenciesMeta\": {\n        \"typescript\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@typescript-eslint/utils\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz\",\n      \"integrity\": \"sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"@types/json-schema\": \"^7.0.9\",\n        \"@types/semver\": \"^7.3.12\",\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"eslint-scope\": \"^5.1.1\",\n        \"semver\": \"^7.3.7\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^6.0.0 || ^7.0.0 || ^8.0.0\"\n      }\n    },\n    \"node_modules/@typescript-eslint/visitor-keys\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz\",\n      \"integrity\": \"sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"eslint-visitor-keys\": \"^3.3.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/typescript-eslint\"\n      }\n    },\n    \"node_modules/@vitejs/plugin-vue\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz\",\n      \"integrity\": \"sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^14.18.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"vite\": \"^4.0.0\",\n        \"vue\": \"^3.2.25\"\n      }\n    },\n    \"node_modules/@volar/language-core\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/language-core/-/language-core-1.4.1.tgz\",\n      \"integrity\": \"sha512-EIY+Swv+TjsWpxOxujjMf1ZXqOjg9MT2VMXZ+1dKva0wD8W0L6EtptFFcCJdBbcKmGMFkr57Qzz9VNMWhs3jXQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@volar/source-map\": \"1.4.1\"\n      }\n    },\n    \"node_modules/@volar/source-map\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/source-map/-/source-map-1.4.1.tgz\",\n      \"integrity\": \"sha512-bZ46ad72dsbzuOWPUtJjBXkzSQzzSejuR3CT81+GvTEI2E994D8JPXzM3tl98zyCNnjgs4OkRyliImL1dvJ5BA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"muggle-string\": \"^0.2.2\"\n      }\n    },\n    \"node_modules/@volar/typescript\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/typescript/-/typescript-1.4.1.tgz\",\n      \"integrity\": \"sha512-phTy6p9yG6bgMIKQWEeDOi/aeT0njZsb1a/G1mrEuDsLmAn24Le4gDwSsGNhea6Uhu+3gdpUZn2PmZXa+WG2iQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@volar/language-core\": \"1.4.1\"\n      },\n      \"peerDependencies\": {\n        \"typescript\": \"*\"\n      }\n    },\n    \"node_modules/@volar/vue-language-core\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.4.4.tgz\",\n      \"integrity\": \"sha512-c3hL6un+CfoOlusGvpypcodmk9ke/ImrWIUc0GkgI+imoQpUGzgu3tEQWlPs604R7AhxeZwWUi8hQNfax0R/zA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@volar/language-core\": \"1.4.1\",\n        \"@volar/source-map\": \"1.4.1\",\n        \"@vue/compiler-dom\": \"^3.2.0\",\n        \"@vue/compiler-sfc\": \"^3.2.0\",\n        \"@vue/reactivity\": \"^3.2.0\",\n        \"@vue/shared\": \"^3.2.0\",\n        \"minimatch\": \"^9.0.0\",\n        \"muggle-string\": \"^0.2.2\",\n        \"vue-template-compiler\": \"^2.7.14\"\n      }\n    },\n    \"node_modules/@volar/vue-language-core/node_modules/brace-expansion\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n      \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"balanced-match\": \"^1.0.0\"\n      }\n    },\n    \"node_modules/@volar/vue-language-core/node_modules/minimatch\": {\n      \"version\": \"9.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz\",\n      \"integrity\": \"sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"brace-expansion\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=16 || 14 >=14.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/@volar/vue-typescript\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.4.4.tgz\",\n      \"integrity\": \"sha512-L61Fk15jlJw3QtIddD4cVE5jei5i6zbLJRiaEMYDDnUKB259/qUrdvnMfnZUFVyDwlevzdstjtaUyreeG/0nPQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@volar/typescript\": \"1.4.1\",\n        \"@volar/vue-language-core\": \"1.4.4\"\n      },\n      \"peerDependencies\": {\n        \"typescript\": \"*\"\n      }\n    },\n    \"node_modules/@vue/compiler-core\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz\",\n      \"integrity\": \"sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==\",\n      \"dependencies\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"source-map\": \"^0.6.1\"\n      }\n    },\n    \"node_modules/@vue/compiler-dom\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz\",\n      \"integrity\": \"sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==\",\n      \"dependencies\": {\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"node_modules/@vue/compiler-sfc\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz\",\n      \"integrity\": \"sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==\",\n      \"dependencies\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/compiler-ssr\": \"3.2.47\",\n        \"@vue/reactivity-transform\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"magic-string\": \"^0.25.7\",\n        \"postcss\": \"^8.1.10\",\n        \"source-map\": \"^0.6.1\"\n      }\n    },\n    \"node_modules/@vue/compiler-sfc/node_modules/magic-string\": {\n      \"version\": \"0.25.9\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n      \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n      \"dependencies\": {\n        \"sourcemap-codec\": \"^1.4.8\"\n      }\n    },\n    \"node_modules/@vue/compiler-ssr\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz\",\n      \"integrity\": \"sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==\",\n      \"dependencies\": {\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"node_modules/@vue/devtools-api\": {\n      \"version\": \"6.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz\",\n      \"integrity\": \"sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==\"\n    },\n    \"node_modules/@vue/reactivity\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz\",\n      \"integrity\": \"sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==\",\n      \"dependencies\": {\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"node_modules/@vue/reactivity-transform\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz\",\n      \"integrity\": \"sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==\",\n      \"dependencies\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"magic-string\": \"^0.25.7\"\n      }\n    },\n    \"node_modules/@vue/reactivity-transform/node_modules/magic-string\": {\n      \"version\": \"0.25.9\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n      \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n      \"dependencies\": {\n        \"sourcemap-codec\": \"^1.4.8\"\n      }\n    },\n    \"node_modules/@vue/runtime-core\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz\",\n      \"integrity\": \"sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==\",\n      \"dependencies\": {\n        \"@vue/reactivity\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"node_modules/@vue/runtime-dom\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz\",\n      \"integrity\": \"sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==\",\n      \"dependencies\": {\n        \"@vue/runtime-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"csstype\": \"^2.6.8\"\n      }\n    },\n    \"node_modules/@vue/runtime-dom/node_modules/csstype\": {\n      \"version\": \"2.6.21\",\n      \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz\",\n      \"integrity\": \"sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==\"\n    },\n    \"node_modules/@vue/server-renderer\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz\",\n      \"integrity\": \"sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==\",\n      \"dependencies\": {\n        \"@vue/compiler-ssr\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"3.2.47\"\n      }\n    },\n    \"node_modules/@vue/shared\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz\",\n      \"integrity\": \"sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==\"\n    },\n    \"node_modules/@vueuse/core\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz\",\n      \"integrity\": \"sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==\",\n      \"dependencies\": {\n        \"@types/web-bluetooth\": \"^0.0.16\",\n        \"@vueuse/metadata\": \"9.13.0\",\n        \"@vueuse/shared\": \"9.13.0\",\n        \"vue-demi\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      }\n    },\n    \"node_modules/@vueuse/core/node_modules/vue-demi\": {\n      \"version\": \"0.14.0\",\n      \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n      \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n      \"hasInstallScript\": true,\n      \"bin\": {\n        \"vue-demi-fix\": \"bin/vue-demi-fix.js\",\n        \"vue-demi-switch\": \"bin/vue-demi-switch.js\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      },\n      \"peerDependencies\": {\n        \"@vue/composition-api\": \"^1.0.0-rc.1\",\n        \"vue\": \"^3.0.0-0 || ^2.6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@vue/composition-api\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@vueuse/metadata\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz\",\n      \"integrity\": \"sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==\",\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      }\n    },\n    \"node_modules/@vueuse/shared\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz\",\n      \"integrity\": \"sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==\",\n      \"dependencies\": {\n        \"vue-demi\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      }\n    },\n    \"node_modules/@vueuse/shared/node_modules/vue-demi\": {\n      \"version\": \"0.14.0\",\n      \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n      \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n      \"hasInstallScript\": true,\n      \"bin\": {\n        \"vue-demi-fix\": \"bin/vue-demi-fix.js\",\n        \"vue-demi-switch\": \"bin/vue-demi-switch.js\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      },\n      \"peerDependencies\": {\n        \"@vue/composition-api\": \"^1.0.0-rc.1\",\n        \"vue\": \"^3.0.0-0 || ^2.6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@vue/composition-api\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/acorn\": {\n      \"version\": \"8.8.2\",\n      \"resolved\": \"https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz\",\n      \"integrity\": \"sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"acorn\": \"bin/acorn\"\n      },\n      \"engines\": {\n        \"node\": \">=0.4.0\"\n      }\n    },\n    \"node_modules/acorn-jsx\": {\n      \"version\": \"5.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz\",\n      \"integrity\": \"sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==\",\n      \"dev\": true,\n      \"peerDependencies\": {\n        \"acorn\": \"^6.0.0 || ^7.0.0 || ^8.0.0\"\n      }\n    },\n    \"node_modules/acorn-walk\": {\n      \"version\": \"8.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz\",\n      \"integrity\": \"sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.4.0\"\n      }\n    },\n    \"node_modules/aggregate-error\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz\",\n      \"integrity\": \"sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"clean-stack\": \"^2.0.0\",\n        \"indent-string\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/ajv\": {\n      \"version\": \"8.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz\",\n      \"integrity\": \"sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fast-deep-equal\": \"^3.1.1\",\n        \"json-schema-traverse\": \"^1.0.0\",\n        \"require-from-string\": \"^2.0.2\",\n        \"uri-js\": \"^4.2.2\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\n      }\n    },\n    \"node_modules/ansi-escapes\": {\n      \"version\": \"4.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz\",\n      \"integrity\": \"sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"type-fest\": \"^0.21.3\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/ansi-escapes/node_modules/type-fest\": {\n      \"version\": \"0.21.3\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz\",\n      \"integrity\": \"sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/ansi-regex\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz\",\n      \"integrity\": \"sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/ansi-styles\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz\",\n      \"integrity\": \"sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-convert\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/ansi-styles?sponsor=1\"\n      }\n    },\n    \"node_modules/any-promise\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz\",\n      \"integrity\": \"sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==\",\n      \"dev\": true\n    },\n    \"node_modules/anymatch\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz\",\n      \"integrity\": \"sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"normalize-path\": \"^3.0.0\",\n        \"picomatch\": \"^2.0.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/arg\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/arg/-/arg-5.0.2.tgz\",\n      \"integrity\": \"sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==\",\n      \"dev\": true\n    },\n    \"node_modules/argparse\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz\",\n      \"integrity\": \"sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==\"\n    },\n    \"node_modules/array-buffer-byte-length\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz\",\n      \"integrity\": \"sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"is-array-buffer\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/array-ify\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz\",\n      \"integrity\": \"sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==\",\n      \"dev\": true\n    },\n    \"node_modules/array-includes\": {\n      \"version\": \"3.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz\",\n      \"integrity\": \"sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"is-string\": \"^1.0.7\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/array-union\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz\",\n      \"integrity\": \"sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/array.prototype.flat\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz\",\n      \"integrity\": \"sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"es-shim-unscopables\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/array.prototype.flatmap\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz\",\n      \"integrity\": \"sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"es-shim-unscopables\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/arrify\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz\",\n      \"integrity\": \"sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/astral-regex\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz\",\n      \"integrity\": \"sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/async\": {\n      \"version\": \"3.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/async/-/async-3.2.4.tgz\",\n      \"integrity\": \"sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==\",\n      \"dev\": true\n    },\n    \"node_modules/async-validator\": {\n      \"version\": \"4.2.5\",\n      \"resolved\": \"https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz\",\n      \"integrity\": \"sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==\"\n    },\n    \"node_modules/asynckit\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz\",\n      \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\",\n      \"dev\": true\n    },\n    \"node_modules/at-least-node\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz\",\n      \"integrity\": \"sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 4.0.0\"\n      }\n    },\n    \"node_modules/autoprefixer\": {\n      \"version\": \"10.4.14\",\n      \"resolved\": \"https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz\",\n      \"integrity\": \"sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/postcss/\"\n        },\n        {\n          \"type\": \"tidelift\",\n          \"url\": \"https://tidelift.com/funding/github/npm/autoprefixer\"\n        }\n      ],\n      \"dependencies\": {\n        \"browserslist\": \"^4.21.5\",\n        \"caniuse-lite\": \"^1.0.30001464\",\n        \"fraction.js\": \"^4.2.0\",\n        \"normalize-range\": \"^0.1.2\",\n        \"picocolors\": \"^1.0.0\",\n        \"postcss-value-parser\": \"^4.2.0\"\n      },\n      \"bin\": {\n        \"autoprefixer\": \"bin/autoprefixer\"\n      },\n      \"engines\": {\n        \"node\": \"^10 || ^12 || >=14\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \"^8.1.0\"\n      }\n    },\n    \"node_modules/available-typed-arrays\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz\",\n      \"integrity\": \"sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/axios\": {\n      \"version\": \"1.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/axios/-/axios-1.3.6.tgz\",\n      \"integrity\": \"sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"follow-redirects\": \"^1.15.0\",\n        \"form-data\": \"^4.0.0\",\n        \"proxy-from-env\": \"^1.1.0\"\n      }\n    },\n    \"node_modules/babel-plugin-polyfill-corejs2\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz\",\n      \"integrity\": \"sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/compat-data\": \"^7.17.7\",\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\",\n        \"semver\": \"^6.1.1\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/babel-plugin-polyfill-corejs3\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz\",\n      \"integrity\": \"sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\",\n        \"core-js-compat\": \"^3.25.1\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/babel-plugin-polyfill-regenerator\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz\",\n      \"integrity\": \"sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0-0\"\n      }\n    },\n    \"node_modules/balanced-match\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz\",\n      \"integrity\": \"sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==\",\n      \"dev\": true\n    },\n    \"node_modules/base64-arraybuffer\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz\",\n      \"integrity\": \"sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==\",\n      \"engines\": {\n        \"node\": \">= 0.6.0\"\n      }\n    },\n    \"node_modules/binary-extensions\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz\",\n      \"integrity\": \"sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"dev\": true\n    },\n    \"node_modules/brace-expansion\": {\n      \"version\": \"1.1.11\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz\",\n      \"integrity\": \"sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"balanced-match\": \"^1.0.0\",\n        \"concat-map\": \"0.0.1\"\n      }\n    },\n    \"node_modules/braces\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/braces/-/braces-3.0.2.tgz\",\n      \"integrity\": \"sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fill-range\": \"^7.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/browserslist\": {\n      \"version\": \"4.21.5\",\n      \"resolved\": \"https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz\",\n      \"integrity\": \"sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/browserslist\"\n        },\n        {\n          \"type\": \"tidelift\",\n          \"url\": \"https://tidelift.com/funding/github/npm/browserslist\"\n        }\n      ],\n      \"dependencies\": {\n        \"caniuse-lite\": \"^1.0.30001449\",\n        \"electron-to-chromium\": \"^1.4.284\",\n        \"node-releases\": \"^2.0.8\",\n        \"update-browserslist-db\": \"^1.0.10\"\n      },\n      \"bin\": {\n        \"browserslist\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \"^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7\"\n      }\n    },\n    \"node_modules/buffer-from\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz\",\n      \"integrity\": \"sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==\",\n      \"dev\": true\n    },\n    \"node_modules/builtin-modules\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz\",\n      \"integrity\": \"sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/builtins\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz\",\n      \"integrity\": \"sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"semver\": \"^7.0.0\"\n      }\n    },\n    \"node_modules/call-bind\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz\",\n      \"integrity\": \"sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"function-bind\": \"^1.1.1\",\n        \"get-intrinsic\": \"^1.0.2\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/callsites\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz\",\n      \"integrity\": \"sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/camelcase\": {\n      \"version\": \"5.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz\",\n      \"integrity\": \"sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/camelcase-css\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz\",\n      \"integrity\": \"sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/camelcase-keys\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz\",\n      \"integrity\": \"sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"camelcase\": \"^5.3.1\",\n        \"map-obj\": \"^4.0.0\",\n        \"quick-lru\": \"^4.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/caniuse-lite\": {\n      \"version\": \"1.0.30001481\",\n      \"resolved\": \"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz\",\n      \"integrity\": \"sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/browserslist\"\n        },\n        {\n          \"type\": \"tidelift\",\n          \"url\": \"https://tidelift.com/funding/github/npm/caniuse-lite\"\n        },\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/ai\"\n        }\n      ]\n    },\n    \"node_modules/chalk\": {\n      \"version\": \"4.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz\",\n      \"integrity\": \"sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^4.1.0\",\n        \"supports-color\": \"^7.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/chalk?sponsor=1\"\n      }\n    },\n    \"node_modules/character-entities\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz\",\n      \"integrity\": \"sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/character-entities-legacy\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz\",\n      \"integrity\": \"sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/character-reference-invalid\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz\",\n      \"integrity\": \"sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/chokidar\": {\n      \"version\": \"3.5.3\",\n      \"resolved\": \"https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz\",\n      \"integrity\": \"sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"individual\",\n          \"url\": \"https://paulmillr.com/funding/\"\n        }\n      ],\n      \"dependencies\": {\n        \"anymatch\": \"~3.1.2\",\n        \"braces\": \"~3.0.2\",\n        \"glob-parent\": \"~5.1.2\",\n        \"is-binary-path\": \"~2.1.0\",\n        \"is-glob\": \"~4.0.1\",\n        \"normalize-path\": \"~3.0.0\",\n        \"readdirp\": \"~3.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8.10.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.2\"\n      }\n    },\n    \"node_modules/chokidar/node_modules/glob-parent\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz\",\n      \"integrity\": \"sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-glob\": \"^4.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/ci-info\": {\n      \"version\": \"3.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz\",\n      \"integrity\": \"sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/sibiraj-s\"\n        }\n      ],\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/clean-regexp\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz\",\n      \"integrity\": \"sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"escape-string-regexp\": \"^1.0.5\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/clean-regexp/node_modules/escape-string-regexp\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n      \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.8.0\"\n      }\n    },\n    \"node_modules/clean-stack\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz\",\n      \"integrity\": \"sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/cli-cursor\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz\",\n      \"integrity\": \"sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"restore-cursor\": \"^3.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/cli-truncate\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz\",\n      \"integrity\": \"sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"slice-ansi\": \"^5.0.0\",\n        \"string-width\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.20.0 || ^14.13.1 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/cliui\": {\n      \"version\": \"8.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz\",\n      \"integrity\": \"sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"string-width\": \"^4.2.0\",\n        \"strip-ansi\": \"^6.0.1\",\n        \"wrap-ansi\": \"^7.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/cliui/node_modules/emoji-regex\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n      \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n      \"dev\": true\n    },\n    \"node_modules/cliui/node_modules/is-fullwidth-code-point\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n      \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/cliui/node_modules/string-width\": {\n      \"version\": \"4.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n      \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"emoji-regex\": \"^8.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\",\n        \"strip-ansi\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/color-convert\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz\",\n      \"integrity\": \"sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-name\": \"~1.1.4\"\n      },\n      \"engines\": {\n        \"node\": \">=7.0.0\"\n      }\n    },\n    \"node_modules/color-name\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz\",\n      \"integrity\": \"sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==\",\n      \"dev\": true\n    },\n    \"node_modules/colorette\": {\n      \"version\": \"2.0.20\",\n      \"resolved\": \"https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz\",\n      \"integrity\": \"sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==\",\n      \"dev\": true\n    },\n    \"node_modules/combined-stream\": {\n      \"version\": \"1.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz\",\n      \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"delayed-stream\": \"~1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"8.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-8.3.0.tgz\",\n      \"integrity\": \"sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==\",\n      \"engines\": {\n        \"node\": \">= 12\"\n      }\n    },\n    \"node_modules/common-tags\": {\n      \"version\": \"1.8.2\",\n      \"resolved\": \"https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz\",\n      \"integrity\": \"sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0.0\"\n      }\n    },\n    \"node_modules/compare-func\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz\",\n      \"integrity\": \"sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"array-ify\": \"^1.0.0\",\n        \"dot-prop\": \"^5.1.0\"\n      }\n    },\n    \"node_modules/concat-map\": {\n      \"version\": \"0.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz\",\n      \"integrity\": \"sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==\",\n      \"dev\": true\n    },\n    \"node_modules/conventional-changelog-angular\": {\n      \"version\": \"5.0.13\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz\",\n      \"integrity\": \"sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"compare-func\": \"^2.0.0\",\n        \"q\": \"^1.5.1\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/conventional-changelog-conventionalcommits\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz\",\n      \"integrity\": \"sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"compare-func\": \"^2.0.0\",\n        \"lodash\": \"^4.17.15\",\n        \"q\": \"^1.5.1\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/conventional-commits-parser\": {\n      \"version\": \"3.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz\",\n      \"integrity\": \"sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-text-path\": \"^1.0.1\",\n        \"JSONStream\": \"^1.0.4\",\n        \"lodash\": \"^4.17.15\",\n        \"meow\": \"^8.0.0\",\n        \"split2\": \"^3.0.0\",\n        \"through2\": \"^4.0.0\"\n      },\n      \"bin\": {\n        \"conventional-commits-parser\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/convert-source-map\": {\n      \"version\": \"1.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz\",\n      \"integrity\": \"sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==\",\n      \"dev\": true\n    },\n    \"node_modules/copy-anything\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz\",\n      \"integrity\": \"sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-what\": \"^3.14.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mesqueeb\"\n      }\n    },\n    \"node_modules/core-js-compat\": {\n      \"version\": \"3.30.1\",\n      \"resolved\": \"https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.1.tgz\",\n      \"integrity\": \"sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"browserslist\": \"^4.21.5\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/core-js\"\n      }\n    },\n    \"node_modules/cosmiconfig\": {\n      \"version\": \"8.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz\",\n      \"integrity\": \"sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"import-fresh\": \"^3.2.1\",\n        \"js-yaml\": \"^4.1.0\",\n        \"parse-json\": \"^5.0.0\",\n        \"path-type\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=14\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/d-fischer\"\n      }\n    },\n    \"node_modules/cosmiconfig-typescript-loader\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz\",\n      \"integrity\": \"sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\",\n        \"npm\": \">=6\"\n      },\n      \"peerDependencies\": {\n        \"@types/node\": \"*\",\n        \"cosmiconfig\": \">=7\",\n        \"ts-node\": \">=10\",\n        \"typescript\": \">=3\"\n      }\n    },\n    \"node_modules/create-require\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz\",\n      \"integrity\": \"sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==\",\n      \"dev\": true\n    },\n    \"node_modules/cross-spawn\": {\n      \"version\": \"7.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz\",\n      \"integrity\": \"sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"path-key\": \"^3.1.0\",\n        \"shebang-command\": \"^2.0.0\",\n        \"which\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/crypto-js\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz\",\n      \"integrity\": \"sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==\",\n      \"dev\": true\n    },\n    \"node_modules/crypto-random-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/css-line-break\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz\",\n      \"integrity\": \"sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==\",\n      \"dependencies\": {\n        \"utrie\": \"^1.0.2\"\n      }\n    },\n    \"node_modules/css-render\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/css-render/-/css-render-0.15.12.tgz\",\n      \"integrity\": \"sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==\",\n      \"dependencies\": {\n        \"@emotion/hash\": \"~0.8.0\",\n        \"csstype\": \"~3.0.5\"\n      }\n    },\n    \"node_modules/cssesc\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz\",\n      \"integrity\": \"sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==\",\n      \"dev\": true,\n      \"bin\": {\n        \"cssesc\": \"bin/cssesc\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/csstype\": {\n      \"version\": \"3.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz\",\n      \"integrity\": \"sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==\"\n    },\n    \"node_modules/dargs\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz\",\n      \"integrity\": \"sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/date-fns\": {\n      \"version\": \"2.29.3\",\n      \"resolved\": \"https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz\",\n      \"integrity\": \"sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==\",\n      \"engines\": {\n        \"node\": \">=0.11\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/date-fns\"\n      }\n    },\n    \"node_modules/date-fns-tz\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.8.tgz\",\n      \"integrity\": \"sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==\",\n      \"peerDependencies\": {\n        \"date-fns\": \">=2.0.0\"\n      }\n    },\n    \"node_modules/de-indent\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz\",\n      \"integrity\": \"sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==\",\n      \"dev\": true\n    },\n    \"node_modules/debug\": {\n      \"version\": \"4.3.4\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.3.4.tgz\",\n      \"integrity\": \"sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ms\": \"2.1.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"supports-color\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/decamelize\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz\",\n      \"integrity\": \"sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/decamelize-keys\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz\",\n      \"integrity\": \"sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"decamelize\": \"^1.1.0\",\n        \"map-obj\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/decamelize-keys/node_modules/map-obj\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz\",\n      \"integrity\": \"sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/deep-is\": {\n      \"version\": \"0.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz\",\n      \"integrity\": \"sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==\",\n      \"dev\": true\n    },\n    \"node_modules/deepmerge\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz\",\n      \"integrity\": \"sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/define-properties\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz\",\n      \"integrity\": \"sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-property-descriptors\": \"^1.0.0\",\n        \"object-keys\": \"^1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/delayed-stream\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz\",\n      \"integrity\": \"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.4.0\"\n      }\n    },\n    \"node_modules/didyoumean\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz\",\n      \"integrity\": \"sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==\",\n      \"dev\": true\n    },\n    \"node_modules/diff\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/diff/-/diff-4.0.2.tgz\",\n      \"integrity\": \"sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.3.1\"\n      }\n    },\n    \"node_modules/dir-glob\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz\",\n      \"integrity\": \"sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"path-type\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/dlv\": {\n      \"version\": \"1.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz\",\n      \"integrity\": \"sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==\",\n      \"dev\": true\n    },\n    \"node_modules/doctrine\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz\",\n      \"integrity\": \"sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esutils\": \"^2.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ]\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz\",\n      \"integrity\": \"sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/dot-prop\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz\",\n      \"integrity\": \"sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-obj\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/eastasianwidth\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz\",\n      \"integrity\": \"sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==\",\n      \"dev\": true\n    },\n    \"node_modules/ejs\": {\n      \"version\": \"3.1.9\",\n      \"resolved\": \"https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz\",\n      \"integrity\": \"sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"jake\": \"^10.8.5\"\n      },\n      \"bin\": {\n        \"ejs\": \"bin/cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/electron-to-chromium\": {\n      \"version\": \"1.4.369\",\n      \"resolved\": \"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.369.tgz\",\n      \"integrity\": \"sha512-LfxbHXdA/S+qyoTEA4EbhxGjrxx7WK2h6yb5K2v0UCOufUKX+VZaHbl3svlzZfv9sGseym/g3Ne4DpsgRULmqg==\",\n      \"dev\": true\n    },\n    \"node_modules/emoji-regex\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz\",\n      \"integrity\": \"sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==\",\n      \"dev\": true\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/errno\": {\n      \"version\": \"0.1.8\",\n      \"resolved\": \"https://registry.npmjs.org/errno/-/errno-0.1.8.tgz\",\n      \"integrity\": \"sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"dependencies\": {\n        \"prr\": \"~1.0.1\"\n      },\n      \"bin\": {\n        \"errno\": \"cli.js\"\n      }\n    },\n    \"node_modules/error-ex\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz\",\n      \"integrity\": \"sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-arrayish\": \"^0.2.1\"\n      }\n    },\n    \"node_modules/es-abstract\": {\n      \"version\": \"1.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz\",\n      \"integrity\": \"sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"array-buffer-byte-length\": \"^1.0.0\",\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"es-set-tostringtag\": \"^2.0.1\",\n        \"es-to-primitive\": \"^1.2.1\",\n        \"function.prototype.name\": \"^1.1.5\",\n        \"get-intrinsic\": \"^1.2.0\",\n        \"get-symbol-description\": \"^1.0.0\",\n        \"globalthis\": \"^1.0.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has\": \"^1.0.3\",\n        \"has-property-descriptors\": \"^1.0.0\",\n        \"has-proto\": \"^1.0.1\",\n        \"has-symbols\": \"^1.0.3\",\n        \"internal-slot\": \"^1.0.5\",\n        \"is-array-buffer\": \"^3.0.2\",\n        \"is-callable\": \"^1.2.7\",\n        \"is-negative-zero\": \"^2.0.2\",\n        \"is-regex\": \"^1.1.4\",\n        \"is-shared-array-buffer\": \"^1.0.2\",\n        \"is-string\": \"^1.0.7\",\n        \"is-typed-array\": \"^1.1.10\",\n        \"is-weakref\": \"^1.0.2\",\n        \"object-inspect\": \"^1.12.3\",\n        \"object-keys\": \"^1.1.1\",\n        \"object.assign\": \"^4.1.4\",\n        \"regexp.prototype.flags\": \"^1.4.3\",\n        \"safe-regex-test\": \"^1.0.0\",\n        \"string.prototype.trim\": \"^1.2.7\",\n        \"string.prototype.trimend\": \"^1.0.6\",\n        \"string.prototype.trimstart\": \"^1.0.6\",\n        \"typed-array-length\": \"^1.0.4\",\n        \"unbox-primitive\": \"^1.0.2\",\n        \"which-typed-array\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/es-set-tostringtag\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz\",\n      \"integrity\": \"sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"get-intrinsic\": \"^1.1.3\",\n        \"has\": \"^1.0.3\",\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/es-shim-unscopables\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz\",\n      \"integrity\": \"sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has\": \"^1.0.3\"\n      }\n    },\n    \"node_modules/es-to-primitive\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz\",\n      \"integrity\": \"sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-callable\": \"^1.1.4\",\n        \"is-date-object\": \"^1.0.1\",\n        \"is-symbol\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/esbuild\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz\",\n      \"integrity\": \"sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"bin\": {\n        \"esbuild\": \"bin/esbuild\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"optionalDependencies\": {\n        \"@esbuild/android-arm\": \"0.17.18\",\n        \"@esbuild/android-arm64\": \"0.17.18\",\n        \"@esbuild/android-x64\": \"0.17.18\",\n        \"@esbuild/darwin-arm64\": \"0.17.18\",\n        \"@esbuild/darwin-x64\": \"0.17.18\",\n        \"@esbuild/freebsd-arm64\": \"0.17.18\",\n        \"@esbuild/freebsd-x64\": \"0.17.18\",\n        \"@esbuild/linux-arm\": \"0.17.18\",\n        \"@esbuild/linux-arm64\": \"0.17.18\",\n        \"@esbuild/linux-ia32\": \"0.17.18\",\n        \"@esbuild/linux-loong64\": \"0.17.18\",\n        \"@esbuild/linux-mips64el\": \"0.17.18\",\n        \"@esbuild/linux-ppc64\": \"0.17.18\",\n        \"@esbuild/linux-riscv64\": \"0.17.18\",\n        \"@esbuild/linux-s390x\": \"0.17.18\",\n        \"@esbuild/linux-x64\": \"0.17.18\",\n        \"@esbuild/netbsd-x64\": \"0.17.18\",\n        \"@esbuild/openbsd-x64\": \"0.17.18\",\n        \"@esbuild/sunos-x64\": \"0.17.18\",\n        \"@esbuild/win32-arm64\": \"0.17.18\",\n        \"@esbuild/win32-ia32\": \"0.17.18\",\n        \"@esbuild/win32-x64\": \"0.17.18\"\n      }\n    },\n    \"node_modules/escalade\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz\",\n      \"integrity\": \"sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/escape-string-regexp\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz\",\n      \"integrity\": \"sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/eslint\": {\n      \"version\": \"8.39.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz\",\n      \"integrity\": \"sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"@eslint-community/regexpp\": \"^4.4.0\",\n        \"@eslint/eslintrc\": \"^2.0.2\",\n        \"@eslint/js\": \"8.39.0\",\n        \"@humanwhocodes/config-array\": \"^0.11.8\",\n        \"@humanwhocodes/module-importer\": \"^1.0.1\",\n        \"@nodelib/fs.walk\": \"^1.2.8\",\n        \"ajv\": \"^6.10.0\",\n        \"chalk\": \"^4.0.0\",\n        \"cross-spawn\": \"^7.0.2\",\n        \"debug\": \"^4.3.2\",\n        \"doctrine\": \"^3.0.0\",\n        \"escape-string-regexp\": \"^4.0.0\",\n        \"eslint-scope\": \"^7.2.0\",\n        \"eslint-visitor-keys\": \"^3.4.0\",\n        \"espree\": \"^9.5.1\",\n        \"esquery\": \"^1.4.2\",\n        \"esutils\": \"^2.0.2\",\n        \"fast-deep-equal\": \"^3.1.3\",\n        \"file-entry-cache\": \"^6.0.1\",\n        \"find-up\": \"^5.0.0\",\n        \"glob-parent\": \"^6.0.2\",\n        \"globals\": \"^13.19.0\",\n        \"grapheme-splitter\": \"^1.0.4\",\n        \"ignore\": \"^5.2.0\",\n        \"import-fresh\": \"^3.0.0\",\n        \"imurmurhash\": \"^0.1.4\",\n        \"is-glob\": \"^4.0.0\",\n        \"is-path-inside\": \"^3.0.3\",\n        \"js-sdsl\": \"^4.1.4\",\n        \"js-yaml\": \"^4.1.0\",\n        \"json-stable-stringify-without-jsonify\": \"^1.0.1\",\n        \"levn\": \"^0.4.1\",\n        \"lodash.merge\": \"^4.6.2\",\n        \"minimatch\": \"^3.1.2\",\n        \"natural-compare\": \"^1.4.0\",\n        \"optionator\": \"^0.9.1\",\n        \"strip-ansi\": \"^6.0.1\",\n        \"strip-json-comments\": \"^3.1.0\",\n        \"text-table\": \"^0.2.0\"\n      },\n      \"bin\": {\n        \"eslint\": \"bin/eslint.js\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/eslint-import-resolver-node\": {\n      \"version\": \"0.3.7\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz\",\n      \"integrity\": \"sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"debug\": \"^3.2.7\",\n        \"is-core-module\": \"^2.11.0\",\n        \"resolve\": \"^1.22.1\"\n      }\n    },\n    \"node_modules/eslint-import-resolver-node/node_modules/debug\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n      \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ms\": \"^2.1.1\"\n      }\n    },\n    \"node_modules/eslint-module-utils\": {\n      \"version\": \"2.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz\",\n      \"integrity\": \"sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"debug\": \"^3.2.7\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      },\n      \"peerDependenciesMeta\": {\n        \"eslint\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/eslint-module-utils/node_modules/debug\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n      \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ms\": \"^2.1.1\"\n      }\n    },\n    \"node_modules/eslint-plugin-antfu\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-0.35.3.tgz\",\n      \"integrity\": \"sha512-90Xct24s2n3aQhuuFFcPLhF5E6lU5s225B0VXupSjvDTuF+CmSQQLQG6KcqcdpA8O6dMbeXB9zy3SJ4aO7lndw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/utils\": \"^5.53.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-es\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz\",\n      \"integrity\": \"sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-utils\": \"^2.0.0\",\n        \"regexpp\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8.10.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=4.19.1\"\n      }\n    },\n    \"node_modules/eslint-plugin-es/node_modules/eslint-utils\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz\",\n      \"integrity\": \"sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-visitor-keys\": \"^1.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      }\n    },\n    \"node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz\",\n      \"integrity\": \"sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/eslint-plugin-eslint-comments\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz\",\n      \"integrity\": \"sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"escape-string-regexp\": \"^1.0.5\",\n        \"ignore\": \"^5.0.5\"\n      },\n      \"engines\": {\n        \"node\": \">=6.5.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=4.19.1\"\n      }\n    },\n    \"node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n      \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.8.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-html\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz\",\n      \"integrity\": \"sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"htmlparser2\": \"^8.0.1\"\n      }\n    },\n    \"node_modules/eslint-plugin-import\": {\n      \"version\": \"2.27.5\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz\",\n      \"integrity\": \"sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"array-includes\": \"^3.1.6\",\n        \"array.prototype.flat\": \"^1.3.1\",\n        \"array.prototype.flatmap\": \"^1.3.1\",\n        \"debug\": \"^3.2.7\",\n        \"doctrine\": \"^2.1.0\",\n        \"eslint-import-resolver-node\": \"^0.3.7\",\n        \"eslint-module-utils\": \"^2.7.4\",\n        \"has\": \"^1.0.3\",\n        \"is-core-module\": \"^2.11.0\",\n        \"is-glob\": \"^4.0.3\",\n        \"minimatch\": \"^3.1.2\",\n        \"object.values\": \"^1.1.6\",\n        \"resolve\": \"^1.22.1\",\n        \"semver\": \"^6.3.0\",\n        \"tsconfig-paths\": \"^3.14.1\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8\"\n      }\n    },\n    \"node_modules/eslint-plugin-import/node_modules/debug\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n      \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ms\": \"^2.1.1\"\n      }\n    },\n    \"node_modules/eslint-plugin-import/node_modules/doctrine\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz\",\n      \"integrity\": \"sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esutils\": \"^2.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-import/node_modules/semver\": {\n      \"version\": \"6.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n      \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      }\n    },\n    \"node_modules/eslint-plugin-jest\": {\n      \"version\": \"27.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz\",\n      \"integrity\": \"sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@typescript-eslint/utils\": \"^5.10.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.15.0 || ^16.10.0 || >=18.0.0\"\n      },\n      \"peerDependencies\": {\n        \"@typescript-eslint/eslint-plugin\": \"^5.0.0\",\n        \"eslint\": \"^7.0.0 || ^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@typescript-eslint/eslint-plugin\": {\n          \"optional\": true\n        },\n        \"jest\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/eslint-plugin-jsonc\": {\n      \"version\": \"2.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.7.0.tgz\",\n      \"integrity\": \"sha512-DZgC71h/hZ9t5k/OGAKOMdJCleg2neZLL7No+YYi2ZMroCN4X5huZdrLf1USbrc6UTHwYujd1EDwXHg1qJ6CYw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"jsonc-eslint-parser\": \"^2.0.4\",\n        \"natural-compare\": \"^1.4.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ota-meshi\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-markdown\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.0.tgz\",\n      \"integrity\": \"sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"mdast-util-from-markdown\": \"^0.8.5\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^6.0.0 || ^7.0.0 || ^8.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-n\": {\n      \"version\": \"15.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz\",\n      \"integrity\": \"sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"builtins\": \"^5.0.1\",\n        \"eslint-plugin-es\": \"^4.1.0\",\n        \"eslint-utils\": \"^3.0.0\",\n        \"ignore\": \"^5.1.1\",\n        \"is-core-module\": \"^2.11.0\",\n        \"minimatch\": \"^3.1.2\",\n        \"resolve\": \"^1.22.1\",\n        \"semver\": \"^7.3.8\"\n      },\n      \"engines\": {\n        \"node\": \">=12.22.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=7.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-no-only-tests\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz\",\n      \"integrity\": \"sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=5.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-promise\": {\n      \"version\": \"6.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz\",\n      \"integrity\": \"sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^7.0.0 || ^8.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-unicorn\": {\n      \"version\": \"45.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz\",\n      \"integrity\": \"sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"@eslint-community/eslint-utils\": \"^4.1.2\",\n        \"ci-info\": \"^3.6.1\",\n        \"clean-regexp\": \"^1.0.0\",\n        \"esquery\": \"^1.4.0\",\n        \"indent-string\": \"^4.0.0\",\n        \"is-builtin-module\": \"^3.2.0\",\n        \"jsesc\": \"^3.0.2\",\n        \"lodash\": \"^4.17.21\",\n        \"pluralize\": \"^8.0.0\",\n        \"read-pkg-up\": \"^7.0.1\",\n        \"regexp-tree\": \"^0.1.24\",\n        \"regjsparser\": \"^0.9.1\",\n        \"safe-regex\": \"^2.1.1\",\n        \"semver\": \"^7.3.8\",\n        \"strip-indent\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=14.18\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=8.28.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-unused-imports\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz\",\n      \"integrity\": \"sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-rule-composer\": \"^0.3.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"@typescript-eslint/eslint-plugin\": \"^5.0.0\",\n        \"eslint\": \"^8.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@typescript-eslint/eslint-plugin\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/eslint-plugin-vue\": {\n      \"version\": \"9.11.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.0.tgz\",\n      \"integrity\": \"sha512-bBCJAZnkBV7ATH4Z1E7CvN3nmtS4H7QUU3UBxPdo8WohRU+yHjnQRALpTbxMVcz0e4Mx3IyxIdP5HYODMxK9cQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@eslint-community/eslint-utils\": \"^4.3.0\",\n        \"natural-compare\": \"^1.4.0\",\n        \"nth-check\": \"^2.0.1\",\n        \"postcss-selector-parser\": \"^6.0.9\",\n        \"semver\": \"^7.3.5\",\n        \"vue-eslint-parser\": \"^9.0.1\",\n        \"xml-name-validator\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.17.0 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \"^6.2.0 || ^7.0.0 || ^8.0.0\"\n      }\n    },\n    \"node_modules/eslint-plugin-yml\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.5.0.tgz\",\n      \"integrity\": \"sha512-iygN054g+ZrnYmtOXMnT+sx9iDNXt89/m0+506cQHeG0+5jJN8hY5iOPQLd3yfd50AfK/mSasajBWruf1SoHpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.3.2\",\n        \"lodash\": \"^4.17.21\",\n        \"natural-compare\": \"^1.4.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ota-meshi\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/eslint-rule-composer\": {\n      \"version\": \"0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz\",\n      \"integrity\": \"sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0.0\"\n      }\n    },\n    \"node_modules/eslint-scope\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz\",\n      \"integrity\": \"sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esrecurse\": \"^4.3.0\",\n        \"estraverse\": \"^4.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8.0.0\"\n      }\n    },\n    \"node_modules/eslint-utils\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz\",\n      \"integrity\": \"sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-visitor-keys\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^10.0.0 || ^12.0.0 || >= 14.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=5\"\n      }\n    },\n    \"node_modules/eslint-utils/node_modules/eslint-visitor-keys\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz\",\n      \"integrity\": \"sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/eslint-visitor-keys\": {\n      \"version\": \"3.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz\",\n      \"integrity\": \"sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/eslint/node_modules/ajv\": {\n      \"version\": \"6.12.6\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz\",\n      \"integrity\": \"sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fast-deep-equal\": \"^3.1.1\",\n        \"fast-json-stable-stringify\": \"^2.0.0\",\n        \"json-schema-traverse\": \"^0.4.1\",\n        \"uri-js\": \"^4.2.2\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\n      }\n    },\n    \"node_modules/eslint/node_modules/eslint-scope\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz\",\n      \"integrity\": \"sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esrecurse\": \"^4.3.0\",\n        \"estraverse\": \"^5.2.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/eslint/node_modules/estraverse\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n      \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/eslint/node_modules/json-schema-traverse\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz\",\n      \"integrity\": \"sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==\",\n      \"dev\": true\n    },\n    \"node_modules/espree\": {\n      \"version\": \"9.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/espree/-/espree-9.5.1.tgz\",\n      \"integrity\": \"sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"acorn\": \"^8.8.0\",\n        \"acorn-jsx\": \"^5.3.2\",\n        \"eslint-visitor-keys\": \"^3.4.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/esquery\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz\",\n      \"integrity\": \"sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"estraverse\": \"^5.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10\"\n      }\n    },\n    \"node_modules/esquery/node_modules/estraverse\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n      \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/esrecurse\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz\",\n      \"integrity\": \"sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"estraverse\": \"^5.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/esrecurse/node_modules/estraverse\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n      \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/estraverse\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz\",\n      \"integrity\": \"sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/estree-walker\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz\",\n      \"integrity\": \"sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==\"\n    },\n    \"node_modules/esutils\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz\",\n      \"integrity\": \"sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/evtd\": {\n      \"version\": \"0.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/evtd/-/evtd-0.2.4.tgz\",\n      \"integrity\": \"sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==\"\n    },\n    \"node_modules/execa\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/execa/-/execa-5.1.1.tgz\",\n      \"integrity\": \"sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"cross-spawn\": \"^7.0.3\",\n        \"get-stream\": \"^6.0.0\",\n        \"human-signals\": \"^2.1.0\",\n        \"is-stream\": \"^2.0.0\",\n        \"merge-stream\": \"^2.0.0\",\n        \"npm-run-path\": \"^4.0.1\",\n        \"onetime\": \"^5.1.2\",\n        \"signal-exit\": \"^3.0.3\",\n        \"strip-final-newline\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sindresorhus/execa?sponsor=1\"\n      }\n    },\n    \"node_modules/fast-deep-equal\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz\",\n      \"integrity\": \"sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==\",\n      \"dev\": true\n    },\n    \"node_modules/fast-glob\": {\n      \"version\": \"3.2.12\",\n      \"resolved\": \"https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz\",\n      \"integrity\": \"sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"^2.0.2\",\n        \"@nodelib/fs.walk\": \"^1.2.3\",\n        \"glob-parent\": \"^5.1.2\",\n        \"merge2\": \"^1.3.0\",\n        \"micromatch\": \"^4.0.4\"\n      },\n      \"engines\": {\n        \"node\": \">=8.6.0\"\n      }\n    },\n    \"node_modules/fast-glob/node_modules/glob-parent\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz\",\n      \"integrity\": \"sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-glob\": \"^4.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/fast-json-stable-stringify\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz\",\n      \"integrity\": \"sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==\",\n      \"dev\": true\n    },\n    \"node_modules/fast-levenshtein\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz\",\n      \"integrity\": \"sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==\",\n      \"dev\": true\n    },\n    \"node_modules/fastq\": {\n      \"version\": \"1.15.0\",\n      \"resolved\": \"https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz\",\n      \"integrity\": \"sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"reusify\": \"^1.0.4\"\n      }\n    },\n    \"node_modules/file-entry-cache\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz\",\n      \"integrity\": \"sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"flat-cache\": \"^3.0.4\"\n      },\n      \"engines\": {\n        \"node\": \"^10.12.0 || >=12.0.0\"\n      }\n    },\n    \"node_modules/filelist\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz\",\n      \"integrity\": \"sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"minimatch\": \"^5.0.1\"\n      }\n    },\n    \"node_modules/filelist/node_modules/brace-expansion\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n      \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"balanced-match\": \"^1.0.0\"\n      }\n    },\n    \"node_modules/filelist/node_modules/minimatch\": {\n      \"version\": \"5.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz\",\n      \"integrity\": \"sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"brace-expansion\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/fill-range\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz\",\n      \"integrity\": \"sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"to-regex-range\": \"^5.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/find-up\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz\",\n      \"integrity\": \"sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"locate-path\": \"^6.0.0\",\n        \"path-exists\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/flat-cache\": {\n      \"version\": \"3.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz\",\n      \"integrity\": \"sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"flatted\": \"^3.1.0\",\n        \"rimraf\": \"^3.0.2\"\n      },\n      \"engines\": {\n        \"node\": \"^10.12.0 || >=12.0.0\"\n      }\n    },\n    \"node_modules/flat-cache/node_modules/glob\": {\n      \"version\": \"7.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.2.3.tgz\",\n      \"integrity\": \"sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fs.realpath\": \"^1.0.0\",\n        \"inflight\": \"^1.0.4\",\n        \"inherits\": \"2\",\n        \"minimatch\": \"^3.1.1\",\n        \"once\": \"^1.3.0\",\n        \"path-is-absolute\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/flat-cache/node_modules/rimraf\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz\",\n      \"integrity\": \"sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"glob\": \"^7.1.3\"\n      },\n      \"bin\": {\n        \"rimraf\": \"bin.js\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/flatted\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz\",\n      \"integrity\": \"sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==\",\n      \"dev\": true\n    },\n    \"node_modules/follow-redirects\": {\n      \"version\": \"1.15.2\",\n      \"resolved\": \"https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz\",\n      \"integrity\": \"sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"individual\",\n          \"url\": \"https://github.com/sponsors/RubenVerborgh\"\n        }\n      ],\n      \"engines\": {\n        \"node\": \">=4.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"debug\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/for-each\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz\",\n      \"integrity\": \"sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-callable\": \"^1.1.3\"\n      }\n    },\n    \"node_modules/form-data\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz\",\n      \"integrity\": \"sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"asynckit\": \"^0.4.0\",\n        \"combined-stream\": \"^1.0.8\",\n        \"mime-types\": \"^2.1.12\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/fraction.js\": {\n      \"version\": \"4.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz\",\n      \"integrity\": \"sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"*\"\n      },\n      \"funding\": {\n        \"type\": \"patreon\",\n        \"url\": \"https://www.patreon.com/infusion\"\n      }\n    },\n    \"node_modules/fs-extra\": {\n      \"version\": \"11.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz\",\n      \"integrity\": \"sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=14.14\"\n      }\n    },\n    \"node_modules/fs.realpath\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz\",\n      \"integrity\": \"sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==\",\n      \"dev\": true\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"dev\": true,\n      \"hasInstallScript\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/function-bind\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz\",\n      \"integrity\": \"sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==\",\n      \"dev\": true\n    },\n    \"node_modules/function.prototype.name\": {\n      \"version\": \"1.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz\",\n      \"integrity\": \"sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.3\",\n        \"es-abstract\": \"^1.19.0\",\n        \"functions-have-names\": \"^1.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/functions-have-names\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz\",\n      \"integrity\": \"sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==\",\n      \"dev\": true,\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/gensync\": {\n      \"version\": \"1.0.0-beta.2\",\n      \"resolved\": \"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz\",\n      \"integrity\": \"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6.9.0\"\n      }\n    },\n    \"node_modules/get-caller-file\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz\",\n      \"integrity\": \"sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"6.* || 8.* || >= 10.*\"\n      }\n    },\n    \"node_modules/get-intrinsic\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz\",\n      \"integrity\": \"sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"function-bind\": \"^1.1.1\",\n        \"has\": \"^1.0.3\",\n        \"has-symbols\": \"^1.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/get-own-enumerable-property-symbols\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz\",\n      \"integrity\": \"sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==\",\n      \"dev\": true\n    },\n    \"node_modules/get-stream\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz\",\n      \"integrity\": \"sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/get-symbol-description\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz\",\n      \"integrity\": \"sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/git-raw-commits\": {\n      \"version\": \"2.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz\",\n      \"integrity\": \"sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"dargs\": \"^7.0.0\",\n        \"lodash\": \"^4.17.15\",\n        \"meow\": \"^8.0.0\",\n        \"split2\": \"^3.0.0\",\n        \"through2\": \"^4.0.0\"\n      },\n      \"bin\": {\n        \"git-raw-commits\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/glob\": {\n      \"version\": \"9.3.5\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-9.3.5.tgz\",\n      \"integrity\": \"sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fs.realpath\": \"^1.0.0\",\n        \"minimatch\": \"^8.0.2\",\n        \"minipass\": \"^4.2.4\",\n        \"path-scurry\": \"^1.6.1\"\n      },\n      \"engines\": {\n        \"node\": \">=16 || 14 >=14.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/glob-parent\": {\n      \"version\": \"6.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz\",\n      \"integrity\": \"sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-glob\": \"^4.0.3\"\n      },\n      \"engines\": {\n        \"node\": \">=10.13.0\"\n      }\n    },\n    \"node_modules/glob/node_modules/brace-expansion\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n      \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"balanced-match\": \"^1.0.0\"\n      }\n    },\n    \"node_modules/glob/node_modules/minimatch\": {\n      \"version\": \"8.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz\",\n      \"integrity\": \"sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"brace-expansion\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=16 || 14 >=14.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/global-dirs\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz\",\n      \"integrity\": \"sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ini\": \"^1.3.4\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/globals\": {\n      \"version\": \"13.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/globals/-/globals-13.20.0.tgz\",\n      \"integrity\": \"sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"type-fest\": \"^0.20.2\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/globalthis\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz\",\n      \"integrity\": \"sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"define-properties\": \"^1.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/globby\": {\n      \"version\": \"11.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/globby/-/globby-11.1.0.tgz\",\n      \"integrity\": \"sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"array-union\": \"^2.1.0\",\n        \"dir-glob\": \"^3.0.1\",\n        \"fast-glob\": \"^3.2.9\",\n        \"ignore\": \"^5.2.0\",\n        \"merge2\": \"^1.4.1\",\n        \"slash\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/gopd\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz\",\n      \"integrity\": \"sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"get-intrinsic\": \"^1.1.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/graceful-fs\": {\n      \"version\": \"4.2.11\",\n      \"resolved\": \"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz\",\n      \"integrity\": \"sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==\",\n      \"dev\": true\n    },\n    \"node_modules/grapheme-splitter\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz\",\n      \"integrity\": \"sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==\",\n      \"dev\": true\n    },\n    \"node_modules/hard-rejection\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz\",\n      \"integrity\": \"sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/has\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/has/-/has-1.0.3.tgz\",\n      \"integrity\": \"sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"function-bind\": \"^1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4.0\"\n      }\n    },\n    \"node_modules/has-bigints\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz\",\n      \"integrity\": \"sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==\",\n      \"dev\": true,\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-flag\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz\",\n      \"integrity\": \"sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/has-property-descriptors\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz\",\n      \"integrity\": \"sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"get-intrinsic\": \"^1.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-symbols\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz\",\n      \"integrity\": \"sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/has-tostringtag\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz\",\n      \"integrity\": \"sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-symbols\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/he\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/he/-/he-1.2.0.tgz\",\n      \"integrity\": \"sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"he\": \"bin/he\"\n      }\n    },\n    \"node_modules/highlight.js\": {\n      \"version\": \"11.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz\",\n      \"integrity\": \"sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==\",\n      \"engines\": {\n        \"node\": \">=12.0.0\"\n      }\n    },\n    \"node_modules/hosted-git-info\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz\",\n      \"integrity\": \"sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lru-cache\": \"^6.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/html2canvas\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz\",\n      \"integrity\": \"sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==\",\n      \"dependencies\": {\n        \"css-line-break\": \"^2.1.0\",\n        \"text-segmentation\": \"^1.0.3\"\n      },\n      \"engines\": {\n        \"node\": \">=8.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"8.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz\",\n      \"integrity\": \"sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==\",\n      \"dev\": true,\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\",\n        \"entities\": \"^4.4.0\"\n      }\n    },\n    \"node_modules/human-signals\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz\",\n      \"integrity\": \"sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10.17.0\"\n      }\n    },\n    \"node_modules/husky\": {\n      \"version\": \"8.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/husky/-/husky-8.0.3.tgz\",\n      \"integrity\": \"sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==\",\n      \"dev\": true,\n      \"bin\": {\n        \"husky\": \"lib/bin.js\"\n      },\n      \"engines\": {\n        \"node\": \">=14\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/typicode\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/idb\": {\n      \"version\": \"7.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/idb/-/idb-7.1.1.tgz\",\n      \"integrity\": \"sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==\",\n      \"dev\": true\n    },\n    \"node_modules/ignore\": {\n      \"version\": \"5.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz\",\n      \"integrity\": \"sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 4\"\n      }\n    },\n    \"node_modules/image-size\": {\n      \"version\": \"0.5.5\",\n      \"resolved\": \"https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz\",\n      \"integrity\": \"sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"bin\": {\n        \"image-size\": \"bin/image-size.js\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/import-fresh\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz\",\n      \"integrity\": \"sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"parent-module\": \"^1.0.0\",\n        \"resolve-from\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/import-fresh/node_modules/resolve-from\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz\",\n      \"integrity\": \"sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/imurmurhash\": {\n      \"version\": \"0.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz\",\n      \"integrity\": \"sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.8.19\"\n      }\n    },\n    \"node_modules/indent-string\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz\",\n      \"integrity\": \"sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/inflight\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz\",\n      \"integrity\": \"sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"once\": \"^1.3.0\",\n        \"wrappy\": \"1\"\n      }\n    },\n    \"node_modules/inherits\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz\",\n      \"integrity\": \"sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==\",\n      \"dev\": true\n    },\n    \"node_modules/ini\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/ini/-/ini-1.3.8.tgz\",\n      \"integrity\": \"sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==\",\n      \"dev\": true\n    },\n    \"node_modules/internal-slot\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz\",\n      \"integrity\": \"sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"get-intrinsic\": \"^1.2.0\",\n        \"has\": \"^1.0.3\",\n        \"side-channel\": \"^1.0.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/is-alphabetical\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz\",\n      \"integrity\": \"sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/is-alphanumerical\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz\",\n      \"integrity\": \"sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-alphabetical\": \"^1.0.0\",\n        \"is-decimal\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/is-array-buffer\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz\",\n      \"integrity\": \"sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.2.0\",\n        \"is-typed-array\": \"^1.1.10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-arrayish\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz\",\n      \"integrity\": \"sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==\",\n      \"dev\": true\n    },\n    \"node_modules/is-bigint\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz\",\n      \"integrity\": \"sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-bigints\": \"^1.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-binary-path\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz\",\n      \"integrity\": \"sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"binary-extensions\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/is-boolean-object\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz\",\n      \"integrity\": \"sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-builtin-module\": {\n      \"version\": \"3.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz\",\n      \"integrity\": \"sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"builtin-modules\": \"^3.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/is-callable\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz\",\n      \"integrity\": \"sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-core-module\": {\n      \"version\": \"2.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz\",\n      \"integrity\": \"sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has\": \"^1.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-date-object\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz\",\n      \"integrity\": \"sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-decimal\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz\",\n      \"integrity\": \"sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/is-extglob\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz\",\n      \"integrity\": \"sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/is-fullwidth-code-point\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz\",\n      \"integrity\": \"sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/is-glob\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz\",\n      \"integrity\": \"sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-extglob\": \"^2.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/is-hexadecimal\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz\",\n      \"integrity\": \"sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/is-module\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz\",\n      \"integrity\": \"sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==\",\n      \"dev\": true\n    },\n    \"node_modules/is-negative-zero\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz\",\n      \"integrity\": \"sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-number\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz\",\n      \"integrity\": \"sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.12.0\"\n      }\n    },\n    \"node_modules/is-number-object\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz\",\n      \"integrity\": \"sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-obj\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz\",\n      \"integrity\": \"sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/is-path-inside\": {\n      \"version\": \"3.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz\",\n      \"integrity\": \"sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/is-plain-obj\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz\",\n      \"integrity\": \"sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/is-regex\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz\",\n      \"integrity\": \"sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-regexp\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz\",\n      \"integrity\": \"sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/is-shared-array-buffer\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz\",\n      \"integrity\": \"sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-stream\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz\",\n      \"integrity\": \"sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/is-string\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz\",\n      \"integrity\": \"sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-symbol\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz\",\n      \"integrity\": \"sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-symbols\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-text-path\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz\",\n      \"integrity\": \"sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"text-extensions\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/is-typed-array\": {\n      \"version\": \"1.1.10\",\n      \"resolved\": \"https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz\",\n      \"integrity\": \"sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has-tostringtag\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-weakref\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz\",\n      \"integrity\": \"sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/is-what\": {\n      \"version\": \"3.14.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz\",\n      \"integrity\": \"sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==\",\n      \"dev\": true\n    },\n    \"node_modules/isexe\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\",\n      \"integrity\": \"sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==\",\n      \"dev\": true\n    },\n    \"node_modules/jake\": {\n      \"version\": \"10.8.5\",\n      \"resolved\": \"https://registry.npmjs.org/jake/-/jake-10.8.5.tgz\",\n      \"integrity\": \"sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"async\": \"^3.2.3\",\n        \"chalk\": \"^4.0.2\",\n        \"filelist\": \"^1.0.1\",\n        \"minimatch\": \"^3.0.4\"\n      },\n      \"bin\": {\n        \"jake\": \"bin/cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/jest-worker\": {\n      \"version\": \"26.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz\",\n      \"integrity\": \"sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\",\n        \"merge-stream\": \"^2.0.0\",\n        \"supports-color\": \"^7.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 10.13.0\"\n      }\n    },\n    \"node_modules/jiti\": {\n      \"version\": \"1.18.2\",\n      \"resolved\": \"https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz\",\n      \"integrity\": \"sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==\",\n      \"dev\": true,\n      \"bin\": {\n        \"jiti\": \"bin/jiti.js\"\n      }\n    },\n    \"node_modules/js-sdsl\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz\",\n      \"integrity\": \"sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/js-sdsl\"\n      }\n    },\n    \"node_modules/js-tokens\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz\",\n      \"integrity\": \"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==\",\n      \"dev\": true\n    },\n    \"node_modules/js-yaml\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz\",\n      \"integrity\": \"sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"argparse\": \"^2.0.1\"\n      },\n      \"bin\": {\n        \"js-yaml\": \"bin/js-yaml.js\"\n      }\n    },\n    \"node_modules/jsesc\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz\",\n      \"integrity\": \"sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==\",\n      \"dev\": true,\n      \"bin\": {\n        \"jsesc\": \"bin/jsesc\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/json-parse-better-errors\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz\",\n      \"integrity\": \"sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==\",\n      \"dev\": true\n    },\n    \"node_modules/json-parse-even-better-errors\": {\n      \"version\": \"2.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz\",\n      \"integrity\": \"sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==\",\n      \"dev\": true\n    },\n    \"node_modules/json-schema\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz\",\n      \"integrity\": \"sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==\",\n      \"dev\": true\n    },\n    \"node_modules/json-schema-traverse\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz\",\n      \"integrity\": \"sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==\",\n      \"dev\": true\n    },\n    \"node_modules/json-stable-stringify-without-jsonify\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz\",\n      \"integrity\": \"sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==\",\n      \"dev\": true\n    },\n    \"node_modules/json5\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json5/-/json5-1.0.2.tgz\",\n      \"integrity\": \"sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"minimist\": \"^1.2.0\"\n      },\n      \"bin\": {\n        \"json5\": \"lib/cli.js\"\n      }\n    },\n    \"node_modules/jsonc-eslint-parser\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.2.0.tgz\",\n      \"integrity\": \"sha512-x5QjzBOORd+T2EjErIxJnkOEbLVEdD1ILEeBbIJt8Eq/zUn7P7M8qdnWiNVBK5f8oxnJpc6SBHOeeIEl/swPjg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"acorn\": \"^8.5.0\",\n        \"eslint-visitor-keys\": \"^3.0.0\",\n        \"espree\": \"^9.0.0\",\n        \"semver\": \"^7.3.5\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ota-meshi\"\n      }\n    },\n    \"node_modules/jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"universalify\": \"^2.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"graceful-fs\": \"^4.1.6\"\n      }\n    },\n    \"node_modules/jsonparse\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz\",\n      \"integrity\": \"sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==\",\n      \"dev\": true,\n      \"engines\": [\n        \"node >= 0.2.0\"\n      ]\n    },\n    \"node_modules/jsonpointer\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz\",\n      \"integrity\": \"sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/JSONStream\": {\n      \"version\": \"1.3.5\",\n      \"resolved\": \"https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz\",\n      \"integrity\": \"sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"jsonparse\": \"^1.2.0\",\n        \"through\": \">=2.2.7 <3\"\n      },\n      \"bin\": {\n        \"JSONStream\": \"bin.js\"\n      },\n      \"engines\": {\n        \"node\": \"*\"\n      }\n    },\n    \"node_modules/katex\": {\n      \"version\": \"0.16.6\",\n      \"resolved\": \"https://registry.npmjs.org/katex/-/katex-0.16.6.tgz\",\n      \"integrity\": \"sha512-XVB7X8jEogjJ+OY+a9JdE+VOk9i7znela0HP6WaDbpB4sUh8ghrG0Ccluu2MA2tcJbFAViBC9aVXus2UvkEr8A==\",\n      \"funding\": [\n        \"https://opencollective.com/katex\",\n        \"https://github.com/sponsors/katex\"\n      ],\n      \"dependencies\": {\n        \"commander\": \"^8.3.0\"\n      },\n      \"bin\": {\n        \"katex\": \"cli.js\"\n      }\n    },\n    \"node_modules/kind-of\": {\n      \"version\": \"6.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz\",\n      \"integrity\": \"sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/less\": {\n      \"version\": \"4.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/less/-/less-4.1.3.tgz\",\n      \"integrity\": \"sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"copy-anything\": \"^2.0.1\",\n        \"parse-node-version\": \"^1.0.1\",\n        \"tslib\": \"^2.3.0\"\n      },\n      \"bin\": {\n        \"lessc\": \"bin/lessc\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"optionalDependencies\": {\n        \"errno\": \"^0.1.1\",\n        \"graceful-fs\": \"^4.1.2\",\n        \"image-size\": \"~0.5.0\",\n        \"make-dir\": \"^2.1.0\",\n        \"mime\": \"^1.4.1\",\n        \"needle\": \"^3.1.0\",\n        \"source-map\": \"~0.6.0\"\n      }\n    },\n    \"node_modules/leven\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/leven/-/leven-3.1.0.tgz\",\n      \"integrity\": \"sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/levn\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/levn/-/levn-0.4.1.tgz\",\n      \"integrity\": \"sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"prelude-ls\": \"^1.2.1\",\n        \"type-check\": \"~0.4.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modules/lilconfig\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz\",\n      \"integrity\": \"sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/lines-and-columns\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz\",\n      \"integrity\": \"sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==\",\n      \"dev\": true\n    },\n    \"node_modules/linkify-it\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz\",\n      \"integrity\": \"sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==\",\n      \"dependencies\": {\n        \"uc.micro\": \"^1.0.1\"\n      }\n    },\n    \"node_modules/lint-staged\": {\n      \"version\": \"13.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.1.tgz\",\n      \"integrity\": \"sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"chalk\": \"5.2.0\",\n        \"cli-truncate\": \"^3.1.0\",\n        \"commander\": \"^10.0.0\",\n        \"debug\": \"^4.3.4\",\n        \"execa\": \"^7.0.0\",\n        \"lilconfig\": \"2.1.0\",\n        \"listr2\": \"^5.0.7\",\n        \"micromatch\": \"^4.0.5\",\n        \"normalize-path\": \"^3.0.0\",\n        \"object-inspect\": \"^1.12.3\",\n        \"pidtree\": \"^0.6.0\",\n        \"string-argv\": \"^0.3.1\",\n        \"yaml\": \"^2.2.1\"\n      },\n      \"bin\": {\n        \"lint-staged\": \"bin/lint-staged.js\"\n      },\n      \"engines\": {\n        \"node\": \"^14.13.1 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/lint-staged\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/chalk\": {\n      \"version\": \"5.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz\",\n      \"integrity\": \"sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.17.0 || ^14.13 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/chalk?sponsor=1\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/commander\": {\n      \"version\": \"10.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-10.0.1.tgz\",\n      \"integrity\": \"sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/execa\": {\n      \"version\": \"7.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/execa/-/execa-7.1.1.tgz\",\n      \"integrity\": \"sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"cross-spawn\": \"^7.0.3\",\n        \"get-stream\": \"^6.0.1\",\n        \"human-signals\": \"^4.3.0\",\n        \"is-stream\": \"^3.0.0\",\n        \"merge-stream\": \"^2.0.0\",\n        \"npm-run-path\": \"^5.1.0\",\n        \"onetime\": \"^6.0.0\",\n        \"signal-exit\": \"^3.0.7\",\n        \"strip-final-newline\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.18.0 || ^16.14.0 || >=18.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sindresorhus/execa?sponsor=1\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/human-signals\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz\",\n      \"integrity\": \"sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14.18.0\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/is-stream\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz\",\n      \"integrity\": \"sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^12.20.0 || ^14.13.1 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/mimic-fn\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz\",\n      \"integrity\": \"sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/npm-run-path\": {\n      \"version\": \"5.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz\",\n      \"integrity\": \"sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"path-key\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.20.0 || ^14.13.1 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/onetime\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz\",\n      \"integrity\": \"sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"mimic-fn\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/path-key\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz\",\n      \"integrity\": \"sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lint-staged/node_modules/strip-final-newline\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz\",\n      \"integrity\": \"sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/listr2\": {\n      \"version\": \"5.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz\",\n      \"integrity\": \"sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"cli-truncate\": \"^2.1.0\",\n        \"colorette\": \"^2.0.19\",\n        \"log-update\": \"^4.0.0\",\n        \"p-map\": \"^4.0.0\",\n        \"rfdc\": \"^1.3.0\",\n        \"rxjs\": \"^7.8.0\",\n        \"through\": \"^2.3.8\",\n        \"wrap-ansi\": \"^7.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.13.1 || >=16.0.0\"\n      },\n      \"peerDependencies\": {\n        \"enquirer\": \">= 2.3.0 < 3\"\n      },\n      \"peerDependenciesMeta\": {\n        \"enquirer\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/listr2/node_modules/cli-truncate\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz\",\n      \"integrity\": \"sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"slice-ansi\": \"^3.0.0\",\n        \"string-width\": \"^4.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/listr2/node_modules/emoji-regex\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n      \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n      \"dev\": true\n    },\n    \"node_modules/listr2/node_modules/is-fullwidth-code-point\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n      \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/listr2/node_modules/slice-ansi\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz\",\n      \"integrity\": \"sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^4.0.0\",\n        \"astral-regex\": \"^2.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/listr2/node_modules/string-width\": {\n      \"version\": \"4.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n      \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"emoji-regex\": \"^8.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\",\n        \"strip-ansi\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/load-json-file\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz\",\n      \"integrity\": \"sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"graceful-fs\": \"^4.1.2\",\n        \"parse-json\": \"^4.0.0\",\n        \"pify\": \"^3.0.0\",\n        \"strip-bom\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/load-json-file/node_modules/parse-json\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz\",\n      \"integrity\": \"sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"error-ex\": \"^1.3.1\",\n        \"json-parse-better-errors\": \"^1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/load-json-file/node_modules/pify\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-3.0.0.tgz\",\n      \"integrity\": \"sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/local-pkg\": {\n      \"version\": \"0.4.3\",\n      \"resolved\": \"https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz\",\n      \"integrity\": \"sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      }\n    },\n    \"node_modules/locate-path\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz\",\n      \"integrity\": \"sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"p-locate\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/lodash\": {\n      \"version\": \"4.17.21\",\n      \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz\",\n      \"integrity\": \"sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==\"\n    },\n    \"node_modules/lodash-es\": {\n      \"version\": \"4.17.21\",\n      \"resolved\": \"https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz\",\n      \"integrity\": \"sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==\"\n    },\n    \"node_modules/lodash.camelcase\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz\",\n      \"integrity\": \"sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.debounce\": {\n      \"version\": \"4.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz\",\n      \"integrity\": \"sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.isfunction\": {\n      \"version\": \"3.0.9\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz\",\n      \"integrity\": \"sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.isplainobject\": {\n      \"version\": \"4.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz\",\n      \"integrity\": \"sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.kebabcase\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz\",\n      \"integrity\": \"sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.merge\": {\n      \"version\": \"4.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz\",\n      \"integrity\": \"sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.mergewith\": {\n      \"version\": \"4.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz\",\n      \"integrity\": \"sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.snakecase\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz\",\n      \"integrity\": \"sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.sortby\": {\n      \"version\": \"4.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz\",\n      \"integrity\": \"sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.startcase\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz\",\n      \"integrity\": \"sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.uniq\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz\",\n      \"integrity\": \"sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==\",\n      \"dev\": true\n    },\n    \"node_modules/lodash.upperfirst\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz\",\n      \"integrity\": \"sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==\",\n      \"dev\": true\n    },\n    \"node_modules/log-update\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz\",\n      \"integrity\": \"sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-escapes\": \"^4.3.0\",\n        \"cli-cursor\": \"^3.1.0\",\n        \"slice-ansi\": \"^4.0.0\",\n        \"wrap-ansi\": \"^6.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/log-update/node_modules/emoji-regex\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n      \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n      \"dev\": true\n    },\n    \"node_modules/log-update/node_modules/is-fullwidth-code-point\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n      \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/log-update/node_modules/slice-ansi\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz\",\n      \"integrity\": \"sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^4.0.0\",\n        \"astral-regex\": \"^2.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/slice-ansi?sponsor=1\"\n      }\n    },\n    \"node_modules/log-update/node_modules/string-width\": {\n      \"version\": \"4.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n      \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"emoji-regex\": \"^8.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\",\n        \"strip-ansi\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/log-update/node_modules/wrap-ansi\": {\n      \"version\": \"6.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz\",\n      \"integrity\": \"sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^4.0.0\",\n        \"string-width\": \"^4.1.0\",\n        \"strip-ansi\": \"^6.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/lru-cache\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz\",\n      \"integrity\": \"sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"yallist\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/magic-string\": {\n      \"version\": \"0.27.0\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz\",\n      \"integrity\": \"sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/sourcemap-codec\": \"^1.4.13\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/make-dir\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz\",\n      \"integrity\": \"sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"dependencies\": {\n        \"pify\": \"^4.0.1\",\n        \"semver\": \"^5.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/make-dir/node_modules/semver\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n      \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver\"\n      }\n    },\n    \"node_modules/make-error\": {\n      \"version\": \"1.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz\",\n      \"integrity\": \"sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==\",\n      \"dev\": true\n    },\n    \"node_modules/map-obj\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz\",\n      \"integrity\": \"sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/markdown-it\": {\n      \"version\": \"13.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz\",\n      \"integrity\": \"sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==\",\n      \"dependencies\": {\n        \"argparse\": \"^2.0.1\",\n        \"entities\": \"~3.0.1\",\n        \"linkify-it\": \"^4.0.1\",\n        \"mdurl\": \"^1.0.1\",\n        \"uc.micro\": \"^1.0.5\"\n      },\n      \"bin\": {\n        \"markdown-it\": \"bin/markdown-it.js\"\n      }\n    },\n    \"node_modules/markdown-it-link-attributes\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz\",\n      \"integrity\": \"sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==\",\n      \"dev\": true\n    },\n    \"node_modules/markdown-it/node_modules/entities\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/entities/-/entities-3.0.1.tgz\",\n      \"integrity\": \"sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/mdast-util-from-markdown\": {\n      \"version\": \"0.8.5\",\n      \"resolved\": \"https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz\",\n      \"integrity\": \"sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/mdast\": \"^3.0.0\",\n        \"mdast-util-to-string\": \"^2.0.0\",\n        \"micromark\": \"~2.11.0\",\n        \"parse-entities\": \"^2.0.0\",\n        \"unist-util-stringify-position\": \"^2.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/unified\"\n      }\n    },\n    \"node_modules/mdast-util-to-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==\",\n      \"dev\": true,\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/unified\"\n      }\n    },\n    \"node_modules/mdurl\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz\",\n      \"integrity\": \"sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==\"\n    },\n    \"node_modules/memorystream\": {\n      \"version\": \"0.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz\",\n      \"integrity\": \"sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.10.0\"\n      }\n    },\n    \"node_modules/meow\": {\n      \"version\": \"8.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/meow/-/meow-8.1.2.tgz\",\n      \"integrity\": \"sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/minimist\": \"^1.2.0\",\n        \"camelcase-keys\": \"^6.2.2\",\n        \"decamelize-keys\": \"^1.1.0\",\n        \"hard-rejection\": \"^2.1.0\",\n        \"minimist-options\": \"4.1.0\",\n        \"normalize-package-data\": \"^3.0.0\",\n        \"read-pkg-up\": \"^7.0.1\",\n        \"redent\": \"^3.0.0\",\n        \"trim-newlines\": \"^3.0.0\",\n        \"type-fest\": \"^0.18.0\",\n        \"yargs-parser\": \"^20.2.3\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/meow/node_modules/type-fest\": {\n      \"version\": \"0.18.1\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz\",\n      \"integrity\": \"sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/merge-stream\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz\",\n      \"integrity\": \"sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==\",\n      \"dev\": true\n    },\n    \"node_modules/merge2\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz\",\n      \"integrity\": \"sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/micromark\": {\n      \"version\": \"2.11.4\",\n      \"resolved\": \"https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz\",\n      \"integrity\": \"sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"GitHub Sponsors\",\n          \"url\": \"https://github.com/sponsors/unifiedjs\"\n        },\n        {\n          \"type\": \"OpenCollective\",\n          \"url\": \"https://opencollective.com/unified\"\n        }\n      ],\n      \"dependencies\": {\n        \"debug\": \"^4.0.0\",\n        \"parse-entities\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/micromatch\": {\n      \"version\": \"4.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz\",\n      \"integrity\": \"sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"braces\": \"^3.0.2\",\n        \"picomatch\": \"^2.3.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8.6\"\n      }\n    },\n    \"node_modules/mime\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime/-/mime-1.6.0.tgz\",\n      \"integrity\": \"sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"bin\": {\n        \"mime\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/mime-db\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz\",\n      \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mime-types\": {\n      \"version\": \"2.1.35\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz\",\n      \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"mime-db\": \"1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.6\"\n      }\n    },\n    \"node_modules/mimic-fn\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz\",\n      \"integrity\": \"sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/min-indent\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz\",\n      \"integrity\": \"sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/minimatch\": {\n      \"version\": \"3.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz\",\n      \"integrity\": \"sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"brace-expansion\": \"^1.1.7\"\n      },\n      \"engines\": {\n        \"node\": \"*\"\n      }\n    },\n    \"node_modules/minimist\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz\",\n      \"integrity\": \"sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==\",\n      \"dev\": true,\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/minimist-options\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz\",\n      \"integrity\": \"sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"arrify\": \"^1.0.1\",\n        \"is-plain-obj\": \"^1.1.0\",\n        \"kind-of\": \"^6.0.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/minipass\": {\n      \"version\": \"4.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz\",\n      \"integrity\": \"sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/ms\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.2.tgz\",\n      \"integrity\": \"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==\",\n      \"dev\": true\n    },\n    \"node_modules/muggle-string\": {\n      \"version\": \"0.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/muggle-string/-/muggle-string-0.2.2.tgz\",\n      \"integrity\": \"sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==\",\n      \"dev\": true\n    },\n    \"node_modules/mz\": {\n      \"version\": \"2.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/mz/-/mz-2.7.0.tgz\",\n      \"integrity\": \"sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"any-promise\": \"^1.0.0\",\n        \"object-assign\": \"^4.0.1\",\n        \"thenify-all\": \"^1.0.0\"\n      }\n    },\n    \"node_modules/naive-ui\": {\n      \"version\": \"2.34.3\",\n      \"resolved\": \"https://registry.npmjs.org/naive-ui/-/naive-ui-2.34.3.tgz\",\n      \"integrity\": \"sha512-fUMr0dzb/iGsOTWgoblPVobY5X5dihQ1eam5dA+H74oyLYAvgX4pL96xQFPBLIYqvyRFBAsN85kHN5pLqdtpxA==\",\n      \"dependencies\": {\n        \"@css-render/plugin-bem\": \"^0.15.10\",\n        \"@css-render/vue3-ssr\": \"^0.15.10\",\n        \"@types/katex\": \"^0.14.0\",\n        \"@types/lodash\": \"^4.14.181\",\n        \"@types/lodash-es\": \"^4.17.6\",\n        \"async-validator\": \"^4.0.7\",\n        \"css-render\": \"^0.15.10\",\n        \"date-fns\": \"^2.28.0\",\n        \"date-fns-tz\": \"^1.3.3\",\n        \"evtd\": \"^0.2.4\",\n        \"highlight.js\": \"^11.5.0\",\n        \"lodash\": \"^4.17.21\",\n        \"lodash-es\": \"^4.17.21\",\n        \"seemly\": \"^0.3.6\",\n        \"treemate\": \"^0.3.11\",\n        \"vdirs\": \"^0.1.8\",\n        \"vooks\": \"^0.2.12\",\n        \"vueuc\": \"^0.4.47\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/naive-ui/node_modules/@types/katex\": {\n      \"version\": \"0.14.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz\",\n      \"integrity\": \"sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==\"\n    },\n    \"node_modules/nanoid\": {\n      \"version\": \"3.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz\",\n      \"integrity\": \"sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/ai\"\n        }\n      ],\n      \"bin\": {\n        \"nanoid\": \"bin/nanoid.cjs\"\n      },\n      \"engines\": {\n        \"node\": \"^10 || ^12 || ^13.7 || ^14 || >=15.0.1\"\n      }\n    },\n    \"node_modules/natural-compare\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz\",\n      \"integrity\": \"sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==\",\n      \"dev\": true\n    },\n    \"node_modules/natural-compare-lite\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz\",\n      \"integrity\": \"sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==\",\n      \"dev\": true\n    },\n    \"node_modules/needle\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/needle/-/needle-3.2.0.tgz\",\n      \"integrity\": \"sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"dependencies\": {\n        \"debug\": \"^3.2.6\",\n        \"iconv-lite\": \"^0.6.3\",\n        \"sax\": \"^1.2.4\"\n      },\n      \"bin\": {\n        \"needle\": \"bin/needle\"\n      },\n      \"engines\": {\n        \"node\": \">= 4.4.x\"\n      }\n    },\n    \"node_modules/needle/node_modules/debug\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n      \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"dependencies\": {\n        \"ms\": \"^2.1.1\"\n      }\n    },\n    \"node_modules/nice-try\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz\",\n      \"integrity\": \"sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==\",\n      \"dev\": true\n    },\n    \"node_modules/node-releases\": {\n      \"version\": \"2.0.10\",\n      \"resolved\": \"https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz\",\n      \"integrity\": \"sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==\",\n      \"dev\": true\n    },\n    \"node_modules/normalize-package-data\": {\n      \"version\": \"3.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz\",\n      \"integrity\": \"sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"hosted-git-info\": \"^4.0.1\",\n        \"is-core-module\": \"^2.5.0\",\n        \"semver\": \"^7.3.4\",\n        \"validate-npm-package-license\": \"^3.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/normalize-path\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz\",\n      \"integrity\": \"sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/normalize-range\": {\n      \"version\": \"0.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz\",\n      \"integrity\": \"sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/npm-run-all\": {\n      \"version\": \"4.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz\",\n      \"integrity\": \"sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^3.2.1\",\n        \"chalk\": \"^2.4.1\",\n        \"cross-spawn\": \"^6.0.5\",\n        \"memorystream\": \"^0.3.1\",\n        \"minimatch\": \"^3.0.4\",\n        \"pidtree\": \"^0.3.0\",\n        \"read-pkg\": \"^3.0.0\",\n        \"shell-quote\": \"^1.6.1\",\n        \"string.prototype.padend\": \"^3.0.0\"\n      },\n      \"bin\": {\n        \"npm-run-all\": \"bin/npm-run-all/index.js\",\n        \"run-p\": \"bin/run-p/index.js\",\n        \"run-s\": \"bin/run-s/index.js\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/ansi-styles\": {\n      \"version\": \"3.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz\",\n      \"integrity\": \"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-convert\": \"^1.9.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/chalk\": {\n      \"version\": \"2.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz\",\n      \"integrity\": \"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^3.2.1\",\n        \"escape-string-regexp\": \"^1.0.5\",\n        \"supports-color\": \"^5.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/color-convert\": {\n      \"version\": \"1.9.3\",\n      \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz\",\n      \"integrity\": \"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"color-name\": \"1.1.3\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/color-name\": {\n      \"version\": \"1.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz\",\n      \"integrity\": \"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==\",\n      \"dev\": true\n    },\n    \"node_modules/npm-run-all/node_modules/cross-spawn\": {\n      \"version\": \"6.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz\",\n      \"integrity\": \"sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"nice-try\": \"^1.0.4\",\n        \"path-key\": \"^2.0.1\",\n        \"semver\": \"^5.5.0\",\n        \"shebang-command\": \"^1.2.0\",\n        \"which\": \"^1.2.9\"\n      },\n      \"engines\": {\n        \"node\": \">=4.8\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/escape-string-regexp\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n      \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.8.0\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/has-flag\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz\",\n      \"integrity\": \"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/path-key\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz\",\n      \"integrity\": \"sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/pidtree\": {\n      \"version\": \"0.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz\",\n      \"integrity\": \"sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==\",\n      \"dev\": true,\n      \"bin\": {\n        \"pidtree\": \"bin/pidtree.js\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/semver\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n      \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/shebang-command\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz\",\n      \"integrity\": \"sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"shebang-regex\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/shebang-regex\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz\",\n      \"integrity\": \"sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/supports-color\": {\n      \"version\": \"5.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz\",\n      \"integrity\": \"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-flag\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/npm-run-all/node_modules/which\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-1.3.1.tgz\",\n      \"integrity\": \"sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"isexe\": \"^2.0.0\"\n      },\n      \"bin\": {\n        \"which\": \"bin/which\"\n      }\n    },\n    \"node_modules/npm-run-path\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz\",\n      \"integrity\": \"sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"path-key\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/object-assign\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz\",\n      \"integrity\": \"sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/object-hash\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz\",\n      \"integrity\": \"sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/object-inspect\": {\n      \"version\": \"1.12.3\",\n      \"resolved\": \"https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz\",\n      \"integrity\": \"sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==\",\n      \"dev\": true,\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/object-keys\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz\",\n      \"integrity\": \"sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      }\n    },\n    \"node_modules/object.assign\": {\n      \"version\": \"4.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz\",\n      \"integrity\": \"sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"has-symbols\": \"^1.0.3\",\n        \"object-keys\": \"^1.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/object.values\": {\n      \"version\": \"1.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz\",\n      \"integrity\": \"sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/once\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/once/-/once-1.4.0.tgz\",\n      \"integrity\": \"sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"wrappy\": \"1\"\n      }\n    },\n    \"node_modules/onetime\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz\",\n      \"integrity\": \"sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"mimic-fn\": \"^2.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/optionator\": {\n      \"version\": \"0.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz\",\n      \"integrity\": \"sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"deep-is\": \"^0.1.3\",\n        \"fast-levenshtein\": \"^2.0.6\",\n        \"levn\": \"^0.4.1\",\n        \"prelude-ls\": \"^1.2.1\",\n        \"type-check\": \"^0.4.0\",\n        \"word-wrap\": \"^1.2.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modules/p-limit\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz\",\n      \"integrity\": \"sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"yocto-queue\": \"^0.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/p-locate\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz\",\n      \"integrity\": \"sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"p-limit\": \"^3.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/p-map\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz\",\n      \"integrity\": \"sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"aggregate-error\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/p-try\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz\",\n      \"integrity\": \"sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/parent-module\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz\",\n      \"integrity\": \"sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"callsites\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/parse-entities\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz\",\n      \"integrity\": \"sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"character-entities\": \"^1.0.0\",\n        \"character-entities-legacy\": \"^1.0.0\",\n        \"character-reference-invalid\": \"^1.0.0\",\n        \"is-alphanumerical\": \"^1.0.0\",\n        \"is-decimal\": \"^1.0.0\",\n        \"is-hexadecimal\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"type\": \"github\",\n        \"url\": \"https://github.com/sponsors/wooorm\"\n      }\n    },\n    \"node_modules/parse-json\": {\n      \"version\": \"5.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz\",\n      \"integrity\": \"sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/code-frame\": \"^7.0.0\",\n        \"error-ex\": \"^1.3.1\",\n        \"json-parse-even-better-errors\": \"^2.3.0\",\n        \"lines-and-columns\": \"^1.1.6\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/parse-node-version\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz\",\n      \"integrity\": \"sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.10\"\n      }\n    },\n    \"node_modules/path-exists\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz\",\n      \"integrity\": \"sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/path-is-absolute\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz\",\n      \"integrity\": \"sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/path-key\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz\",\n      \"integrity\": \"sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/path-parse\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz\",\n      \"integrity\": \"sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==\",\n      \"dev\": true\n    },\n    \"node_modules/path-scurry\": {\n      \"version\": \"1.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz\",\n      \"integrity\": \"sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lru-cache\": \"^9.0.0\",\n        \"minipass\": \"^5.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=16 || 14 >=14.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/path-scurry/node_modules/lru-cache\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz\",\n      \"integrity\": \"sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"14 || >=16.14\"\n      }\n    },\n    \"node_modules/path-scurry/node_modules/minipass\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz\",\n      \"integrity\": \"sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/path-type\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz\",\n      \"integrity\": \"sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/picocolors\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz\",\n      \"integrity\": \"sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==\"\n    },\n    \"node_modules/picomatch\": {\n      \"version\": \"2.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz\",\n      \"integrity\": \"sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8.6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/jonschlinkert\"\n      }\n    },\n    \"node_modules/pidtree\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz\",\n      \"integrity\": \"sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==\",\n      \"dev\": true,\n      \"bin\": {\n        \"pidtree\": \"bin/pidtree.js\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10\"\n      }\n    },\n    \"node_modules/pify\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-4.0.1.tgz\",\n      \"integrity\": \"sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/pinia\": {\n      \"version\": \"2.0.35\",\n      \"resolved\": \"https://registry.npmjs.org/pinia/-/pinia-2.0.35.tgz\",\n      \"integrity\": \"sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==\",\n      \"dependencies\": {\n        \"@vue/devtools-api\": \"^6.5.0\",\n        \"vue-demi\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/posva\"\n      },\n      \"peerDependencies\": {\n        \"@vue/composition-api\": \"^1.4.0\",\n        \"typescript\": \">=4.4.4\",\n        \"vue\": \"^2.6.14 || ^3.2.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@vue/composition-api\": {\n          \"optional\": true\n        },\n        \"typescript\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/pinia/node_modules/vue-demi\": {\n      \"version\": \"0.14.0\",\n      \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n      \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n      \"hasInstallScript\": true,\n      \"bin\": {\n        \"vue-demi-fix\": \"bin/vue-demi-fix.js\",\n        \"vue-demi-switch\": \"bin/vue-demi-switch.js\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      },\n      \"peerDependencies\": {\n        \"@vue/composition-api\": \"^1.0.0-rc.1\",\n        \"vue\": \"^3.0.0-0 || ^2.6.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@vue/composition-api\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/pirates\": {\n      \"version\": \"4.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz\",\n      \"integrity\": \"sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/pluralize\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz\",\n      \"integrity\": \"sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/postcss\": {\n      \"version\": \"8.4.23\",\n      \"resolved\": \"https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz\",\n      \"integrity\": \"sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==\",\n      \"funding\": [\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/postcss/\"\n        },\n        {\n          \"type\": \"tidelift\",\n          \"url\": \"https://tidelift.com/funding/github/npm/postcss\"\n        },\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/ai\"\n        }\n      ],\n      \"dependencies\": {\n        \"nanoid\": \"^3.3.6\",\n        \"picocolors\": \"^1.0.0\",\n        \"source-map-js\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \"^10 || ^12 || >=14\"\n      }\n    },\n    \"node_modules/postcss-import\": {\n      \"version\": \"14.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz\",\n      \"integrity\": \"sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"postcss-value-parser\": \"^4.0.0\",\n        \"read-cache\": \"^1.0.0\",\n        \"resolve\": \"^1.1.7\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \"^8.0.0\"\n      }\n    },\n    \"node_modules/postcss-js\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz\",\n      \"integrity\": \"sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"camelcase-css\": \"^2.0.1\"\n      },\n      \"engines\": {\n        \"node\": \"^12 || ^14 || >= 16\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/postcss/\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \"^8.4.21\"\n      }\n    },\n    \"node_modules/postcss-load-config\": {\n      \"version\": \"3.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz\",\n      \"integrity\": \"sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lilconfig\": \"^2.0.5\",\n        \"yaml\": \"^1.10.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 10\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/postcss/\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \">=8.0.9\",\n        \"ts-node\": \">=9.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"postcss\": {\n          \"optional\": true\n        },\n        \"ts-node\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/postcss-load-config/node_modules/yaml\": {\n      \"version\": \"1.10.2\",\n      \"resolved\": \"https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz\",\n      \"integrity\": \"sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/postcss-nested\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz\",\n      \"integrity\": \"sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"postcss-selector-parser\": \"^6.0.10\"\n      },\n      \"engines\": {\n        \"node\": \">=12.0\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/postcss/\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \"^8.2.14\"\n      }\n    },\n    \"node_modules/postcss-selector-parser\": {\n      \"version\": \"6.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz\",\n      \"integrity\": \"sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"cssesc\": \"^3.0.0\",\n        \"util-deprecate\": \"^1.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/postcss-value-parser\": {\n      \"version\": \"4.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz\",\n      \"integrity\": \"sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==\",\n      \"dev\": true\n    },\n    \"node_modules/prelude-ls\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz\",\n      \"integrity\": \"sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modules/pretty-bytes\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz\",\n      \"integrity\": \"sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \"^14.13.1 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/proxy-from-env\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz\",\n      \"integrity\": \"sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==\",\n      \"dev\": true\n    },\n    \"node_modules/prr\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/prr/-/prr-1.0.1.tgz\",\n      \"integrity\": \"sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"node_modules/punycode\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz\",\n      \"integrity\": \"sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/q\": {\n      \"version\": \"1.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/q/-/q-1.5.1.tgz\",\n      \"integrity\": \"sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.6.0\",\n        \"teleport\": \">=0.2.0\"\n      }\n    },\n    \"node_modules/queue-microtask\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz\",\n      \"integrity\": \"sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/feross\"\n        },\n        {\n          \"type\": \"patreon\",\n          \"url\": \"https://www.patreon.com/feross\"\n        },\n        {\n          \"type\": \"consulting\",\n          \"url\": \"https://feross.org/support\"\n        }\n      ]\n    },\n    \"node_modules/quick-lru\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz\",\n      \"integrity\": \"sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/randombytes\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz\",\n      \"integrity\": \"sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"safe-buffer\": \"^5.1.0\"\n      }\n    },\n    \"node_modules/read-cache\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz\",\n      \"integrity\": \"sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"pify\": \"^2.3.0\"\n      }\n    },\n    \"node_modules/read-cache/node_modules/pify\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-2.3.0.tgz\",\n      \"integrity\": \"sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/read-pkg\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz\",\n      \"integrity\": \"sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"load-json-file\": \"^4.0.0\",\n        \"normalize-package-data\": \"^2.3.2\",\n        \"path-type\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/read-pkg-up\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz\",\n      \"integrity\": \"sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"find-up\": \"^4.1.0\",\n        \"read-pkg\": \"^5.2.0\",\n        \"type-fest\": \"^0.8.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/find-up\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz\",\n      \"integrity\": \"sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"locate-path\": \"^5.0.0\",\n        \"path-exists\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/hosted-git-info\": {\n      \"version\": \"2.8.9\",\n      \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz\",\n      \"integrity\": \"sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==\",\n      \"dev\": true\n    },\n    \"node_modules/read-pkg-up/node_modules/locate-path\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz\",\n      \"integrity\": \"sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"p-locate\": \"^4.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/normalize-package-data\": {\n      \"version\": \"2.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz\",\n      \"integrity\": \"sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"hosted-git-info\": \"^2.1.4\",\n        \"resolve\": \"^1.10.0\",\n        \"semver\": \"2 || 3 || 4 || 5\",\n        \"validate-npm-package-license\": \"^3.0.1\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/p-limit\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz\",\n      \"integrity\": \"sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"p-try\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/p-locate\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz\",\n      \"integrity\": \"sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"p-limit\": \"^2.2.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/read-pkg\": {\n      \"version\": \"5.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz\",\n      \"integrity\": \"sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/normalize-package-data\": \"^2.4.0\",\n        \"normalize-package-data\": \"^2.5.0\",\n        \"parse-json\": \"^5.0.0\",\n        \"type-fest\": \"^0.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz\",\n      \"integrity\": \"sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/semver\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n      \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver\"\n      }\n    },\n    \"node_modules/read-pkg-up/node_modules/type-fest\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz\",\n      \"integrity\": \"sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/read-pkg/node_modules/hosted-git-info\": {\n      \"version\": \"2.8.9\",\n      \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz\",\n      \"integrity\": \"sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==\",\n      \"dev\": true\n    },\n    \"node_modules/read-pkg/node_modules/normalize-package-data\": {\n      \"version\": \"2.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz\",\n      \"integrity\": \"sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"hosted-git-info\": \"^2.1.4\",\n        \"resolve\": \"^1.10.0\",\n        \"semver\": \"2 || 3 || 4 || 5\",\n        \"validate-npm-package-license\": \"^3.0.1\"\n      }\n    },\n    \"node_modules/read-pkg/node_modules/path-type\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz\",\n      \"integrity\": \"sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"pify\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/read-pkg/node_modules/pify\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-3.0.0.tgz\",\n      \"integrity\": \"sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/read-pkg/node_modules/semver\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n      \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n      \"dev\": true,\n      \"bin\": {\n        \"semver\": \"bin/semver\"\n      }\n    },\n    \"node_modules/readable-stream\": {\n      \"version\": \"3.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz\",\n      \"integrity\": \"sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"inherits\": \"^2.0.3\",\n        \"string_decoder\": \"^1.1.1\",\n        \"util-deprecate\": \"^1.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/readdirp\": {\n      \"version\": \"3.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz\",\n      \"integrity\": \"sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"picomatch\": \"^2.2.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8.10.0\"\n      }\n    },\n    \"node_modules/redent\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/redent/-/redent-3.0.0.tgz\",\n      \"integrity\": \"sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"indent-string\": \"^4.0.0\",\n        \"strip-indent\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/regenerate\": {\n      \"version\": \"1.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz\",\n      \"integrity\": \"sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==\",\n      \"dev\": true\n    },\n    \"node_modules/regenerate-unicode-properties\": {\n      \"version\": \"10.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz\",\n      \"integrity\": \"sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"regenerate\": \"^1.4.2\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/regenerator-runtime\": {\n      \"version\": \"0.13.11\",\n      \"resolved\": \"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz\",\n      \"integrity\": \"sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==\",\n      \"dev\": true\n    },\n    \"node_modules/regenerator-transform\": {\n      \"version\": \"0.15.1\",\n      \"resolved\": \"https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz\",\n      \"integrity\": \"sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/runtime\": \"^7.8.4\"\n      }\n    },\n    \"node_modules/regexp-tree\": {\n      \"version\": \"0.1.25\",\n      \"resolved\": \"https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.25.tgz\",\n      \"integrity\": \"sha512-szcL3aqw+vEeuxhL1AMYRyeMP+goYF5I/guaH10uJX5xbGyeQeNPPneaj3ZWVmGLCDxrVaaYekkr5R12gk4dJw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"regexp-tree\": \"bin/regexp-tree\"\n      }\n    },\n    \"node_modules/regexp.prototype.flags\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz\",\n      \"integrity\": \"sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.2.0\",\n        \"functions-have-names\": \"^1.2.3\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/regexpp\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz\",\n      \"integrity\": \"sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      }\n    },\n    \"node_modules/regexpu-core\": {\n      \"version\": \"5.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz\",\n      \"integrity\": \"sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/regjsgen\": \"^0.8.0\",\n        \"regenerate\": \"^1.4.2\",\n        \"regenerate-unicode-properties\": \"^10.1.0\",\n        \"regjsparser\": \"^0.9.1\",\n        \"unicode-match-property-ecmascript\": \"^2.0.0\",\n        \"unicode-match-property-value-ecmascript\": \"^2.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/regjsparser\": {\n      \"version\": \"0.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz\",\n      \"integrity\": \"sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"jsesc\": \"~0.5.0\"\n      },\n      \"bin\": {\n        \"regjsparser\": \"bin/parser\"\n      }\n    },\n    \"node_modules/regjsparser/node_modules/jsesc\": {\n      \"version\": \"0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz\",\n      \"integrity\": \"sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==\",\n      \"dev\": true,\n      \"bin\": {\n        \"jsesc\": \"bin/jsesc\"\n      }\n    },\n    \"node_modules/require-directory\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz\",\n      \"integrity\": \"sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/require-from-string\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz\",\n      \"integrity\": \"sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/resolve\": {\n      \"version\": \"1.22.2\",\n      \"resolved\": \"https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz\",\n      \"integrity\": \"sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-core-module\": \"^2.11.0\",\n        \"path-parse\": \"^1.0.7\",\n        \"supports-preserve-symlinks-flag\": \"^1.0.0\"\n      },\n      \"bin\": {\n        \"resolve\": \"bin/resolve\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/resolve-from\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz\",\n      \"integrity\": \"sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/resolve-global\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz\",\n      \"integrity\": \"sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"global-dirs\": \"^0.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/restore-cursor\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz\",\n      \"integrity\": \"sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"onetime\": \"^5.1.0\",\n        \"signal-exit\": \"^3.0.2\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/reusify\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz\",\n      \"integrity\": \"sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"iojs\": \">=1.0.0\",\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/rfdc\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz\",\n      \"integrity\": \"sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==\",\n      \"dev\": true\n    },\n    \"node_modules/rimraf\": {\n      \"version\": \"4.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz\",\n      \"integrity\": \"sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"glob\": \"^9.2.0\"\n      },\n      \"bin\": {\n        \"rimraf\": \"dist/cjs/src/bin.js\"\n      },\n      \"engines\": {\n        \"node\": \">=14\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/rollup\": {\n      \"version\": \"3.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/rollup/-/rollup-3.20.7.tgz\",\n      \"integrity\": \"sha512-P7E2zezKSLhWnTz46XxjSmInrbOCiul1yf+kJccMxT56vxjHwCbDfoLbiqFgu+WQoo9ij2PkraYaBstgB2prBA==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rollup\": \"dist/bin/rollup\"\n      },\n      \"engines\": {\n        \"node\": \">=14.18.0\",\n        \"npm\": \">=8.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.2\"\n      }\n    },\n    \"node_modules/run-parallel\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz\",\n      \"integrity\": \"sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/feross\"\n        },\n        {\n          \"type\": \"patreon\",\n          \"url\": \"https://www.patreon.com/feross\"\n        },\n        {\n          \"type\": \"consulting\",\n          \"url\": \"https://feross.org/support\"\n        }\n      ],\n      \"dependencies\": {\n        \"queue-microtask\": \"^1.2.2\"\n      }\n    },\n    \"node_modules/rxjs\": {\n      \"version\": \"7.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz\",\n      \"integrity\": \"sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"tslib\": \"^2.1.0\"\n      }\n    },\n    \"node_modules/safe-buffer\": {\n      \"version\": \"5.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz\",\n      \"integrity\": \"sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/feross\"\n        },\n        {\n          \"type\": \"patreon\",\n          \"url\": \"https://www.patreon.com/feross\"\n        },\n        {\n          \"type\": \"consulting\",\n          \"url\": \"https://feross.org/support\"\n        }\n      ]\n    },\n    \"node_modules/safe-regex\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz\",\n      \"integrity\": \"sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"regexp-tree\": \"~0.1.1\"\n      }\n    },\n    \"node_modules/safe-regex-test\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz\",\n      \"integrity\": \"sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"is-regex\": \"^1.1.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"node_modules/sax\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/sax/-/sax-1.2.4.tgz\",\n      \"integrity\": \"sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"node_modules/seemly\": {\n      \"version\": \"0.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/seemly/-/seemly-0.3.6.tgz\",\n      \"integrity\": \"sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==\"\n    },\n    \"node_modules/semver\": {\n      \"version\": \"7.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-7.3.8.tgz\",\n      \"integrity\": \"sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lru-cache\": \"^6.0.0\"\n      },\n      \"bin\": {\n        \"semver\": \"bin/semver.js\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/serialize-javascript\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz\",\n      \"integrity\": \"sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"randombytes\": \"^2.1.0\"\n      }\n    },\n    \"node_modules/shebang-command\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz\",\n      \"integrity\": \"sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"shebang-regex\": \"^3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/shebang-regex\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz\",\n      \"integrity\": \"sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/shell-quote\": {\n      \"version\": \"1.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz\",\n      \"integrity\": \"sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==\",\n      \"dev\": true,\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/side-channel\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz\",\n      \"integrity\": \"sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.0\",\n        \"get-intrinsic\": \"^1.0.2\",\n        \"object-inspect\": \"^1.9.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/signal-exit\": {\n      \"version\": \"3.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz\",\n      \"integrity\": \"sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==\",\n      \"dev\": true\n    },\n    \"node_modules/slash\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slash/-/slash-3.0.0.tgz\",\n      \"integrity\": \"sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/slice-ansi\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz\",\n      \"integrity\": \"sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^6.0.0\",\n        \"is-fullwidth-code-point\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/slice-ansi?sponsor=1\"\n      }\n    },\n    \"node_modules/slice-ansi/node_modules/ansi-styles\": {\n      \"version\": \"6.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz\",\n      \"integrity\": \"sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/ansi-styles?sponsor=1\"\n      }\n    },\n    \"node_modules/source-map\": {\n      \"version\": \"0.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz\",\n      \"integrity\": \"sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==\",\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/source-map-js\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz\",\n      \"integrity\": \"sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==\",\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/source-map-support\": {\n      \"version\": \"0.5.21\",\n      \"resolved\": \"https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz\",\n      \"integrity\": \"sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"buffer-from\": \"^1.0.0\",\n        \"source-map\": \"^0.6.0\"\n      }\n    },\n    \"node_modules/sourcemap-codec\": {\n      \"version\": \"1.4.8\",\n      \"resolved\": \"https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz\",\n      \"integrity\": \"sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==\",\n      \"deprecated\": \"Please use @jridgewell/sourcemap-codec instead\"\n    },\n    \"node_modules/spdx-correct\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz\",\n      \"integrity\": \"sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"spdx-expression-parse\": \"^3.0.0\",\n        \"spdx-license-ids\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/spdx-exceptions\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz\",\n      \"integrity\": \"sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==\",\n      \"dev\": true\n    },\n    \"node_modules/spdx-expression-parse\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz\",\n      \"integrity\": \"sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"spdx-exceptions\": \"^2.1.0\",\n        \"spdx-license-ids\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/spdx-license-ids\": {\n      \"version\": \"3.0.13\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz\",\n      \"integrity\": \"sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==\",\n      \"dev\": true\n    },\n    \"node_modules/split2\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/split2/-/split2-3.2.2.tgz\",\n      \"integrity\": \"sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"readable-stream\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/string_decoder\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz\",\n      \"integrity\": \"sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"safe-buffer\": \"~5.2.0\"\n      }\n    },\n    \"node_modules/string-argv\": {\n      \"version\": \"0.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz\",\n      \"integrity\": \"sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.6.19\"\n      }\n    },\n    \"node_modules/string-width\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz\",\n      \"integrity\": \"sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eastasianwidth\": \"^0.2.0\",\n        \"emoji-regex\": \"^9.2.2\",\n        \"strip-ansi\": \"^7.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/string-width/node_modules/ansi-regex\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz\",\n      \"integrity\": \"sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/ansi-regex?sponsor=1\"\n      }\n    },\n    \"node_modules/string-width/node_modules/strip-ansi\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz\",\n      \"integrity\": \"sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-regex\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/strip-ansi?sponsor=1\"\n      }\n    },\n    \"node_modules/string.prototype.matchall\": {\n      \"version\": \"4.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz\",\n      \"integrity\": \"sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"has-symbols\": \"^1.0.3\",\n        \"internal-slot\": \"^1.0.3\",\n        \"regexp.prototype.flags\": \"^1.4.3\",\n        \"side-channel\": \"^1.0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/string.prototype.padend\": {\n      \"version\": \"3.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz\",\n      \"integrity\": \"sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/string.prototype.trim\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz\",\n      \"integrity\": \"sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/string.prototype.trimend\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz\",\n      \"integrity\": \"sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/string.prototype.trimstart\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz\",\n      \"integrity\": \"sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/stringify-object\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz\",\n      \"integrity\": \"sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"get-own-enumerable-property-symbols\": \"^3.0.0\",\n        \"is-obj\": \"^1.0.1\",\n        \"is-regexp\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/stringify-object/node_modules/is-obj\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz\",\n      \"integrity\": \"sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/strip-ansi\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz\",\n      \"integrity\": \"sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-regex\": \"^5.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/strip-bom\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz\",\n      \"integrity\": \"sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/strip-comments\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz\",\n      \"integrity\": \"sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/strip-final-newline\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz\",\n      \"integrity\": \"sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/strip-indent\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz\",\n      \"integrity\": \"sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"min-indent\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/strip-json-comments\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz\",\n      \"integrity\": \"sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/sucrase\": {\n      \"version\": \"3.32.0\",\n      \"resolved\": \"https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz\",\n      \"integrity\": \"sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.2\",\n        \"commander\": \"^4.0.0\",\n        \"glob\": \"7.1.6\",\n        \"lines-and-columns\": \"^1.1.6\",\n        \"mz\": \"^2.7.0\",\n        \"pirates\": \"^4.0.1\",\n        \"ts-interface-checker\": \"^0.1.9\"\n      },\n      \"bin\": {\n        \"sucrase\": \"bin/sucrase\",\n        \"sucrase-node\": \"bin/sucrase-node\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/sucrase/node_modules/commander\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-4.1.1.tgz\",\n      \"integrity\": \"sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 6\"\n      }\n    },\n    \"node_modules/sucrase/node_modules/glob\": {\n      \"version\": \"7.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.1.6.tgz\",\n      \"integrity\": \"sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fs.realpath\": \"^1.0.0\",\n        \"inflight\": \"^1.0.4\",\n        \"inherits\": \"2\",\n        \"minimatch\": \"^3.0.4\",\n        \"once\": \"^1.3.0\",\n        \"path-is-absolute\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/supports-color\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz\",\n      \"integrity\": \"sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"has-flag\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/supports-preserve-symlinks-flag\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz\",\n      \"integrity\": \"sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/tailwindcss\": {\n      \"version\": \"3.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz\",\n      \"integrity\": \"sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"arg\": \"^5.0.2\",\n        \"chokidar\": \"^3.5.3\",\n        \"color-name\": \"^1.1.4\",\n        \"didyoumean\": \"^1.2.2\",\n        \"dlv\": \"^1.1.3\",\n        \"fast-glob\": \"^3.2.12\",\n        \"glob-parent\": \"^6.0.2\",\n        \"is-glob\": \"^4.0.3\",\n        \"jiti\": \"^1.17.2\",\n        \"lilconfig\": \"^2.0.6\",\n        \"micromatch\": \"^4.0.5\",\n        \"normalize-path\": \"^3.0.0\",\n        \"object-hash\": \"^3.0.0\",\n        \"picocolors\": \"^1.0.0\",\n        \"postcss\": \"^8.0.9\",\n        \"postcss-import\": \"^14.1.0\",\n        \"postcss-js\": \"^4.0.0\",\n        \"postcss-load-config\": \"^3.1.4\",\n        \"postcss-nested\": \"6.0.0\",\n        \"postcss-selector-parser\": \"^6.0.11\",\n        \"postcss-value-parser\": \"^4.2.0\",\n        \"quick-lru\": \"^5.1.1\",\n        \"resolve\": \"^1.22.1\",\n        \"sucrase\": \"^3.29.0\"\n      },\n      \"bin\": {\n        \"tailwind\": \"lib/cli.js\",\n        \"tailwindcss\": \"lib/cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=12.13.0\"\n      },\n      \"peerDependencies\": {\n        \"postcss\": \"^8.0.9\"\n      }\n    },\n    \"node_modules/tailwindcss/node_modules/quick-lru\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz\",\n      \"integrity\": \"sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/temp-dir\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz\",\n      \"integrity\": \"sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/tempy\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz\",\n      \"integrity\": \"sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-stream\": \"^2.0.0\",\n        \"temp-dir\": \"^2.0.0\",\n        \"type-fest\": \"^0.16.0\",\n        \"unique-string\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/tempy/node_modules/type-fest\": {\n      \"version\": \"0.16.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz\",\n      \"integrity\": \"sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/terser\": {\n      \"version\": \"5.17.1\",\n      \"resolved\": \"https://registry.npmjs.org/terser/-/terser-5.17.1.tgz\",\n      \"integrity\": \"sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@jridgewell/source-map\": \"^0.3.2\",\n        \"acorn\": \"^8.5.0\",\n        \"commander\": \"^2.20.0\",\n        \"source-map-support\": \"~0.5.20\"\n      },\n      \"bin\": {\n        \"terser\": \"bin/terser\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/terser/node_modules/commander\": {\n      \"version\": \"2.20.3\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.20.3.tgz\",\n      \"integrity\": \"sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==\",\n      \"dev\": true\n    },\n    \"node_modules/text-extensions\": {\n      \"version\": \"1.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz\",\n      \"integrity\": \"sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10\"\n      }\n    },\n    \"node_modules/text-segmentation\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz\",\n      \"integrity\": \"sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==\",\n      \"dependencies\": {\n        \"utrie\": \"^1.0.2\"\n      }\n    },\n    \"node_modules/text-table\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz\",\n      \"integrity\": \"sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==\",\n      \"dev\": true\n    },\n    \"node_modules/thenify\": {\n      \"version\": \"3.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz\",\n      \"integrity\": \"sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"any-promise\": \"^1.0.0\"\n      }\n    },\n    \"node_modules/thenify-all\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz\",\n      \"integrity\": \"sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"thenify\": \">= 3.1.0 < 4\"\n      },\n      \"engines\": {\n        \"node\": \">=0.8\"\n      }\n    },\n    \"node_modules/through\": {\n      \"version\": \"2.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/through/-/through-2.3.8.tgz\",\n      \"integrity\": \"sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==\",\n      \"dev\": true\n    },\n    \"node_modules/through2\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/through2/-/through2-4.0.2.tgz\",\n      \"integrity\": \"sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"readable-stream\": \"3\"\n      }\n    },\n    \"node_modules/to-fast-properties\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz\",\n      \"integrity\": \"sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/to-regex-range\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz\",\n      \"integrity\": \"sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-number\": \"^7.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8.0\"\n      }\n    },\n    \"node_modules/tr46\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz\",\n      \"integrity\": \"sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"punycode\": \"^2.1.0\"\n      }\n    },\n    \"node_modules/treemate\": {\n      \"version\": \"0.3.11\",\n      \"resolved\": \"https://registry.npmjs.org/treemate/-/treemate-0.3.11.tgz\",\n      \"integrity\": \"sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==\"\n    },\n    \"node_modules/trim-newlines\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz\",\n      \"integrity\": \"sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/ts-interface-checker\": {\n      \"version\": \"0.1.13\",\n      \"resolved\": \"https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz\",\n      \"integrity\": \"sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==\",\n      \"dev\": true\n    },\n    \"node_modules/ts-node\": {\n      \"version\": \"10.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz\",\n      \"integrity\": \"sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@cspotcode/source-map-support\": \"^0.8.0\",\n        \"@tsconfig/node10\": \"^1.0.7\",\n        \"@tsconfig/node12\": \"^1.0.7\",\n        \"@tsconfig/node14\": \"^1.0.0\",\n        \"@tsconfig/node16\": \"^1.0.2\",\n        \"acorn\": \"^8.4.1\",\n        \"acorn-walk\": \"^8.1.1\",\n        \"arg\": \"^4.1.0\",\n        \"create-require\": \"^1.1.0\",\n        \"diff\": \"^4.0.1\",\n        \"make-error\": \"^1.1.1\",\n        \"v8-compile-cache-lib\": \"^3.0.1\",\n        \"yn\": \"3.1.1\"\n      },\n      \"bin\": {\n        \"ts-node\": \"dist/bin.js\",\n        \"ts-node-cwd\": \"dist/bin-cwd.js\",\n        \"ts-node-esm\": \"dist/bin-esm.js\",\n        \"ts-node-script\": \"dist/bin-script.js\",\n        \"ts-node-transpile-only\": \"dist/bin-transpile.js\",\n        \"ts-script\": \"dist/bin-script-deprecated.js\"\n      },\n      \"peerDependencies\": {\n        \"@swc/core\": \">=1.2.50\",\n        \"@swc/wasm\": \">=1.2.50\",\n        \"@types/node\": \"*\",\n        \"typescript\": \">=2.7\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@swc/core\": {\n          \"optional\": true\n        },\n        \"@swc/wasm\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/ts-node/node_modules/arg\": {\n      \"version\": \"4.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/arg/-/arg-4.1.3.tgz\",\n      \"integrity\": \"sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==\",\n      \"dev\": true\n    },\n    \"node_modules/tsconfig-paths\": {\n      \"version\": \"3.14.2\",\n      \"resolved\": \"https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz\",\n      \"integrity\": \"sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/json5\": \"^0.0.29\",\n        \"json5\": \"^1.0.2\",\n        \"minimist\": \"^1.2.6\",\n        \"strip-bom\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/tslib\": {\n      \"version\": \"2.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz\",\n      \"integrity\": \"sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==\",\n      \"dev\": true\n    },\n    \"node_modules/tsutils\": {\n      \"version\": \"3.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz\",\n      \"integrity\": \"sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"tslib\": \"^1.8.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"peerDependencies\": {\n        \"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\"\n      }\n    },\n    \"node_modules/tsutils/node_modules/tslib\": {\n      \"version\": \"1.14.1\",\n      \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz\",\n      \"integrity\": \"sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==\",\n      \"dev\": true\n    },\n    \"node_modules/type-check\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz\",\n      \"integrity\": \"sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"prelude-ls\": \"^1.2.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.8.0\"\n      }\n    },\n    \"node_modules/type-fest\": {\n      \"version\": \"0.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz\",\n      \"integrity\": \"sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/typed-array-length\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz\",\n      \"integrity\": \"sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"is-typed-array\": \"^1.1.9\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/typescript\": {\n      \"version\": \"4.9.5\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz\",\n      \"integrity\": \"sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==\",\n      \"devOptional\": true,\n      \"bin\": {\n        \"tsc\": \"bin/tsc\",\n        \"tsserver\": \"bin/tsserver\"\n      },\n      \"engines\": {\n        \"node\": \">=4.2.0\"\n      }\n    },\n    \"node_modules/uc.micro\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz\",\n      \"integrity\": \"sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==\"\n    },\n    \"node_modules/unbox-primitive\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz\",\n      \"integrity\": \"sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-bigints\": \"^1.0.2\",\n        \"has-symbols\": \"^1.0.3\",\n        \"which-boxed-primitive\": \"^1.0.2\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/unicode-canonical-property-names-ecmascript\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz\",\n      \"integrity\": \"sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/unicode-match-property-ecmascript\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz\",\n      \"integrity\": \"sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"unicode-canonical-property-names-ecmascript\": \"^2.0.0\",\n        \"unicode-property-aliases-ecmascript\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/unicode-match-property-value-ecmascript\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz\",\n      \"integrity\": \"sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/unicode-property-aliases-ecmascript\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz\",\n      \"integrity\": \"sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\"\n      }\n    },\n    \"node_modules/unique-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"crypto-random-string\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/unist-util-stringify-position\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz\",\n      \"integrity\": \"sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/unist\": \"^2.0.2\"\n      },\n      \"funding\": {\n        \"type\": \"opencollective\",\n        \"url\": \"https://opencollective.com/unified\"\n      }\n    },\n    \"node_modules/universalify\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz\",\n      \"integrity\": \"sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      }\n    },\n    \"node_modules/upath\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/upath/-/upath-1.2.0.tgz\",\n      \"integrity\": \"sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4\",\n        \"yarn\": \"*\"\n      }\n    },\n    \"node_modules/update-browserslist-db\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz\",\n      \"integrity\": \"sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==\",\n      \"dev\": true,\n      \"funding\": [\n        {\n          \"type\": \"opencollective\",\n          \"url\": \"https://opencollective.com/browserslist\"\n        },\n        {\n          \"type\": \"tidelift\",\n          \"url\": \"https://tidelift.com/funding/github/npm/browserslist\"\n        },\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/ai\"\n        }\n      ],\n      \"dependencies\": {\n        \"escalade\": \"^3.1.1\",\n        \"picocolors\": \"^1.0.0\"\n      },\n      \"bin\": {\n        \"update-browserslist-db\": \"cli.js\"\n      },\n      \"peerDependencies\": {\n        \"browserslist\": \">= 4.21.0\"\n      }\n    },\n    \"node_modules/uri-js\": {\n      \"version\": \"4.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz\",\n      \"integrity\": \"sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"punycode\": \"^2.1.0\"\n      }\n    },\n    \"node_modules/util-deprecate\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz\",\n      \"integrity\": \"sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==\",\n      \"dev\": true\n    },\n    \"node_modules/utrie\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz\",\n      \"integrity\": \"sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==\",\n      \"dependencies\": {\n        \"base64-arraybuffer\": \"^1.0.2\"\n      }\n    },\n    \"node_modules/v8-compile-cache-lib\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz\",\n      \"integrity\": \"sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==\",\n      \"dev\": true\n    },\n    \"node_modules/validate-npm-package-license\": {\n      \"version\": \"3.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz\",\n      \"integrity\": \"sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"spdx-correct\": \"^3.0.0\",\n        \"spdx-expression-parse\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/vdirs\": {\n      \"version\": \"0.1.8\",\n      \"resolved\": \"https://registry.npmjs.org/vdirs/-/vdirs-0.1.8.tgz\",\n      \"integrity\": \"sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==\",\n      \"dependencies\": {\n        \"evtd\": \"^0.2.2\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.11\"\n      }\n    },\n    \"node_modules/vite\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/vite/-/vite-4.3.1.tgz\",\n      \"integrity\": \"sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esbuild\": \"^0.17.5\",\n        \"postcss\": \"^8.4.21\",\n        \"rollup\": \"^3.20.2\"\n      },\n      \"bin\": {\n        \"vite\": \"bin/vite.js\"\n      },\n      \"engines\": {\n        \"node\": \"^14.18.0 || >=16.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.2\"\n      },\n      \"peerDependencies\": {\n        \"@types/node\": \">= 14\",\n        \"less\": \"*\",\n        \"sass\": \"*\",\n        \"stylus\": \"*\",\n        \"sugarss\": \"*\",\n        \"terser\": \"^5.4.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@types/node\": {\n          \"optional\": true\n        },\n        \"less\": {\n          \"optional\": true\n        },\n        \"sass\": {\n          \"optional\": true\n        },\n        \"stylus\": {\n          \"optional\": true\n        },\n        \"sugarss\": {\n          \"optional\": true\n        },\n        \"terser\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/vite-plugin-pwa\": {\n      \"version\": \"0.14.7\",\n      \"resolved\": \"https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.14.7.tgz\",\n      \"integrity\": \"sha512-dNJaf0fYOWncmjxv9HiSa2xrSjipjff7IkYE5oIUJ2x5HKu3cXgA8LRgzOwTc5MhwyFYRSU0xyN0Phbx3NsQYw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@rollup/plugin-replace\": \"^5.0.1\",\n        \"debug\": \"^4.3.4\",\n        \"fast-glob\": \"^3.2.12\",\n        \"pretty-bytes\": \"^6.0.0\",\n        \"rollup\": \"^3.7.2\",\n        \"workbox-build\": \"^6.5.4\",\n        \"workbox-window\": \"^6.5.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/antfu\"\n      },\n      \"peerDependencies\": {\n        \"vite\": \"^3.1.0 || ^4.0.0\",\n        \"workbox-build\": \"^6.5.4\",\n        \"workbox-window\": \"^6.5.4\"\n      }\n    },\n    \"node_modules/vooks\": {\n      \"version\": \"0.2.12\",\n      \"resolved\": \"https://registry.npmjs.org/vooks/-/vooks-0.2.12.tgz\",\n      \"integrity\": \"sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==\",\n      \"dependencies\": {\n        \"evtd\": \"^0.2.2\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/vue\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/vue/-/vue-3.2.47.tgz\",\n      \"integrity\": \"sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==\",\n      \"dependencies\": {\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/compiler-sfc\": \"3.2.47\",\n        \"@vue/runtime-dom\": \"3.2.47\",\n        \"@vue/server-renderer\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"node_modules/vue-eslint-parser\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz\",\n      \"integrity\": \"sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.3.4\",\n        \"eslint-scope\": \"^7.1.1\",\n        \"eslint-visitor-keys\": \"^3.3.0\",\n        \"espree\": \"^9.3.1\",\n        \"esquery\": \"^1.4.0\",\n        \"lodash\": \"^4.17.21\",\n        \"semver\": \"^7.3.6\"\n      },\n      \"engines\": {\n        \"node\": \"^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/mysticatea\"\n      },\n      \"peerDependencies\": {\n        \"eslint\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/vue-eslint-parser/node_modules/eslint-scope\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz\",\n      \"integrity\": \"sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"esrecurse\": \"^4.3.0\",\n        \"estraverse\": \"^5.2.0\"\n      },\n      \"engines\": {\n        \"node\": \"^12.22.0 || ^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://opencollective.com/eslint\"\n      }\n    },\n    \"node_modules/vue-eslint-parser/node_modules/estraverse\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n      \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=4.0\"\n      }\n    },\n    \"node_modules/vue-i18n\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz\",\n      \"integrity\": \"sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==\",\n      \"dependencies\": {\n        \"@intlify/core-base\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\",\n        \"@intlify/vue-devtools\": \"9.2.2\",\n        \"@vue/devtools-api\": \"^6.2.1\"\n      },\n      \"engines\": {\n        \"node\": \">= 14\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.0\"\n      }\n    },\n    \"node_modules/vue-router\": {\n      \"version\": \"4.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz\",\n      \"integrity\": \"sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==\",\n      \"dependencies\": {\n        \"@vue/devtools-api\": \"^6.4.5\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/posva\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.2.0\"\n      }\n    },\n    \"node_modules/vue-template-compiler\": {\n      \"version\": \"2.7.14\",\n      \"resolved\": \"https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz\",\n      \"integrity\": \"sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"de-indent\": \"^1.0.2\",\n        \"he\": \"^1.2.0\"\n      }\n    },\n    \"node_modules/vue-tsc\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.4.4.tgz\",\n      \"integrity\": \"sha512-2XsCjF2mLo6gwOVcOpngwJkP8GzYQjNh20A+Pr2FGdsWzr9jjXJ0k08/DfcslfncsuCrTrnWtb4KEL3gcDtlNA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@volar/vue-language-core\": \"1.4.4\",\n        \"@volar/vue-typescript\": \"1.4.4\",\n        \"semver\": \"^7.3.8\"\n      },\n      \"bin\": {\n        \"vue-tsc\": \"bin/vue-tsc.js\"\n      },\n      \"peerDependencies\": {\n        \"typescript\": \"*\"\n      }\n    },\n    \"node_modules/vueuc\": {\n      \"version\": \"0.4.51\",\n      \"resolved\": \"https://registry.npmjs.org/vueuc/-/vueuc-0.4.51.tgz\",\n      \"integrity\": \"sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==\",\n      \"dependencies\": {\n        \"@css-render/vue3-ssr\": \"^0.15.10\",\n        \"@juggle/resize-observer\": \"^3.3.1\",\n        \"css-render\": \"^0.15.10\",\n        \"evtd\": \"^0.2.4\",\n        \"seemly\": \"^0.3.6\",\n        \"vdirs\": \"^0.1.4\",\n        \"vooks\": \"^0.2.4\"\n      },\n      \"peerDependencies\": {\n        \"vue\": \"^3.0.11\"\n      }\n    },\n    \"node_modules/webidl-conversions\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz\",\n      \"integrity\": \"sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==\",\n      \"dev\": true\n    },\n    \"node_modules/whatwg-url\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz\",\n      \"integrity\": \"sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lodash.sortby\": \"^4.7.0\",\n        \"tr46\": \"^1.0.1\",\n        \"webidl-conversions\": \"^4.0.2\"\n      }\n    },\n    \"node_modules/which\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-2.0.2.tgz\",\n      \"integrity\": \"sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"isexe\": \"^2.0.0\"\n      },\n      \"bin\": {\n        \"node-which\": \"bin/node-which\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/which-boxed-primitive\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz\",\n      \"integrity\": \"sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-bigint\": \"^1.0.1\",\n        \"is-boolean-object\": \"^1.1.0\",\n        \"is-number-object\": \"^1.0.4\",\n        \"is-string\": \"^1.0.5\",\n        \"is-symbol\": \"^1.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/which-typed-array\": {\n      \"version\": \"1.1.9\",\n      \"resolved\": \"https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz\",\n      \"integrity\": \"sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has-tostringtag\": \"^1.0.0\",\n        \"is-typed-array\": \"^1.1.10\"\n      },\n      \"engines\": {\n        \"node\": \">= 0.4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ljharb\"\n      }\n    },\n    \"node_modules/word-wrap\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz\",\n      \"integrity\": \"sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/workbox-background-sync\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz\",\n      \"integrity\": \"sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"idb\": \"^7.0.1\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-broadcast-update\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz\",\n      \"integrity\": \"sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-build\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz\",\n      \"integrity\": \"sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@apideck/better-ajv-errors\": \"^0.3.1\",\n        \"@babel/core\": \"^7.11.1\",\n        \"@babel/preset-env\": \"^7.11.0\",\n        \"@babel/runtime\": \"^7.11.2\",\n        \"@rollup/plugin-babel\": \"^5.2.0\",\n        \"@rollup/plugin-node-resolve\": \"^11.2.1\",\n        \"@rollup/plugin-replace\": \"^2.4.1\",\n        \"@surma/rollup-plugin-off-main-thread\": \"^2.2.3\",\n        \"ajv\": \"^8.6.0\",\n        \"common-tags\": \"^1.8.0\",\n        \"fast-json-stable-stringify\": \"^2.1.0\",\n        \"fs-extra\": \"^9.0.1\",\n        \"glob\": \"^7.1.6\",\n        \"lodash\": \"^4.17.20\",\n        \"pretty-bytes\": \"^5.3.0\",\n        \"rollup\": \"^2.43.1\",\n        \"rollup-plugin-terser\": \"^7.0.0\",\n        \"source-map\": \"^0.8.0-beta.0\",\n        \"stringify-object\": \"^3.3.0\",\n        \"strip-comments\": \"^2.0.1\",\n        \"tempy\": \"^0.6.0\",\n        \"upath\": \"^1.2.0\",\n        \"workbox-background-sync\": \"6.5.4\",\n        \"workbox-broadcast-update\": \"6.5.4\",\n        \"workbox-cacheable-response\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-expiration\": \"6.5.4\",\n        \"workbox-google-analytics\": \"6.5.4\",\n        \"workbox-navigation-preload\": \"6.5.4\",\n        \"workbox-precaching\": \"6.5.4\",\n        \"workbox-range-requests\": \"6.5.4\",\n        \"workbox-recipes\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\",\n        \"workbox-streams\": \"6.5.4\",\n        \"workbox-sw\": \"6.5.4\",\n        \"workbox-window\": \"6.5.4\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/@rollup/plugin-babel\": {\n      \"version\": \"5.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz\",\n      \"integrity\": \"sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/helper-module-imports\": \"^7.10.4\",\n        \"@rollup/pluginutils\": \"^3.1.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      },\n      \"peerDependencies\": {\n        \"@babel/core\": \"^7.0.0\",\n        \"@types/babel__core\": \"^7.1.9\",\n        \"rollup\": \"^1.20.0||^2.0.0\"\n      },\n      \"peerDependenciesMeta\": {\n        \"@types/babel__core\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/workbox-build/node_modules/@rollup/plugin-node-resolve\": {\n      \"version\": \"11.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz\",\n      \"integrity\": \"sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@rollup/pluginutils\": \"^3.1.0\",\n        \"@types/resolve\": \"1.17.1\",\n        \"builtin-modules\": \"^3.1.0\",\n        \"deepmerge\": \"^4.2.2\",\n        \"is-module\": \"^1.0.0\",\n        \"resolve\": \"^1.19.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^1.20.0||^2.0.0\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/@rollup/plugin-replace\": {\n      \"version\": \"2.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz\",\n      \"integrity\": \"sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@rollup/pluginutils\": \"^3.1.0\",\n        \"magic-string\": \"^0.25.7\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^1.20.0 || ^2.0.0\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/@rollup/pluginutils\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz\",\n      \"integrity\": \"sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/estree\": \"0.0.39\",\n        \"estree-walker\": \"^1.0.1\",\n        \"picomatch\": \"^2.2.2\"\n      },\n      \"engines\": {\n        \"node\": \">= 8.0.0\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^1.20.0||^2.0.0\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/@types/estree\": {\n      \"version\": \"0.0.39\",\n      \"resolved\": \"https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz\",\n      \"integrity\": \"sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==\",\n      \"dev\": true\n    },\n    \"node_modules/workbox-build/node_modules/estree-walker\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz\",\n      \"integrity\": \"sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==\",\n      \"dev\": true\n    },\n    \"node_modules/workbox-build/node_modules/fs-extra\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz\",\n      \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"at-least-node\": \"^1.0.0\",\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/glob\": {\n      \"version\": \"7.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.2.3.tgz\",\n      \"integrity\": \"sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"fs.realpath\": \"^1.0.0\",\n        \"inflight\": \"^1.0.4\",\n        \"inherits\": \"2\",\n        \"minimatch\": \"^3.1.1\",\n        \"once\": \"^1.3.0\",\n        \"path-is-absolute\": \"^1.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"*\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/isaacs\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/magic-string\": {\n      \"version\": \"0.25.9\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n      \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"sourcemap-codec\": \"^1.4.8\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/pretty-bytes\": {\n      \"version\": \"5.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz\",\n      \"integrity\": \"sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/rollup\": {\n      \"version\": \"2.79.1\",\n      \"resolved\": \"https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz\",\n      \"integrity\": \"sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rollup\": \"dist/bin/rollup\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"~2.3.2\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/rollup-plugin-terser\": {\n      \"version\": \"7.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz\",\n      \"integrity\": \"sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==\",\n      \"deprecated\": \"This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@babel/code-frame\": \"^7.10.4\",\n        \"jest-worker\": \"^26.2.1\",\n        \"serialize-javascript\": \"^4.0.0\",\n        \"terser\": \"^5.0.0\"\n      },\n      \"peerDependencies\": {\n        \"rollup\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/workbox-build/node_modules/source-map\": {\n      \"version\": \"0.8.0-beta.0\",\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz\",\n      \"integrity\": \"sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"whatwg-url\": \"^7.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/workbox-cacheable-response\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz\",\n      \"integrity\": \"sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-core\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz\",\n      \"integrity\": \"sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==\",\n      \"dev\": true\n    },\n    \"node_modules/workbox-expiration\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz\",\n      \"integrity\": \"sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"idb\": \"^7.0.1\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-google-analytics\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz\",\n      \"integrity\": \"sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-background-sync\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-navigation-preload\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz\",\n      \"integrity\": \"sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-precaching\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz\",\n      \"integrity\": \"sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-range-requests\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz\",\n      \"integrity\": \"sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-recipes\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz\",\n      \"integrity\": \"sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-cacheable-response\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-expiration\": \"6.5.4\",\n        \"workbox-precaching\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-routing\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz\",\n      \"integrity\": \"sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-strategies\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz\",\n      \"integrity\": \"sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-streams\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz\",\n      \"integrity\": \"sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\"\n      }\n    },\n    \"node_modules/workbox-sw\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz\",\n      \"integrity\": \"sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==\",\n      \"dev\": true\n    },\n    \"node_modules/workbox-window\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz\",\n      \"integrity\": \"sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/trusted-types\": \"^2.0.2\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"node_modules/wrap-ansi\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz\",\n      \"integrity\": \"sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": \"^4.0.0\",\n        \"string-width\": \"^4.1.0\",\n        \"strip-ansi\": \"^6.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/chalk/wrap-ansi?sponsor=1\"\n      }\n    },\n    \"node_modules/wrap-ansi/node_modules/emoji-regex\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n      \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n      \"dev\": true\n    },\n    \"node_modules/wrap-ansi/node_modules/is-fullwidth-code-point\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n      \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/wrap-ansi/node_modules/string-width\": {\n      \"version\": \"4.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n      \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"emoji-regex\": \"^8.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\",\n        \"strip-ansi\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/wrappy\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\",\n      \"integrity\": \"sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==\",\n      \"dev\": true\n    },\n    \"node_modules/xml-name-validator\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz\",\n      \"integrity\": \"sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/y18n\": {\n      \"version\": \"5.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz\",\n      \"integrity\": \"sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/yallist\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz\",\n      \"integrity\": \"sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==\",\n      \"dev\": true\n    },\n    \"node_modules/yaml\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz\",\n      \"integrity\": \"sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 14\"\n      }\n    },\n    \"node_modules/yaml-eslint-parser\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.0.tgz\",\n      \"integrity\": \"sha512-OmuvQd5lyIJWfFALc39K5fGqp0aWNc+EtyhVgcQIPZaUKMnTb7An3RMp+QJizJ/x0F4kpgTNe6BL/ctdvoIwIg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"eslint-visitor-keys\": \"^3.0.0\",\n        \"lodash\": \"^4.17.21\",\n        \"yaml\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \"^14.17.0 || >=16.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/ota-meshi\"\n      }\n    },\n    \"node_modules/yargs\": {\n      \"version\": \"17.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz\",\n      \"integrity\": \"sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"cliui\": \"^8.0.1\",\n        \"escalade\": \"^3.1.1\",\n        \"get-caller-file\": \"^2.0.5\",\n        \"require-directory\": \"^2.1.1\",\n        \"string-width\": \"^4.2.3\",\n        \"y18n\": \"^5.0.5\",\n        \"yargs-parser\": \"^21.1.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/yargs-parser\": {\n      \"version\": \"20.2.9\",\n      \"resolved\": \"https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz\",\n      \"integrity\": \"sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/yargs/node_modules/emoji-regex\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n      \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n      \"dev\": true\n    },\n    \"node_modules/yargs/node_modules/is-fullwidth-code-point\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n      \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/yargs/node_modules/string-width\": {\n      \"version\": \"4.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n      \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"emoji-regex\": \"^8.0.0\",\n        \"is-fullwidth-code-point\": \"^3.0.0\",\n        \"strip-ansi\": \"^6.0.1\"\n      },\n      \"engines\": {\n        \"node\": \">=8\"\n      }\n    },\n    \"node_modules/yargs/node_modules/yargs-parser\": {\n      \"version\": \"21.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz\",\n      \"integrity\": \"sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/yn\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/yn/-/yn-3.1.1.tgz\",\n      \"integrity\": \"sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/yocto-queue\": {\n      \"version\": \"0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz\",\n      \"integrity\": \"sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=10\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\n      }\n    }\n  },\n  \"dependencies\": {\n    \"@ampproject/remapping\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz\",\n      \"integrity\": \"sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.0\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      }\n    },\n    \"@antfu/eslint-config\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-0.35.3.tgz\",\n      \"integrity\": \"sha512-wd0ry/TNqaZmniqkKtZKoCvpl55x9YbHgL5Ug3H9rVuUSqaNi9G9AjYlynQqn4/M1EhYYWO597Lu7f/fC+csrg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@antfu/eslint-config-vue\": \"0.35.3\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.53.0\",\n        \"@typescript-eslint/parser\": \"^5.53.0\",\n        \"eslint-plugin-eslint-comments\": \"^3.2.0\",\n        \"eslint-plugin-html\": \"^7.1.0\",\n        \"eslint-plugin-import\": \"^2.27.5\",\n        \"eslint-plugin-jsonc\": \"^2.6.0\",\n        \"eslint-plugin-n\": \"^15.6.1\",\n        \"eslint-plugin-promise\": \"^6.1.1\",\n        \"eslint-plugin-unicorn\": \"^45.0.2\",\n        \"eslint-plugin-vue\": \"^9.9.0\",\n        \"eslint-plugin-yml\": \"^1.5.0\",\n        \"jsonc-eslint-parser\": \"^2.1.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      }\n    },\n    \"@antfu/eslint-config-basic\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-basic/-/eslint-config-basic-0.35.3.tgz\",\n      \"integrity\": \"sha512-NbWJKNgd3Ky3/ok2Z88cXNme/6I9otkiaB+FYLFgQE81sfMAhKpLKXtTSwzdcKMzhKDqUchAijt0BxjE/mcTJg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-plugin-antfu\": \"0.35.3\",\n        \"eslint-plugin-eslint-comments\": \"^3.2.0\",\n        \"eslint-plugin-html\": \"^7.1.0\",\n        \"eslint-plugin-import\": \"^2.27.5\",\n        \"eslint-plugin-jsonc\": \"^2.6.0\",\n        \"eslint-plugin-markdown\": \"^3.0.0\",\n        \"eslint-plugin-n\": \"^15.6.1\",\n        \"eslint-plugin-no-only-tests\": \"^3.1.0\",\n        \"eslint-plugin-promise\": \"^6.1.1\",\n        \"eslint-plugin-unicorn\": \"^45.0.2\",\n        \"eslint-plugin-unused-imports\": \"^2.0.0\",\n        \"eslint-plugin-yml\": \"^1.5.0\",\n        \"jsonc-eslint-parser\": \"^2.1.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      }\n    },\n    \"@antfu/eslint-config-ts\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-ts/-/eslint-config-ts-0.35.3.tgz\",\n      \"integrity\": \"sha512-FS5hir2ghXYlJWAiB2bpT9oAr0kpSNmYbaJWWkztocJG95AORl4tWzxMTkLT+TxaOmhuwJszcrMTHy5RgHL8/w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@antfu/eslint-config-basic\": \"0.35.3\",\n        \"@typescript-eslint/eslint-plugin\": \"^5.53.0\",\n        \"@typescript-eslint/parser\": \"^5.53.0\",\n        \"eslint-plugin-jest\": \"^27.2.1\"\n      }\n    },\n    \"@antfu/eslint-config-vue\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/@antfu/eslint-config-vue/-/eslint-config-vue-0.35.3.tgz\",\n      \"integrity\": \"sha512-BA3vGLyuzqtEUb9gfgE7YzBT+a4oUnQuUPasIUfN/BVXaEhRVYlMmUgxN4ekQLuzOgUjUH13lqplXtkLJ62t9g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@antfu/eslint-config-basic\": \"0.35.3\",\n        \"@antfu/eslint-config-ts\": \"0.35.3\",\n        \"eslint-plugin-vue\": \"^9.9.0\",\n        \"local-pkg\": \"^0.4.3\"\n      }\n    },\n    \"@apideck/better-ajv-errors\": {\n      \"version\": \"0.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz\",\n      \"integrity\": \"sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"json-schema\": \"^0.4.0\",\n        \"jsonpointer\": \"^5.0.0\",\n        \"leven\": \"^3.1.0\"\n      }\n    },\n    \"@babel/code-frame\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz\",\n      \"integrity\": \"sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/highlight\": \"^7.18.6\"\n      }\n    },\n    \"@babel/compat-data\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz\",\n      \"integrity\": \"sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==\",\n      \"dev\": true\n    },\n    \"@babel/core\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz\",\n      \"integrity\": \"sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@ampproject/remapping\": \"^2.2.0\",\n        \"@babel/code-frame\": \"^7.21.4\",\n        \"@babel/generator\": \"^7.21.4\",\n        \"@babel/helper-compilation-targets\": \"^7.21.4\",\n        \"@babel/helper-module-transforms\": \"^7.21.2\",\n        \"@babel/helpers\": \"^7.21.0\",\n        \"@babel/parser\": \"^7.21.4\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.4\",\n        \"@babel/types\": \"^7.21.4\",\n        \"convert-source-map\": \"^1.7.0\",\n        \"debug\": \"^4.1.0\",\n        \"gensync\": \"^1.0.0-beta.2\",\n        \"json5\": \"^2.2.2\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"dependencies\": {\n        \"json5\": {\n          \"version\": \"2.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz\",\n          \"integrity\": \"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==\",\n          \"dev\": true\n        },\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/generator\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz\",\n      \"integrity\": \"sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.21.4\",\n        \"@jridgewell/gen-mapping\": \"^0.3.2\",\n        \"@jridgewell/trace-mapping\": \"^0.3.17\",\n        \"jsesc\": \"^2.5.1\"\n      },\n      \"dependencies\": {\n        \"jsesc\": {\n          \"version\": \"2.5.2\",\n          \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz\",\n          \"integrity\": \"sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/helper-annotate-as-pure\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz\",\n      \"integrity\": \"sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-builder-binary-assignment-operator-visitor\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz\",\n      \"integrity\": \"sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-explode-assignable-expression\": \"^7.18.6\",\n        \"@babel/types\": \"^7.18.9\"\n      }\n    },\n    \"@babel/helper-compilation-targets\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz\",\n      \"integrity\": \"sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/compat-data\": \"^7.21.4\",\n        \"@babel/helper-validator-option\": \"^7.21.0\",\n        \"browserslist\": \"^4.21.3\",\n        \"lru-cache\": \"^5.1.1\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"dependencies\": {\n        \"lru-cache\": {\n          \"version\": \"5.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz\",\n          \"integrity\": \"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==\",\n          \"dev\": true,\n          \"requires\": {\n            \"yallist\": \"^3.0.2\"\n          }\n        },\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        },\n        \"yallist\": {\n          \"version\": \"3.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz\",\n          \"integrity\": \"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/helper-create-class-features-plugin\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz\",\n      \"integrity\": \"sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-member-expression-to-functions\": \"^7.21.0\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/helper-replace-supers\": \"^7.20.7\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-create-regexp-features-plugin\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz\",\n      \"integrity\": \"sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"regexpu-core\": \"^5.3.1\"\n      }\n    },\n    \"@babel/helper-define-polyfill-provider\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz\",\n      \"integrity\": \"sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-compilation-targets\": \"^7.17.7\",\n        \"@babel/helper-plugin-utils\": \"^7.16.7\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.debounce\": \"^4.0.8\",\n        \"resolve\": \"^1.14.2\",\n        \"semver\": \"^6.1.2\"\n      },\n      \"dependencies\": {\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/helper-environment-visitor\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz\",\n      \"integrity\": \"sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==\",\n      \"dev\": true\n    },\n    \"@babel/helper-explode-assignable-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-function-name\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz\",\n      \"integrity\": \"sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/types\": \"^7.21.0\"\n      }\n    },\n    \"@babel/helper-hoist-variables\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz\",\n      \"integrity\": \"sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-member-expression-to-functions\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz\",\n      \"integrity\": \"sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.21.0\"\n      }\n    },\n    \"@babel/helper-module-imports\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz\",\n      \"integrity\": \"sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.21.4\"\n      }\n    },\n    \"@babel/helper-module-transforms\": {\n      \"version\": \"7.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz\",\n      \"integrity\": \"sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-module-imports\": \"^7.18.6\",\n        \"@babel/helper-simple-access\": \"^7.20.2\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.2\",\n        \"@babel/types\": \"^7.21.2\"\n      }\n    },\n    \"@babel/helper-optimise-call-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-plugin-utils\": {\n      \"version\": \"7.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz\",\n      \"integrity\": \"sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==\",\n      \"dev\": true\n    },\n    \"@babel/helper-remap-async-to-generator\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz\",\n      \"integrity\": \"sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-wrap-function\": \"^7.18.9\",\n        \"@babel/types\": \"^7.18.9\"\n      }\n    },\n    \"@babel/helper-replace-supers\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz\",\n      \"integrity\": \"sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-member-expression-to-functions\": \"^7.20.7\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.20.7\",\n        \"@babel/types\": \"^7.20.7\"\n      }\n    },\n    \"@babel/helper-simple-access\": {\n      \"version\": \"7.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz\",\n      \"integrity\": \"sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.20.2\"\n      }\n    },\n    \"@babel/helper-skip-transparent-expression-wrappers\": {\n      \"version\": \"7.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz\",\n      \"integrity\": \"sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.20.0\"\n      }\n    },\n    \"@babel/helper-split-export-declaration\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz\",\n      \"integrity\": \"sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/types\": \"^7.18.6\"\n      }\n    },\n    \"@babel/helper-string-parser\": {\n      \"version\": \"7.19.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz\",\n      \"integrity\": \"sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==\",\n      \"dev\": true\n    },\n    \"@babel/helper-validator-identifier\": {\n      \"version\": \"7.19.1\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz\",\n      \"integrity\": \"sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==\",\n      \"dev\": true\n    },\n    \"@babel/helper-validator-option\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz\",\n      \"integrity\": \"sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==\",\n      \"dev\": true\n    },\n    \"@babel/helper-wrap-function\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz\",\n      \"integrity\": \"sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-function-name\": \"^7.19.0\",\n        \"@babel/template\": \"^7.18.10\",\n        \"@babel/traverse\": \"^7.20.5\",\n        \"@babel/types\": \"^7.20.5\"\n      }\n    },\n    \"@babel/helpers\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz\",\n      \"integrity\": \"sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/template\": \"^7.20.7\",\n        \"@babel/traverse\": \"^7.21.0\",\n        \"@babel/types\": \"^7.21.0\"\n      }\n    },\n    \"@babel/highlight\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz\",\n      \"integrity\": \"sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-validator-identifier\": \"^7.18.6\",\n        \"chalk\": \"^2.0.0\",\n        \"js-tokens\": \"^4.0.0\"\n      },\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"3.2.1\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz\",\n          \"integrity\": \"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"color-convert\": \"^1.9.0\"\n          }\n        },\n        \"chalk\": {\n          \"version\": \"2.4.2\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz\",\n          \"integrity\": \"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-styles\": \"^3.2.1\",\n            \"escape-string-regexp\": \"^1.0.5\",\n            \"supports-color\": \"^5.3.0\"\n          }\n        },\n        \"color-convert\": {\n          \"version\": \"1.9.3\",\n          \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz\",\n          \"integrity\": \"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"color-name\": \"1.1.3\"\n          }\n        },\n        \"color-name\": {\n          \"version\": \"1.1.3\",\n          \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz\",\n          \"integrity\": \"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==\",\n          \"dev\": true\n        },\n        \"escape-string-regexp\": {\n          \"version\": \"1.0.5\",\n          \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n          \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n          \"dev\": true\n        },\n        \"has-flag\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz\",\n          \"integrity\": \"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"5.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz\",\n          \"integrity\": \"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==\",\n          \"dev\": true,\n          \"requires\": {\n            \"has-flag\": \"^3.0.0\"\n          }\n        }\n      }\n    },\n    \"@babel/parser\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz\",\n      \"integrity\": \"sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==\"\n    },\n    \"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz\",\n      \"integrity\": \"sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz\",\n      \"integrity\": \"sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/plugin-proposal-optional-chaining\": \"^7.20.7\"\n      }\n    },\n    \"@babel/plugin-proposal-async-generator-functions\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz\",\n      \"integrity\": \"sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-remap-async-to-generator\": \"^7.18.9\",\n        \"@babel/plugin-syntax-async-generators\": \"^7.8.4\"\n      }\n    },\n    \"@babel/plugin-proposal-class-properties\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz\",\n      \"integrity\": \"sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-proposal-class-static-block\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz\",\n      \"integrity\": \"sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.21.0\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-class-static-block\": \"^7.14.5\"\n      }\n    },\n    \"@babel/plugin-proposal-dynamic-import\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz\",\n      \"integrity\": \"sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-export-namespace-from\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz\",\n      \"integrity\": \"sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\",\n        \"@babel/plugin-syntax-export-namespace-from\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-json-strings\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz\",\n      \"integrity\": \"sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-json-strings\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-logical-assignment-operators\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz\",\n      \"integrity\": \"sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-logical-assignment-operators\": \"^7.10.4\"\n      }\n    },\n    \"@babel/plugin-proposal-nullish-coalescing-operator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz\",\n      \"integrity\": \"sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-nullish-coalescing-operator\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-numeric-separator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz\",\n      \"integrity\": \"sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-numeric-separator\": \"^7.10.4\"\n      }\n    },\n    \"@babel/plugin-proposal-object-rest-spread\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz\",\n      \"integrity\": \"sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/compat-data\": \"^7.20.5\",\n        \"@babel/helper-compilation-targets\": \"^7.20.7\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-object-rest-spread\": \"^7.8.3\",\n        \"@babel/plugin-transform-parameters\": \"^7.20.7\"\n      }\n    },\n    \"@babel/plugin-proposal-optional-catch-binding\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz\",\n      \"integrity\": \"sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/plugin-syntax-optional-catch-binding\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-optional-chaining\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz\",\n      \"integrity\": \"sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\",\n        \"@babel/plugin-syntax-optional-chaining\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-proposal-private-methods\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz\",\n      \"integrity\": \"sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-class-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-proposal-private-property-in-object\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz\",\n      \"integrity\": \"sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-create-class-features-plugin\": \"^7.21.0\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/plugin-syntax-private-property-in-object\": \"^7.14.5\"\n      }\n    },\n    \"@babel/plugin-proposal-unicode-property-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-syntax-async-generators\": {\n      \"version\": \"7.8.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz\",\n      \"integrity\": \"sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-class-properties\": {\n      \"version\": \"7.12.13\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz\",\n      \"integrity\": \"sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.12.13\"\n      }\n    },\n    \"@babel/plugin-syntax-class-static-block\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz\",\n      \"integrity\": \"sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      }\n    },\n    \"@babel/plugin-syntax-dynamic-import\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz\",\n      \"integrity\": \"sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-export-namespace-from\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz\",\n      \"integrity\": \"sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.3\"\n      }\n    },\n    \"@babel/plugin-syntax-import-assertions\": {\n      \"version\": \"7.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz\",\n      \"integrity\": \"sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.19.0\"\n      }\n    },\n    \"@babel/plugin-syntax-json-strings\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz\",\n      \"integrity\": \"sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-logical-assignment-operators\": {\n      \"version\": \"7.10.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz\",\n      \"integrity\": \"sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.10.4\"\n      }\n    },\n    \"@babel/plugin-syntax-nullish-coalescing-operator\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz\",\n      \"integrity\": \"sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-numeric-separator\": {\n      \"version\": \"7.10.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz\",\n      \"integrity\": \"sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.10.4\"\n      }\n    },\n    \"@babel/plugin-syntax-object-rest-spread\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz\",\n      \"integrity\": \"sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-optional-catch-binding\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz\",\n      \"integrity\": \"sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-optional-chaining\": {\n      \"version\": \"7.8.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz\",\n      \"integrity\": \"sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.8.0\"\n      }\n    },\n    \"@babel/plugin-syntax-private-property-in-object\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz\",\n      \"integrity\": \"sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      }\n    },\n    \"@babel/plugin-syntax-top-level-await\": {\n      \"version\": \"7.14.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz\",\n      \"integrity\": \"sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.14.5\"\n      }\n    },\n    \"@babel/plugin-transform-arrow-functions\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz\",\n      \"integrity\": \"sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-async-to-generator\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz\",\n      \"integrity\": \"sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-module-imports\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-remap-async-to-generator\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-block-scoped-functions\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz\",\n      \"integrity\": \"sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-block-scoping\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz\",\n      \"integrity\": \"sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-classes\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz\",\n      \"integrity\": \"sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-annotate-as-pure\": \"^7.18.6\",\n        \"@babel/helper-compilation-targets\": \"^7.20.7\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-optimise-call-expression\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-replace-supers\": \"^7.20.7\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"globals\": \"^11.1.0\"\n      },\n      \"dependencies\": {\n        \"globals\": {\n          \"version\": \"11.12.0\",\n          \"resolved\": \"https://registry.npmjs.org/globals/-/globals-11.12.0.tgz\",\n          \"integrity\": \"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/plugin-transform-computed-properties\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz\",\n      \"integrity\": \"sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/template\": \"^7.20.7\"\n      }\n    },\n    \"@babel/plugin-transform-destructuring\": {\n      \"version\": \"7.21.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz\",\n      \"integrity\": \"sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-dotall-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-duplicate-keys\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz\",\n      \"integrity\": \"sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-exponentiation-operator\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz\",\n      \"integrity\": \"sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-builder-binary-assignment-operator-visitor\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-for-of\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz\",\n      \"integrity\": \"sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-function-name\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz\",\n      \"integrity\": \"sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-compilation-targets\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.18.9\",\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-literals\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz\",\n      \"integrity\": \"sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-member-expression-literals\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz\",\n      \"integrity\": \"sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-modules-amd\": {\n      \"version\": \"7.20.11\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz\",\n      \"integrity\": \"sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-module-transforms\": \"^7.20.11\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-modules-commonjs\": {\n      \"version\": \"7.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz\",\n      \"integrity\": \"sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-module-transforms\": \"^7.21.2\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-simple-access\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-modules-systemjs\": {\n      \"version\": \"7.20.11\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz\",\n      \"integrity\": \"sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-hoist-variables\": \"^7.18.6\",\n        \"@babel/helper-module-transforms\": \"^7.20.11\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\"\n      }\n    },\n    \"@babel/plugin-transform-modules-umd\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz\",\n      \"integrity\": \"sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-module-transforms\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-named-capturing-groups-regex\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz\",\n      \"integrity\": \"sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.20.5\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-new-target\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz\",\n      \"integrity\": \"sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-object-super\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz\",\n      \"integrity\": \"sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\",\n        \"@babel/helper-replace-supers\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-parameters\": {\n      \"version\": \"7.21.3\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz\",\n      \"integrity\": \"sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\"\n      }\n    },\n    \"@babel/plugin-transform-property-literals\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz\",\n      \"integrity\": \"sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-regenerator\": {\n      \"version\": \"7.20.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz\",\n      \"integrity\": \"sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"regenerator-transform\": \"^0.15.1\"\n      }\n    },\n    \"@babel/plugin-transform-reserved-words\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz\",\n      \"integrity\": \"sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-shorthand-properties\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz\",\n      \"integrity\": \"sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-spread\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz\",\n      \"integrity\": \"sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.20.0\"\n      }\n    },\n    \"@babel/plugin-transform-sticky-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/plugin-transform-template-literals\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz\",\n      \"integrity\": \"sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-typeof-symbol\": {\n      \"version\": \"7.18.9\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz\",\n      \"integrity\": \"sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-unicode-escapes\": {\n      \"version\": \"7.18.10\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz\",\n      \"integrity\": \"sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.18.9\"\n      }\n    },\n    \"@babel/plugin-transform-unicode-regex\": {\n      \"version\": \"7.18.6\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz\",\n      \"integrity\": \"sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-create-regexp-features-plugin\": \"^7.18.6\",\n        \"@babel/helper-plugin-utils\": \"^7.18.6\"\n      }\n    },\n    \"@babel/preset-env\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz\",\n      \"integrity\": \"sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/compat-data\": \"^7.21.4\",\n        \"@babel/helper-compilation-targets\": \"^7.21.4\",\n        \"@babel/helper-plugin-utils\": \"^7.20.2\",\n        \"@babel/helper-validator-option\": \"^7.21.0\",\n        \"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression\": \"^7.18.6\",\n        \"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining\": \"^7.20.7\",\n        \"@babel/plugin-proposal-async-generator-functions\": \"^7.20.7\",\n        \"@babel/plugin-proposal-class-properties\": \"^7.18.6\",\n        \"@babel/plugin-proposal-class-static-block\": \"^7.21.0\",\n        \"@babel/plugin-proposal-dynamic-import\": \"^7.18.6\",\n        \"@babel/plugin-proposal-export-namespace-from\": \"^7.18.9\",\n        \"@babel/plugin-proposal-json-strings\": \"^7.18.6\",\n        \"@babel/plugin-proposal-logical-assignment-operators\": \"^7.20.7\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\": \"^7.18.6\",\n        \"@babel/plugin-proposal-numeric-separator\": \"^7.18.6\",\n        \"@babel/plugin-proposal-object-rest-spread\": \"^7.20.7\",\n        \"@babel/plugin-proposal-optional-catch-binding\": \"^7.18.6\",\n        \"@babel/plugin-proposal-optional-chaining\": \"^7.21.0\",\n        \"@babel/plugin-proposal-private-methods\": \"^7.18.6\",\n        \"@babel/plugin-proposal-private-property-in-object\": \"^7.21.0\",\n        \"@babel/plugin-proposal-unicode-property-regex\": \"^7.18.6\",\n        \"@babel/plugin-syntax-async-generators\": \"^7.8.4\",\n        \"@babel/plugin-syntax-class-properties\": \"^7.12.13\",\n        \"@babel/plugin-syntax-class-static-block\": \"^7.14.5\",\n        \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\",\n        \"@babel/plugin-syntax-export-namespace-from\": \"^7.8.3\",\n        \"@babel/plugin-syntax-import-assertions\": \"^7.20.0\",\n        \"@babel/plugin-syntax-json-strings\": \"^7.8.3\",\n        \"@babel/plugin-syntax-logical-assignment-operators\": \"^7.10.4\",\n        \"@babel/plugin-syntax-nullish-coalescing-operator\": \"^7.8.3\",\n        \"@babel/plugin-syntax-numeric-separator\": \"^7.10.4\",\n        \"@babel/plugin-syntax-object-rest-spread\": \"^7.8.3\",\n        \"@babel/plugin-syntax-optional-catch-binding\": \"^7.8.3\",\n        \"@babel/plugin-syntax-optional-chaining\": \"^7.8.3\",\n        \"@babel/plugin-syntax-private-property-in-object\": \"^7.14.5\",\n        \"@babel/plugin-syntax-top-level-await\": \"^7.14.5\",\n        \"@babel/plugin-transform-arrow-functions\": \"^7.20.7\",\n        \"@babel/plugin-transform-async-to-generator\": \"^7.20.7\",\n        \"@babel/plugin-transform-block-scoped-functions\": \"^7.18.6\",\n        \"@babel/plugin-transform-block-scoping\": \"^7.21.0\",\n        \"@babel/plugin-transform-classes\": \"^7.21.0\",\n        \"@babel/plugin-transform-computed-properties\": \"^7.20.7\",\n        \"@babel/plugin-transform-destructuring\": \"^7.21.3\",\n        \"@babel/plugin-transform-dotall-regex\": \"^7.18.6\",\n        \"@babel/plugin-transform-duplicate-keys\": \"^7.18.9\",\n        \"@babel/plugin-transform-exponentiation-operator\": \"^7.18.6\",\n        \"@babel/plugin-transform-for-of\": \"^7.21.0\",\n        \"@babel/plugin-transform-function-name\": \"^7.18.9\",\n        \"@babel/plugin-transform-literals\": \"^7.18.9\",\n        \"@babel/plugin-transform-member-expression-literals\": \"^7.18.6\",\n        \"@babel/plugin-transform-modules-amd\": \"^7.20.11\",\n        \"@babel/plugin-transform-modules-commonjs\": \"^7.21.2\",\n        \"@babel/plugin-transform-modules-systemjs\": \"^7.20.11\",\n        \"@babel/plugin-transform-modules-umd\": \"^7.18.6\",\n        \"@babel/plugin-transform-named-capturing-groups-regex\": \"^7.20.5\",\n        \"@babel/plugin-transform-new-target\": \"^7.18.6\",\n        \"@babel/plugin-transform-object-super\": \"^7.18.6\",\n        \"@babel/plugin-transform-parameters\": \"^7.21.3\",\n        \"@babel/plugin-transform-property-literals\": \"^7.18.6\",\n        \"@babel/plugin-transform-regenerator\": \"^7.20.5\",\n        \"@babel/plugin-transform-reserved-words\": \"^7.18.6\",\n        \"@babel/plugin-transform-shorthand-properties\": \"^7.18.6\",\n        \"@babel/plugin-transform-spread\": \"^7.20.7\",\n        \"@babel/plugin-transform-sticky-regex\": \"^7.18.6\",\n        \"@babel/plugin-transform-template-literals\": \"^7.18.9\",\n        \"@babel/plugin-transform-typeof-symbol\": \"^7.18.9\",\n        \"@babel/plugin-transform-unicode-escapes\": \"^7.18.10\",\n        \"@babel/plugin-transform-unicode-regex\": \"^7.18.6\",\n        \"@babel/preset-modules\": \"^0.1.5\",\n        \"@babel/types\": \"^7.21.4\",\n        \"babel-plugin-polyfill-corejs2\": \"^0.3.3\",\n        \"babel-plugin-polyfill-corejs3\": \"^0.6.0\",\n        \"babel-plugin-polyfill-regenerator\": \"^0.4.1\",\n        \"core-js-compat\": \"^3.25.1\",\n        \"semver\": \"^6.3.0\"\n      },\n      \"dependencies\": {\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/preset-modules\": {\n      \"version\": \"0.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz\",\n      \"integrity\": \"sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-plugin-utils\": \"^7.0.0\",\n        \"@babel/plugin-proposal-unicode-property-regex\": \"^7.4.4\",\n        \"@babel/plugin-transform-dotall-regex\": \"^7.4.4\",\n        \"@babel/types\": \"^7.4.4\",\n        \"esutils\": \"^2.0.2\"\n      }\n    },\n    \"@babel/regjsgen\": {\n      \"version\": \"0.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz\",\n      \"integrity\": \"sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==\",\n      \"dev\": true\n    },\n    \"@babel/runtime\": {\n      \"version\": \"7.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz\",\n      \"integrity\": \"sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"regenerator-runtime\": \"^0.13.11\"\n      }\n    },\n    \"@babel/template\": {\n      \"version\": \"7.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz\",\n      \"integrity\": \"sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/code-frame\": \"^7.18.6\",\n        \"@babel/parser\": \"^7.20.7\",\n        \"@babel/types\": \"^7.20.7\"\n      }\n    },\n    \"@babel/traverse\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz\",\n      \"integrity\": \"sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/code-frame\": \"^7.21.4\",\n        \"@babel/generator\": \"^7.21.4\",\n        \"@babel/helper-environment-visitor\": \"^7.18.9\",\n        \"@babel/helper-function-name\": \"^7.21.0\",\n        \"@babel/helper-hoist-variables\": \"^7.18.6\",\n        \"@babel/helper-split-export-declaration\": \"^7.18.6\",\n        \"@babel/parser\": \"^7.21.4\",\n        \"@babel/types\": \"^7.21.4\",\n        \"debug\": \"^4.1.0\",\n        \"globals\": \"^11.1.0\"\n      },\n      \"dependencies\": {\n        \"globals\": {\n          \"version\": \"11.12.0\",\n          \"resolved\": \"https://registry.npmjs.org/globals/-/globals-11.12.0.tgz\",\n          \"integrity\": \"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@babel/types\": {\n      \"version\": \"7.21.4\",\n      \"resolved\": \"https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz\",\n      \"integrity\": \"sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-string-parser\": \"^7.19.4\",\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"to-fast-properties\": \"^2.0.0\"\n      }\n    },\n    \"@commitlint/cli\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/cli/-/cli-17.6.1.tgz\",\n      \"integrity\": \"sha512-kCnDD9LE2ySiTnj/VPaxy4/oRayRcdv4aCuVxtoum8SxIU7OADHc0nJPQfheE8bHcs3zZdWzDMWltRosuT13bg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/format\": \"^17.4.4\",\n        \"@commitlint/lint\": \"^17.6.1\",\n        \"@commitlint/load\": \"^17.5.0\",\n        \"@commitlint/read\": \"^17.5.1\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"execa\": \"^5.0.0\",\n        \"lodash.isfunction\": \"^3.0.9\",\n        \"resolve-from\": \"5.0.0\",\n        \"resolve-global\": \"1.0.0\",\n        \"yargs\": \"^17.0.0\"\n      }\n    },\n    \"@commitlint/config-conventional\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.6.1.tgz\",\n      \"integrity\": \"sha512-ng/ybaSLuTCH9F+7uavSOnEQ9EFMl7lHEjfAEgRh1hwmEe8SpLKpQeMo2aT1IWvHaGMuTb+gjfbzoRf2IR23NQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"conventional-changelog-conventionalcommits\": \"^5.0.0\"\n      }\n    },\n    \"@commitlint/config-validator\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz\",\n      \"integrity\": \"sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"ajv\": \"^8.11.0\"\n      }\n    },\n    \"@commitlint/ensure\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.4.tgz\",\n      \"integrity\": \"sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"lodash.camelcase\": \"^4.3.0\",\n        \"lodash.kebabcase\": \"^4.1.1\",\n        \"lodash.snakecase\": \"^4.1.1\",\n        \"lodash.startcase\": \"^4.4.0\",\n        \"lodash.upperfirst\": \"^4.3.1\"\n      }\n    },\n    \"@commitlint/execute-rule\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz\",\n      \"integrity\": \"sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==\",\n      \"dev\": true\n    },\n    \"@commitlint/format\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz\",\n      \"integrity\": \"sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"chalk\": \"^4.1.0\"\n      }\n    },\n    \"@commitlint/is-ignored\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.4.tgz\",\n      \"integrity\": \"sha512-Y3eo1SFJ2JQDik4rWkBC4tlRIxlXEFrRWxcyrzb1PUT2k3kZ/XGNuCDfk/u0bU2/yS0tOA/mTjFsV+C4qyACHw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"semver\": \"7.3.8\"\n      }\n    },\n    \"@commitlint/lint\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/lint/-/lint-17.6.1.tgz\",\n      \"integrity\": \"sha512-VARJ9kxH64isgwVnC+ABPafCYzqxpsWJIpDaTuI0gh8aX4GQ0i7cn9tvxtFNfJj4ER2BAJeWJ0vURdNYjK2RQQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/is-ignored\": \"^17.4.4\",\n        \"@commitlint/parse\": \"^17.4.4\",\n        \"@commitlint/rules\": \"^17.6.1\",\n        \"@commitlint/types\": \"^17.4.4\"\n      }\n    },\n    \"@commitlint/load\": {\n      \"version\": \"17.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz\",\n      \"integrity\": \"sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/config-validator\": \"^17.4.4\",\n        \"@commitlint/execute-rule\": \"^17.4.0\",\n        \"@commitlint/resolve-extends\": \"^17.4.4\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"@types/node\": \"*\",\n        \"chalk\": \"^4.1.0\",\n        \"cosmiconfig\": \"^8.0.0\",\n        \"cosmiconfig-typescript-loader\": \"^4.0.0\",\n        \"lodash.isplainobject\": \"^4.0.6\",\n        \"lodash.merge\": \"^4.6.2\",\n        \"lodash.uniq\": \"^4.5.0\",\n        \"resolve-from\": \"^5.0.0\",\n        \"ts-node\": \"^10.8.1\",\n        \"typescript\": \"^4.6.4 || ^5.0.0\"\n      }\n    },\n    \"@commitlint/message\": {\n      \"version\": \"17.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz\",\n      \"integrity\": \"sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==\",\n      \"dev\": true\n    },\n    \"@commitlint/parse\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.4.tgz\",\n      \"integrity\": \"sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/types\": \"^17.4.4\",\n        \"conventional-changelog-angular\": \"^5.0.11\",\n        \"conventional-commits-parser\": \"^3.2.2\"\n      }\n    },\n    \"@commitlint/read\": {\n      \"version\": \"17.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz\",\n      \"integrity\": \"sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/top-level\": \"^17.4.0\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"fs-extra\": \"^11.0.0\",\n        \"git-raw-commits\": \"^2.0.11\",\n        \"minimist\": \"^1.2.6\"\n      }\n    },\n    \"@commitlint/resolve-extends\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz\",\n      \"integrity\": \"sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/config-validator\": \"^17.4.4\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"import-fresh\": \"^3.0.0\",\n        \"lodash.mergewith\": \"^4.6.2\",\n        \"resolve-from\": \"^5.0.0\",\n        \"resolve-global\": \"^1.0.0\"\n      }\n    },\n    \"@commitlint/rules\": {\n      \"version\": \"17.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/rules/-/rules-17.6.1.tgz\",\n      \"integrity\": \"sha512-lUdHw6lYQ1RywExXDdLOKxhpp6857/4c95Dc/1BikrHgdysVUXz26yV0vp1GL7Gv+avx9WqZWTIVB7pNouxlfw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@commitlint/ensure\": \"^17.4.4\",\n        \"@commitlint/message\": \"^17.4.2\",\n        \"@commitlint/to-lines\": \"^17.4.0\",\n        \"@commitlint/types\": \"^17.4.4\",\n        \"execa\": \"^5.0.0\"\n      }\n    },\n    \"@commitlint/to-lines\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz\",\n      \"integrity\": \"sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==\",\n      \"dev\": true\n    },\n    \"@commitlint/top-level\": {\n      \"version\": \"17.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz\",\n      \"integrity\": \"sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"find-up\": \"^5.0.0\"\n      }\n    },\n    \"@commitlint/types\": {\n      \"version\": \"17.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz\",\n      \"integrity\": \"sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"chalk\": \"^4.1.0\"\n      }\n    },\n    \"@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": {\n          \"version\": \"0.3.9\",\n          \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n          \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@jridgewell/resolve-uri\": \"^3.0.3\",\n            \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n          }\n        }\n      }\n    },\n    \"@css-render/plugin-bem\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/@css-render/plugin-bem/-/plugin-bem-0.15.12.tgz\",\n      \"integrity\": \"sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==\",\n      \"requires\": {}\n    },\n    \"@css-render/vue3-ssr\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/@css-render/vue3-ssr/-/vue3-ssr-0.15.12.tgz\",\n      \"integrity\": \"sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==\",\n      \"requires\": {}\n    },\n    \"@emotion/hash\": {\n      \"version\": \"0.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz\",\n      \"integrity\": \"sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==\"\n    },\n    \"@esbuild/android-arm\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz\",\n      \"integrity\": \"sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/android-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/android-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/darwin-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/darwin-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/freebsd-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/freebsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-arm\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz\",\n      \"integrity\": \"sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-ia32\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz\",\n      \"integrity\": \"sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-loong64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz\",\n      \"integrity\": \"sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-mips64el\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz\",\n      \"integrity\": \"sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-ppc64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz\",\n      \"integrity\": \"sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-riscv64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz\",\n      \"integrity\": \"sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-s390x\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz\",\n      \"integrity\": \"sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/linux-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/netbsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/openbsd-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/sunos-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/win32-arm64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz\",\n      \"integrity\": \"sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/win32-ia32\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz\",\n      \"integrity\": \"sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@esbuild/win32-x64\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz\",\n      \"integrity\": \"sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"@eslint-community/eslint-utils\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz\",\n      \"integrity\": \"sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-visitor-keys\": \"^3.3.0\"\n      }\n    },\n    \"@eslint-community/regexpp\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz\",\n      \"integrity\": \"sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==\",\n      \"dev\": true\n    },\n    \"@eslint/eslintrc\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz\",\n      \"integrity\": \"sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ajv\": \"^6.12.4\",\n        \"debug\": \"^4.3.2\",\n        \"espree\": \"^9.5.1\",\n        \"globals\": \"^13.19.0\",\n        \"ignore\": \"^5.2.0\",\n        \"import-fresh\": \"^3.2.1\",\n        \"js-yaml\": \"^4.1.0\",\n        \"minimatch\": \"^3.1.2\",\n        \"strip-json-comments\": \"^3.1.1\"\n      },\n      \"dependencies\": {\n        \"ajv\": {\n          \"version\": \"6.12.6\",\n          \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz\",\n          \"integrity\": \"sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fast-deep-equal\": \"^3.1.1\",\n            \"fast-json-stable-stringify\": \"^2.0.0\",\n            \"json-schema-traverse\": \"^0.4.1\",\n            \"uri-js\": \"^4.2.2\"\n          }\n        },\n        \"json-schema-traverse\": {\n          \"version\": \"0.4.1\",\n          \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz\",\n          \"integrity\": \"sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@eslint/js\": {\n      \"version\": \"8.39.0\",\n      \"resolved\": \"https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz\",\n      \"integrity\": \"sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==\",\n      \"dev\": true\n    },\n    \"@humanwhocodes/config-array\": {\n      \"version\": \"0.11.8\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz\",\n      \"integrity\": \"sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@humanwhocodes/object-schema\": \"^1.2.1\",\n        \"debug\": \"^4.1.1\",\n        \"minimatch\": \"^3.0.5\"\n      }\n    },\n    \"@humanwhocodes/module-importer\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz\",\n      \"integrity\": \"sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==\",\n      \"dev\": true\n    },\n    \"@humanwhocodes/object-schema\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz\",\n      \"integrity\": \"sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==\",\n      \"dev\": true\n    },\n    \"@iconify/types\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz\",\n      \"integrity\": \"sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==\",\n      \"dev\": true\n    },\n    \"@iconify/vue\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@iconify/vue/-/vue-4.1.1.tgz\",\n      \"integrity\": \"sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@iconify/types\": \"^2.0.0\"\n      }\n    },\n    \"@intlify/core-base\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/core-base/-/core-base-9.2.2.tgz\",\n      \"integrity\": \"sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==\",\n      \"requires\": {\n        \"@intlify/devtools-if\": \"9.2.2\",\n        \"@intlify/message-compiler\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\",\n        \"@intlify/vue-devtools\": \"9.2.2\"\n      }\n    },\n    \"@intlify/devtools-if\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.2.2.tgz\",\n      \"integrity\": \"sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==\",\n      \"requires\": {\n        \"@intlify/shared\": \"9.2.2\"\n      }\n    },\n    \"@intlify/message-compiler\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.2.tgz\",\n      \"integrity\": \"sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==\",\n      \"requires\": {\n        \"@intlify/shared\": \"9.2.2\",\n        \"source-map\": \"0.6.1\"\n      }\n    },\n    \"@intlify/shared\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/shared/-/shared-9.2.2.tgz\",\n      \"integrity\": \"sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==\"\n    },\n    \"@intlify/vue-devtools\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz\",\n      \"integrity\": \"sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==\",\n      \"requires\": {\n        \"@intlify/core-base\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\"\n      }\n    },\n    \"@jridgewell/gen-mapping\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz\",\n      \"integrity\": \"sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/set-array\": \"^1.0.1\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      }\n    },\n    \"@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true\n    },\n    \"@jridgewell/set-array\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz\",\n      \"integrity\": \"sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==\",\n      \"dev\": true\n    },\n    \"@jridgewell/source-map\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz\",\n      \"integrity\": \"sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.0\",\n        \"@jridgewell/trace-mapping\": \"^0.3.9\"\n      }\n    },\n    \"@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.15\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz\",\n      \"integrity\": \"sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==\",\n      \"dev\": true\n    },\n    \"@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.18\",\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz\",\n      \"integrity\": \"sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/resolve-uri\": \"3.1.0\",\n        \"@jridgewell/sourcemap-codec\": \"1.4.14\"\n      },\n      \"dependencies\": {\n        \"@jridgewell/sourcemap-codec\": {\n          \"version\": \"1.4.14\",\n          \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n          \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"@juggle/resize-observer\": {\n      \"version\": \"3.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz\",\n      \"integrity\": \"sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==\"\n    },\n    \"@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      }\n    },\n    \"@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true\n    },\n    \"@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      }\n    },\n    \"@rollup/plugin-replace\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz\",\n      \"integrity\": \"sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@rollup/pluginutils\": \"^5.0.1\",\n        \"magic-string\": \"^0.27.0\"\n      }\n    },\n    \"@rollup/pluginutils\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz\",\n      \"integrity\": \"sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/estree\": \"^1.0.0\",\n        \"estree-walker\": \"^2.0.2\",\n        \"picomatch\": \"^2.3.1\"\n      }\n    },\n    \"@surma/rollup-plugin-off-main-thread\": {\n      \"version\": \"2.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz\",\n      \"integrity\": \"sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ejs\": \"^3.1.6\",\n        \"json5\": \"^2.2.0\",\n        \"magic-string\": \"^0.25.0\",\n        \"string.prototype.matchall\": \"^4.0.6\"\n      },\n      \"dependencies\": {\n        \"json5\": {\n          \"version\": \"2.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz\",\n          \"integrity\": \"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==\",\n          \"dev\": true\n        },\n        \"magic-string\": {\n          \"version\": \"0.25.9\",\n          \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n          \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"sourcemap-codec\": \"^1.4.8\"\n          }\n        }\n      }\n    },\n    \"@traptitech/markdown-it-katex\": {\n      \"version\": \"3.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/@traptitech/markdown-it-katex/-/markdown-it-katex-3.6.0.tgz\",\n      \"integrity\": \"sha512-CnJzTWxsgLGXFdSrWRaGz7GZ1kUUi8g3E9HzJmeveX1YwVJavrKYqysktfHZQsujdnRqV5O7g8FPKEA/aeTkOQ==\",\n      \"requires\": {\n        \"katex\": \"^0.16.0\"\n      }\n    },\n    \"@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true\n    },\n    \"@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true\n    },\n    \"@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true\n    },\n    \"@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true\n    },\n    \"@types/crypto-js\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz\",\n      \"integrity\": \"sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==\",\n      \"dev\": true\n    },\n    \"@types/estree\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz\",\n      \"integrity\": \"sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==\",\n      \"dev\": true\n    },\n    \"@types/json-schema\": {\n      \"version\": \"7.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz\",\n      \"integrity\": \"sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==\",\n      \"dev\": true\n    },\n    \"@types/json5\": {\n      \"version\": \"0.0.29\",\n      \"resolved\": \"https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz\",\n      \"integrity\": \"sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==\",\n      \"dev\": true\n    },\n    \"@types/katex\": {\n      \"version\": \"0.16.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz\",\n      \"integrity\": \"sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==\",\n      \"dev\": true\n    },\n    \"@types/linkify-it\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz\",\n      \"integrity\": \"sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==\",\n      \"dev\": true\n    },\n    \"@types/lodash\": {\n      \"version\": \"4.14.194\",\n      \"resolved\": \"https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz\",\n      \"integrity\": \"sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==\"\n    },\n    \"@types/lodash-es\": {\n      \"version\": \"4.17.7\",\n      \"resolved\": \"https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz\",\n      \"integrity\": \"sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==\",\n      \"requires\": {\n        \"@types/lodash\": \"*\"\n      }\n    },\n    \"@types/markdown-it\": {\n      \"version\": \"12.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz\",\n      \"integrity\": \"sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/linkify-it\": \"*\",\n        \"@types/mdurl\": \"*\"\n      }\n    },\n    \"@types/markdown-it-link-attributes\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.1.tgz\",\n      \"integrity\": \"sha512-K8RnNb1q8j7rDOJbMF7AnlhCC/45BjrQ8z3WZWOrvkBIl8u9RXvmBdG/hfpnmK1JhhEZcmFEKWt+ilW1Mly+2Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/markdown-it\": \"*\"\n      }\n    },\n    \"@types/mdast\": {\n      \"version\": \"3.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz\",\n      \"integrity\": \"sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/unist\": \"*\"\n      }\n    },\n    \"@types/mdurl\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz\",\n      \"integrity\": \"sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==\",\n      \"dev\": true\n    },\n    \"@types/minimist\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz\",\n      \"integrity\": \"sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==\",\n      \"dev\": true\n    },\n    \"@types/node\": {\n      \"version\": \"18.16.0\",\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz\",\n      \"integrity\": \"sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==\",\n      \"dev\": true\n    },\n    \"@types/normalize-package-data\": {\n      \"version\": \"2.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz\",\n      \"integrity\": \"sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==\",\n      \"dev\": true\n    },\n    \"@types/resolve\": {\n      \"version\": \"1.17.1\",\n      \"resolved\": \"https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz\",\n      \"integrity\": \"sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"@types/semver\": {\n      \"version\": \"7.3.13\",\n      \"resolved\": \"https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz\",\n      \"integrity\": \"sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==\",\n      \"dev\": true\n    },\n    \"@types/trusted-types\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz\",\n      \"integrity\": \"sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==\",\n      \"dev\": true\n    },\n    \"@types/unist\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz\",\n      \"integrity\": \"sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==\",\n      \"dev\": true\n    },\n    \"@types/web-bluetooth\": {\n      \"version\": \"0.0.16\",\n      \"resolved\": \"https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz\",\n      \"integrity\": \"sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==\"\n    },\n    \"@typescript-eslint/eslint-plugin\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.0.tgz\",\n      \"integrity\": \"sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@eslint-community/regexpp\": \"^4.4.0\",\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/type-utils\": \"5.59.0\",\n        \"@typescript-eslint/utils\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"grapheme-splitter\": \"^1.0.4\",\n        \"ignore\": \"^5.2.0\",\n        \"natural-compare-lite\": \"^1.4.0\",\n        \"semver\": \"^7.3.7\",\n        \"tsutils\": \"^3.21.0\"\n      }\n    },\n    \"@typescript-eslint/parser\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.0.tgz\",\n      \"integrity\": \"sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"debug\": \"^4.3.4\"\n      }\n    },\n    \"@typescript-eslint/scope-manager\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.0.tgz\",\n      \"integrity\": \"sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/visitor-keys\": \"5.59.0\"\n      }\n    },\n    \"@typescript-eslint/type-utils\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.0.tgz\",\n      \"integrity\": \"sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"@typescript-eslint/utils\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"tsutils\": \"^3.21.0\"\n      }\n    },\n    \"@typescript-eslint/types\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz\",\n      \"integrity\": \"sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==\",\n      \"dev\": true\n    },\n    \"@typescript-eslint/typescript-estree\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz\",\n      \"integrity\": \"sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/visitor-keys\": \"5.59.0\",\n        \"debug\": \"^4.3.4\",\n        \"globby\": \"^11.1.0\",\n        \"is-glob\": \"^4.0.3\",\n        \"semver\": \"^7.3.7\",\n        \"tsutils\": \"^3.21.0\"\n      }\n    },\n    \"@typescript-eslint/utils\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.0.tgz\",\n      \"integrity\": \"sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"@types/json-schema\": \"^7.0.9\",\n        \"@types/semver\": \"^7.3.12\",\n        \"@typescript-eslint/scope-manager\": \"5.59.0\",\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"@typescript-eslint/typescript-estree\": \"5.59.0\",\n        \"eslint-scope\": \"^5.1.1\",\n        \"semver\": \"^7.3.7\"\n      }\n    },\n    \"@typescript-eslint/visitor-keys\": {\n      \"version\": \"5.59.0\",\n      \"resolved\": \"https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz\",\n      \"integrity\": \"sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/types\": \"5.59.0\",\n        \"eslint-visitor-keys\": \"^3.3.0\"\n      }\n    },\n    \"@vitejs/plugin-vue\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz\",\n      \"integrity\": \"sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==\",\n      \"dev\": true,\n      \"requires\": {}\n    },\n    \"@volar/language-core\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/language-core/-/language-core-1.4.1.tgz\",\n      \"integrity\": \"sha512-EIY+Swv+TjsWpxOxujjMf1ZXqOjg9MT2VMXZ+1dKva0wD8W0L6EtptFFcCJdBbcKmGMFkr57Qzz9VNMWhs3jXQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@volar/source-map\": \"1.4.1\"\n      }\n    },\n    \"@volar/source-map\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/source-map/-/source-map-1.4.1.tgz\",\n      \"integrity\": \"sha512-bZ46ad72dsbzuOWPUtJjBXkzSQzzSejuR3CT81+GvTEI2E994D8JPXzM3tl98zyCNnjgs4OkRyliImL1dvJ5BA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"muggle-string\": \"^0.2.2\"\n      }\n    },\n    \"@volar/typescript\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/typescript/-/typescript-1.4.1.tgz\",\n      \"integrity\": \"sha512-phTy6p9yG6bgMIKQWEeDOi/aeT0njZsb1a/G1mrEuDsLmAn24Le4gDwSsGNhea6Uhu+3gdpUZn2PmZXa+WG2iQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@volar/language-core\": \"1.4.1\"\n      }\n    },\n    \"@volar/vue-language-core\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.4.4.tgz\",\n      \"integrity\": \"sha512-c3hL6un+CfoOlusGvpypcodmk9ke/ImrWIUc0GkgI+imoQpUGzgu3tEQWlPs604R7AhxeZwWUi8hQNfax0R/zA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@volar/language-core\": \"1.4.1\",\n        \"@volar/source-map\": \"1.4.1\",\n        \"@vue/compiler-dom\": \"^3.2.0\",\n        \"@vue/compiler-sfc\": \"^3.2.0\",\n        \"@vue/reactivity\": \"^3.2.0\",\n        \"@vue/shared\": \"^3.2.0\",\n        \"minimatch\": \"^9.0.0\",\n        \"muggle-string\": \"^0.2.2\",\n        \"vue-template-compiler\": \"^2.7.14\"\n      },\n      \"dependencies\": {\n        \"brace-expansion\": {\n          \"version\": \"2.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n          \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"balanced-match\": \"^1.0.0\"\n          }\n        },\n        \"minimatch\": {\n          \"version\": \"9.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz\",\n          \"integrity\": \"sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==\",\n          \"dev\": true,\n          \"requires\": {\n            \"brace-expansion\": \"^2.0.1\"\n          }\n        }\n      }\n    },\n    \"@volar/vue-typescript\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.4.4.tgz\",\n      \"integrity\": \"sha512-L61Fk15jlJw3QtIddD4cVE5jei5i6zbLJRiaEMYDDnUKB259/qUrdvnMfnZUFVyDwlevzdstjtaUyreeG/0nPQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@volar/typescript\": \"1.4.1\",\n        \"@volar/vue-language-core\": \"1.4.4\"\n      }\n    },\n    \"@vue/compiler-core\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz\",\n      \"integrity\": \"sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==\",\n      \"requires\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"source-map\": \"^0.6.1\"\n      }\n    },\n    \"@vue/compiler-dom\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz\",\n      \"integrity\": \"sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==\",\n      \"requires\": {\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"@vue/compiler-sfc\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz\",\n      \"integrity\": \"sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==\",\n      \"requires\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/compiler-ssr\": \"3.2.47\",\n        \"@vue/reactivity-transform\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"magic-string\": \"^0.25.7\",\n        \"postcss\": \"^8.1.10\",\n        \"source-map\": \"^0.6.1\"\n      },\n      \"dependencies\": {\n        \"magic-string\": {\n          \"version\": \"0.25.9\",\n          \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n          \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n          \"requires\": {\n            \"sourcemap-codec\": \"^1.4.8\"\n          }\n        }\n      }\n    },\n    \"@vue/compiler-ssr\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz\",\n      \"integrity\": \"sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==\",\n      \"requires\": {\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"@vue/devtools-api\": {\n      \"version\": \"6.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz\",\n      \"integrity\": \"sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==\"\n    },\n    \"@vue/reactivity\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz\",\n      \"integrity\": \"sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==\",\n      \"requires\": {\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"@vue/reactivity-transform\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz\",\n      \"integrity\": \"sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==\",\n      \"requires\": {\n        \"@babel/parser\": \"^7.16.4\",\n        \"@vue/compiler-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"estree-walker\": \"^2.0.2\",\n        \"magic-string\": \"^0.25.7\"\n      },\n      \"dependencies\": {\n        \"magic-string\": {\n          \"version\": \"0.25.9\",\n          \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n          \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n          \"requires\": {\n            \"sourcemap-codec\": \"^1.4.8\"\n          }\n        }\n      }\n    },\n    \"@vue/runtime-core\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz\",\n      \"integrity\": \"sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==\",\n      \"requires\": {\n        \"@vue/reactivity\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"@vue/runtime-dom\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz\",\n      \"integrity\": \"sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==\",\n      \"requires\": {\n        \"@vue/runtime-core\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\",\n        \"csstype\": \"^2.6.8\"\n      },\n      \"dependencies\": {\n        \"csstype\": {\n          \"version\": \"2.6.21\",\n          \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz\",\n          \"integrity\": \"sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==\"\n        }\n      }\n    },\n    \"@vue/server-renderer\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz\",\n      \"integrity\": \"sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==\",\n      \"requires\": {\n        \"@vue/compiler-ssr\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"@vue/shared\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz\",\n      \"integrity\": \"sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==\"\n    },\n    \"@vueuse/core\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz\",\n      \"integrity\": \"sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==\",\n      \"requires\": {\n        \"@types/web-bluetooth\": \"^0.0.16\",\n        \"@vueuse/metadata\": \"9.13.0\",\n        \"@vueuse/shared\": \"9.13.0\",\n        \"vue-demi\": \"*\"\n      },\n      \"dependencies\": {\n        \"vue-demi\": {\n          \"version\": \"0.14.0\",\n          \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n          \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n          \"requires\": {}\n        }\n      }\n    },\n    \"@vueuse/metadata\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz\",\n      \"integrity\": \"sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==\"\n    },\n    \"@vueuse/shared\": {\n      \"version\": \"9.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz\",\n      \"integrity\": \"sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==\",\n      \"requires\": {\n        \"vue-demi\": \"*\"\n      },\n      \"dependencies\": {\n        \"vue-demi\": {\n          \"version\": \"0.14.0\",\n          \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n          \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n          \"requires\": {}\n        }\n      }\n    },\n    \"acorn\": {\n      \"version\": \"8.8.2\",\n      \"resolved\": \"https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz\",\n      \"integrity\": \"sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==\",\n      \"dev\": true\n    },\n    \"acorn-jsx\": {\n      \"version\": \"5.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz\",\n      \"integrity\": \"sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==\",\n      \"dev\": true,\n      \"requires\": {}\n    },\n    \"acorn-walk\": {\n      \"version\": \"8.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz\",\n      \"integrity\": \"sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==\",\n      \"dev\": true\n    },\n    \"aggregate-error\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz\",\n      \"integrity\": \"sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"clean-stack\": \"^2.0.0\",\n        \"indent-string\": \"^4.0.0\"\n      }\n    },\n    \"ajv\": {\n      \"version\": \"8.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz\",\n      \"integrity\": \"sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"fast-deep-equal\": \"^3.1.1\",\n        \"json-schema-traverse\": \"^1.0.0\",\n        \"require-from-string\": \"^2.0.2\",\n        \"uri-js\": \"^4.2.2\"\n      }\n    },\n    \"ansi-escapes\": {\n      \"version\": \"4.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz\",\n      \"integrity\": \"sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"type-fest\": \"^0.21.3\"\n      },\n      \"dependencies\": {\n        \"type-fest\": {\n          \"version\": \"0.21.3\",\n          \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz\",\n          \"integrity\": \"sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"ansi-regex\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz\",\n      \"integrity\": \"sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==\",\n      \"dev\": true\n    },\n    \"ansi-styles\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz\",\n      \"integrity\": \"sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"color-convert\": \"^2.0.1\"\n      }\n    },\n    \"any-promise\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz\",\n      \"integrity\": \"sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==\",\n      \"dev\": true\n    },\n    \"anymatch\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz\",\n      \"integrity\": \"sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"normalize-path\": \"^3.0.0\",\n        \"picomatch\": \"^2.0.4\"\n      }\n    },\n    \"arg\": {\n      \"version\": \"5.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/arg/-/arg-5.0.2.tgz\",\n      \"integrity\": \"sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==\",\n      \"dev\": true\n    },\n    \"argparse\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz\",\n      \"integrity\": \"sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==\"\n    },\n    \"array-buffer-byte-length\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz\",\n      \"integrity\": \"sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"is-array-buffer\": \"^3.0.1\"\n      }\n    },\n    \"array-ify\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz\",\n      \"integrity\": \"sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==\",\n      \"dev\": true\n    },\n    \"array-includes\": {\n      \"version\": \"3.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz\",\n      \"integrity\": \"sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"is-string\": \"^1.0.7\"\n      }\n    },\n    \"array-union\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz\",\n      \"integrity\": \"sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==\",\n      \"dev\": true\n    },\n    \"array.prototype.flat\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz\",\n      \"integrity\": \"sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"es-shim-unscopables\": \"^1.0.0\"\n      }\n    },\n    \"array.prototype.flatmap\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz\",\n      \"integrity\": \"sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"es-shim-unscopables\": \"^1.0.0\"\n      }\n    },\n    \"arrify\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz\",\n      \"integrity\": \"sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==\",\n      \"dev\": true\n    },\n    \"astral-regex\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz\",\n      \"integrity\": \"sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==\",\n      \"dev\": true\n    },\n    \"async\": {\n      \"version\": \"3.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/async/-/async-3.2.4.tgz\",\n      \"integrity\": \"sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==\",\n      \"dev\": true\n    },\n    \"async-validator\": {\n      \"version\": \"4.2.5\",\n      \"resolved\": \"https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz\",\n      \"integrity\": \"sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==\"\n    },\n    \"asynckit\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz\",\n      \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\",\n      \"dev\": true\n    },\n    \"at-least-node\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz\",\n      \"integrity\": \"sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==\",\n      \"dev\": true\n    },\n    \"autoprefixer\": {\n      \"version\": \"10.4.14\",\n      \"resolved\": \"https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz\",\n      \"integrity\": \"sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"browserslist\": \"^4.21.5\",\n        \"caniuse-lite\": \"^1.0.30001464\",\n        \"fraction.js\": \"^4.2.0\",\n        \"normalize-range\": \"^0.1.2\",\n        \"picocolors\": \"^1.0.0\",\n        \"postcss-value-parser\": \"^4.2.0\"\n      }\n    },\n    \"available-typed-arrays\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz\",\n      \"integrity\": \"sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==\",\n      \"dev\": true\n    },\n    \"axios\": {\n      \"version\": \"1.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/axios/-/axios-1.3.6.tgz\",\n      \"integrity\": \"sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"follow-redirects\": \"^1.15.0\",\n        \"form-data\": \"^4.0.0\",\n        \"proxy-from-env\": \"^1.1.0\"\n      }\n    },\n    \"babel-plugin-polyfill-corejs2\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz\",\n      \"integrity\": \"sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/compat-data\": \"^7.17.7\",\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\",\n        \"semver\": \"^6.1.1\"\n      },\n      \"dependencies\": {\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"babel-plugin-polyfill-corejs3\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz\",\n      \"integrity\": \"sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\",\n        \"core-js-compat\": \"^3.25.1\"\n      }\n    },\n    \"babel-plugin-polyfill-regenerator\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz\",\n      \"integrity\": \"sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-define-polyfill-provider\": \"^0.3.3\"\n      }\n    },\n    \"balanced-match\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz\",\n      \"integrity\": \"sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==\",\n      \"dev\": true\n    },\n    \"base64-arraybuffer\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz\",\n      \"integrity\": \"sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==\"\n    },\n    \"binary-extensions\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz\",\n      \"integrity\": \"sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==\",\n      \"dev\": true\n    },\n    \"boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"dev\": true\n    },\n    \"brace-expansion\": {\n      \"version\": \"1.1.11\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz\",\n      \"integrity\": \"sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"balanced-match\": \"^1.0.0\",\n        \"concat-map\": \"0.0.1\"\n      }\n    },\n    \"braces\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/braces/-/braces-3.0.2.tgz\",\n      \"integrity\": \"sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"fill-range\": \"^7.0.1\"\n      }\n    },\n    \"browserslist\": {\n      \"version\": \"4.21.5\",\n      \"resolved\": \"https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz\",\n      \"integrity\": \"sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"caniuse-lite\": \"^1.0.30001449\",\n        \"electron-to-chromium\": \"^1.4.284\",\n        \"node-releases\": \"^2.0.8\",\n        \"update-browserslist-db\": \"^1.0.10\"\n      }\n    },\n    \"buffer-from\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz\",\n      \"integrity\": \"sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==\",\n      \"dev\": true\n    },\n    \"builtin-modules\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz\",\n      \"integrity\": \"sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==\",\n      \"dev\": true\n    },\n    \"builtins\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz\",\n      \"integrity\": \"sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"semver\": \"^7.0.0\"\n      }\n    },\n    \"call-bind\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz\",\n      \"integrity\": \"sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"function-bind\": \"^1.1.1\",\n        \"get-intrinsic\": \"^1.0.2\"\n      }\n    },\n    \"callsites\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz\",\n      \"integrity\": \"sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==\",\n      \"dev\": true\n    },\n    \"camelcase\": {\n      \"version\": \"5.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz\",\n      \"integrity\": \"sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==\",\n      \"dev\": true\n    },\n    \"camelcase-css\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz\",\n      \"integrity\": \"sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==\",\n      \"dev\": true\n    },\n    \"camelcase-keys\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz\",\n      \"integrity\": \"sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"camelcase\": \"^5.3.1\",\n        \"map-obj\": \"^4.0.0\",\n        \"quick-lru\": \"^4.0.1\"\n      }\n    },\n    \"caniuse-lite\": {\n      \"version\": \"1.0.30001481\",\n      \"resolved\": \"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz\",\n      \"integrity\": \"sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==\",\n      \"dev\": true\n    },\n    \"chalk\": {\n      \"version\": \"4.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz\",\n      \"integrity\": \"sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-styles\": \"^4.1.0\",\n        \"supports-color\": \"^7.1.0\"\n      }\n    },\n    \"character-entities\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz\",\n      \"integrity\": \"sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==\",\n      \"dev\": true\n    },\n    \"character-entities-legacy\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz\",\n      \"integrity\": \"sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==\",\n      \"dev\": true\n    },\n    \"character-reference-invalid\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz\",\n      \"integrity\": \"sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==\",\n      \"dev\": true\n    },\n    \"chokidar\": {\n      \"version\": \"3.5.3\",\n      \"resolved\": \"https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz\",\n      \"integrity\": \"sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"anymatch\": \"~3.1.2\",\n        \"braces\": \"~3.0.2\",\n        \"fsevents\": \"~2.3.2\",\n        \"glob-parent\": \"~5.1.2\",\n        \"is-binary-path\": \"~2.1.0\",\n        \"is-glob\": \"~4.0.1\",\n        \"normalize-path\": \"~3.0.0\",\n        \"readdirp\": \"~3.6.0\"\n      },\n      \"dependencies\": {\n        \"glob-parent\": {\n          \"version\": \"5.1.2\",\n          \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz\",\n          \"integrity\": \"sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==\",\n          \"dev\": true,\n          \"requires\": {\n            \"is-glob\": \"^4.0.1\"\n          }\n        }\n      }\n    },\n    \"ci-info\": {\n      \"version\": \"3.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz\",\n      \"integrity\": \"sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==\",\n      \"dev\": true\n    },\n    \"clean-regexp\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz\",\n      \"integrity\": \"sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"escape-string-regexp\": \"^1.0.5\"\n      },\n      \"dependencies\": {\n        \"escape-string-regexp\": {\n          \"version\": \"1.0.5\",\n          \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n          \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"clean-stack\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz\",\n      \"integrity\": \"sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==\",\n      \"dev\": true\n    },\n    \"cli-cursor\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz\",\n      \"integrity\": \"sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"restore-cursor\": \"^3.1.0\"\n      }\n    },\n    \"cli-truncate\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz\",\n      \"integrity\": \"sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"slice-ansi\": \"^5.0.0\",\n        \"string-width\": \"^5.0.0\"\n      }\n    },\n    \"cliui\": {\n      \"version\": \"8.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz\",\n      \"integrity\": \"sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"string-width\": \"^4.2.0\",\n        \"strip-ansi\": \"^6.0.1\",\n        \"wrap-ansi\": \"^7.0.0\"\n      },\n      \"dependencies\": {\n        \"emoji-regex\": {\n          \"version\": \"8.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n          \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n          \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n          \"dev\": true\n        },\n        \"string-width\": {\n          \"version\": \"4.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n          \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"emoji-regex\": \"^8.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\",\n            \"strip-ansi\": \"^6.0.1\"\n          }\n        }\n      }\n    },\n    \"color-convert\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz\",\n      \"integrity\": \"sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"color-name\": \"~1.1.4\"\n      }\n    },\n    \"color-name\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz\",\n      \"integrity\": \"sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==\",\n      \"dev\": true\n    },\n    \"colorette\": {\n      \"version\": \"2.0.20\",\n      \"resolved\": \"https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz\",\n      \"integrity\": \"sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==\",\n      \"dev\": true\n    },\n    \"combined-stream\": {\n      \"version\": \"1.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz\",\n      \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"delayed-stream\": \"~1.0.0\"\n      }\n    },\n    \"commander\": {\n      \"version\": \"8.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-8.3.0.tgz\",\n      \"integrity\": \"sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==\"\n    },\n    \"common-tags\": {\n      \"version\": \"1.8.2\",\n      \"resolved\": \"https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz\",\n      \"integrity\": \"sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==\",\n      \"dev\": true\n    },\n    \"compare-func\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz\",\n      \"integrity\": \"sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"array-ify\": \"^1.0.0\",\n        \"dot-prop\": \"^5.1.0\"\n      }\n    },\n    \"concat-map\": {\n      \"version\": \"0.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz\",\n      \"integrity\": \"sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==\",\n      \"dev\": true\n    },\n    \"conventional-changelog-angular\": {\n      \"version\": \"5.0.13\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz\",\n      \"integrity\": \"sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"compare-func\": \"^2.0.0\",\n        \"q\": \"^1.5.1\"\n      }\n    },\n    \"conventional-changelog-conventionalcommits\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz\",\n      \"integrity\": \"sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"compare-func\": \"^2.0.0\",\n        \"lodash\": \"^4.17.15\",\n        \"q\": \"^1.5.1\"\n      }\n    },\n    \"conventional-commits-parser\": {\n      \"version\": \"3.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz\",\n      \"integrity\": \"sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-text-path\": \"^1.0.1\",\n        \"JSONStream\": \"^1.0.4\",\n        \"lodash\": \"^4.17.15\",\n        \"meow\": \"^8.0.0\",\n        \"split2\": \"^3.0.0\",\n        \"through2\": \"^4.0.0\"\n      }\n    },\n    \"convert-source-map\": {\n      \"version\": \"1.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz\",\n      \"integrity\": \"sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==\",\n      \"dev\": true\n    },\n    \"copy-anything\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz\",\n      \"integrity\": \"sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-what\": \"^3.14.1\"\n      }\n    },\n    \"core-js-compat\": {\n      \"version\": \"3.30.1\",\n      \"resolved\": \"https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.1.tgz\",\n      \"integrity\": \"sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"browserslist\": \"^4.21.5\"\n      }\n    },\n    \"cosmiconfig\": {\n      \"version\": \"8.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz\",\n      \"integrity\": \"sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"import-fresh\": \"^3.2.1\",\n        \"js-yaml\": \"^4.1.0\",\n        \"parse-json\": \"^5.0.0\",\n        \"path-type\": \"^4.0.0\"\n      }\n    },\n    \"cosmiconfig-typescript-loader\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz\",\n      \"integrity\": \"sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==\",\n      \"dev\": true,\n      \"requires\": {}\n    },\n    \"create-require\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz\",\n      \"integrity\": \"sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==\",\n      \"dev\": true\n    },\n    \"cross-spawn\": {\n      \"version\": \"7.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz\",\n      \"integrity\": \"sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"path-key\": \"^3.1.0\",\n        \"shebang-command\": \"^2.0.0\",\n        \"which\": \"^2.0.1\"\n      }\n    },\n    \"crypto-js\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz\",\n      \"integrity\": \"sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==\",\n      \"dev\": true\n    },\n    \"crypto-random-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==\",\n      \"dev\": true\n    },\n    \"css-line-break\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz\",\n      \"integrity\": \"sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==\",\n      \"requires\": {\n        \"utrie\": \"^1.0.2\"\n      }\n    },\n    \"css-render\": {\n      \"version\": \"0.15.12\",\n      \"resolved\": \"https://registry.npmjs.org/css-render/-/css-render-0.15.12.tgz\",\n      \"integrity\": \"sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==\",\n      \"requires\": {\n        \"@emotion/hash\": \"~0.8.0\",\n        \"csstype\": \"~3.0.5\"\n      }\n    },\n    \"cssesc\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz\",\n      \"integrity\": \"sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==\",\n      \"dev\": true\n    },\n    \"csstype\": {\n      \"version\": \"3.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz\",\n      \"integrity\": \"sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==\"\n    },\n    \"dargs\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz\",\n      \"integrity\": \"sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==\",\n      \"dev\": true\n    },\n    \"date-fns\": {\n      \"version\": \"2.29.3\",\n      \"resolved\": \"https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz\",\n      \"integrity\": \"sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==\"\n    },\n    \"date-fns-tz\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.8.tgz\",\n      \"integrity\": \"sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==\",\n      \"requires\": {}\n    },\n    \"de-indent\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz\",\n      \"integrity\": \"sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==\",\n      \"dev\": true\n    },\n    \"debug\": {\n      \"version\": \"4.3.4\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.3.4.tgz\",\n      \"integrity\": \"sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ms\": \"2.1.2\"\n      }\n    },\n    \"decamelize\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz\",\n      \"integrity\": \"sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==\",\n      \"dev\": true\n    },\n    \"decamelize-keys\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz\",\n      \"integrity\": \"sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"decamelize\": \"^1.1.0\",\n        \"map-obj\": \"^1.0.0\"\n      },\n      \"dependencies\": {\n        \"map-obj\": {\n          \"version\": \"1.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz\",\n          \"integrity\": \"sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"deep-is\": {\n      \"version\": \"0.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz\",\n      \"integrity\": \"sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==\",\n      \"dev\": true\n    },\n    \"deepmerge\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz\",\n      \"integrity\": \"sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==\",\n      \"dev\": true\n    },\n    \"define-properties\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz\",\n      \"integrity\": \"sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-property-descriptors\": \"^1.0.0\",\n        \"object-keys\": \"^1.1.1\"\n      }\n    },\n    \"delayed-stream\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz\",\n      \"integrity\": \"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==\",\n      \"dev\": true\n    },\n    \"didyoumean\": {\n      \"version\": \"1.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz\",\n      \"integrity\": \"sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==\",\n      \"dev\": true\n    },\n    \"diff\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/diff/-/diff-4.0.2.tgz\",\n      \"integrity\": \"sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==\",\n      \"dev\": true\n    },\n    \"dir-glob\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz\",\n      \"integrity\": \"sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"path-type\": \"^4.0.0\"\n      }\n    },\n    \"dlv\": {\n      \"version\": \"1.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz\",\n      \"integrity\": \"sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==\",\n      \"dev\": true\n    },\n    \"doctrine\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz\",\n      \"integrity\": \"sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"esutils\": \"^2.0.2\"\n      }\n    },\n    \"dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      }\n    },\n    \"domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"dev\": true\n    },\n    \"domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"domelementtype\": \"^2.3.0\"\n      }\n    },\n    \"domutils\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz\",\n      \"integrity\": \"sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.1\"\n      }\n    },\n    \"dot-prop\": {\n      \"version\": \"5.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz\",\n      \"integrity\": \"sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-obj\": \"^2.0.0\"\n      }\n    },\n    \"eastasianwidth\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz\",\n      \"integrity\": \"sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==\",\n      \"dev\": true\n    },\n    \"ejs\": {\n      \"version\": \"3.1.9\",\n      \"resolved\": \"https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz\",\n      \"integrity\": \"sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"jake\": \"^10.8.5\"\n      }\n    },\n    \"electron-to-chromium\": {\n      \"version\": \"1.4.369\",\n      \"resolved\": \"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.369.tgz\",\n      \"integrity\": \"sha512-LfxbHXdA/S+qyoTEA4EbhxGjrxx7WK2h6yb5K2v0UCOufUKX+VZaHbl3svlzZfv9sGseym/g3Ne4DpsgRULmqg==\",\n      \"dev\": true\n    },\n    \"emoji-regex\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz\",\n      \"integrity\": \"sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==\",\n      \"dev\": true\n    },\n    \"entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"dev\": true\n    },\n    \"errno\": {\n      \"version\": \"0.1.8\",\n      \"resolved\": \"https://registry.npmjs.org/errno/-/errno-0.1.8.tgz\",\n      \"integrity\": \"sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"requires\": {\n        \"prr\": \"~1.0.1\"\n      }\n    },\n    \"error-ex\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz\",\n      \"integrity\": \"sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-arrayish\": \"^0.2.1\"\n      }\n    },\n    \"es-abstract\": {\n      \"version\": \"1.21.2\",\n      \"resolved\": \"https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz\",\n      \"integrity\": \"sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"array-buffer-byte-length\": \"^1.0.0\",\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"es-set-tostringtag\": \"^2.0.1\",\n        \"es-to-primitive\": \"^1.2.1\",\n        \"function.prototype.name\": \"^1.1.5\",\n        \"get-intrinsic\": \"^1.2.0\",\n        \"get-symbol-description\": \"^1.0.0\",\n        \"globalthis\": \"^1.0.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has\": \"^1.0.3\",\n        \"has-property-descriptors\": \"^1.0.0\",\n        \"has-proto\": \"^1.0.1\",\n        \"has-symbols\": \"^1.0.3\",\n        \"internal-slot\": \"^1.0.5\",\n        \"is-array-buffer\": \"^3.0.2\",\n        \"is-callable\": \"^1.2.7\",\n        \"is-negative-zero\": \"^2.0.2\",\n        \"is-regex\": \"^1.1.4\",\n        \"is-shared-array-buffer\": \"^1.0.2\",\n        \"is-string\": \"^1.0.7\",\n        \"is-typed-array\": \"^1.1.10\",\n        \"is-weakref\": \"^1.0.2\",\n        \"object-inspect\": \"^1.12.3\",\n        \"object-keys\": \"^1.1.1\",\n        \"object.assign\": \"^4.1.4\",\n        \"regexp.prototype.flags\": \"^1.4.3\",\n        \"safe-regex-test\": \"^1.0.0\",\n        \"string.prototype.trim\": \"^1.2.7\",\n        \"string.prototype.trimend\": \"^1.0.6\",\n        \"string.prototype.trimstart\": \"^1.0.6\",\n        \"typed-array-length\": \"^1.0.4\",\n        \"unbox-primitive\": \"^1.0.2\",\n        \"which-typed-array\": \"^1.1.9\"\n      }\n    },\n    \"es-set-tostringtag\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz\",\n      \"integrity\": \"sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"get-intrinsic\": \"^1.1.3\",\n        \"has\": \"^1.0.3\",\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"es-shim-unscopables\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz\",\n      \"integrity\": \"sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has\": \"^1.0.3\"\n      }\n    },\n    \"es-to-primitive\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz\",\n      \"integrity\": \"sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-callable\": \"^1.1.4\",\n        \"is-date-object\": \"^1.0.1\",\n        \"is-symbol\": \"^1.0.2\"\n      }\n    },\n    \"esbuild\": {\n      \"version\": \"0.17.18\",\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz\",\n      \"integrity\": \"sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@esbuild/android-arm\": \"0.17.18\",\n        \"@esbuild/android-arm64\": \"0.17.18\",\n        \"@esbuild/android-x64\": \"0.17.18\",\n        \"@esbuild/darwin-arm64\": \"0.17.18\",\n        \"@esbuild/darwin-x64\": \"0.17.18\",\n        \"@esbuild/freebsd-arm64\": \"0.17.18\",\n        \"@esbuild/freebsd-x64\": \"0.17.18\",\n        \"@esbuild/linux-arm\": \"0.17.18\",\n        \"@esbuild/linux-arm64\": \"0.17.18\",\n        \"@esbuild/linux-ia32\": \"0.17.18\",\n        \"@esbuild/linux-loong64\": \"0.17.18\",\n        \"@esbuild/linux-mips64el\": \"0.17.18\",\n        \"@esbuild/linux-ppc64\": \"0.17.18\",\n        \"@esbuild/linux-riscv64\": \"0.17.18\",\n        \"@esbuild/linux-s390x\": \"0.17.18\",\n        \"@esbuild/linux-x64\": \"0.17.18\",\n        \"@esbuild/netbsd-x64\": \"0.17.18\",\n        \"@esbuild/openbsd-x64\": \"0.17.18\",\n        \"@esbuild/sunos-x64\": \"0.17.18\",\n        \"@esbuild/win32-arm64\": \"0.17.18\",\n        \"@esbuild/win32-ia32\": \"0.17.18\",\n        \"@esbuild/win32-x64\": \"0.17.18\"\n      }\n    },\n    \"escalade\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz\",\n      \"integrity\": \"sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==\",\n      \"dev\": true\n    },\n    \"escape-string-regexp\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz\",\n      \"integrity\": \"sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==\",\n      \"dev\": true\n    },\n    \"eslint\": {\n      \"version\": \"8.39.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz\",\n      \"integrity\": \"sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"@eslint-community/regexpp\": \"^4.4.0\",\n        \"@eslint/eslintrc\": \"^2.0.2\",\n        \"@eslint/js\": \"8.39.0\",\n        \"@humanwhocodes/config-array\": \"^0.11.8\",\n        \"@humanwhocodes/module-importer\": \"^1.0.1\",\n        \"@nodelib/fs.walk\": \"^1.2.8\",\n        \"ajv\": \"^6.10.0\",\n        \"chalk\": \"^4.0.0\",\n        \"cross-spawn\": \"^7.0.2\",\n        \"debug\": \"^4.3.2\",\n        \"doctrine\": \"^3.0.0\",\n        \"escape-string-regexp\": \"^4.0.0\",\n        \"eslint-scope\": \"^7.2.0\",\n        \"eslint-visitor-keys\": \"^3.4.0\",\n        \"espree\": \"^9.5.1\",\n        \"esquery\": \"^1.4.2\",\n        \"esutils\": \"^2.0.2\",\n        \"fast-deep-equal\": \"^3.1.3\",\n        \"file-entry-cache\": \"^6.0.1\",\n        \"find-up\": \"^5.0.0\",\n        \"glob-parent\": \"^6.0.2\",\n        \"globals\": \"^13.19.0\",\n        \"grapheme-splitter\": \"^1.0.4\",\n        \"ignore\": \"^5.2.0\",\n        \"import-fresh\": \"^3.0.0\",\n        \"imurmurhash\": \"^0.1.4\",\n        \"is-glob\": \"^4.0.0\",\n        \"is-path-inside\": \"^3.0.3\",\n        \"js-sdsl\": \"^4.1.4\",\n        \"js-yaml\": \"^4.1.0\",\n        \"json-stable-stringify-without-jsonify\": \"^1.0.1\",\n        \"levn\": \"^0.4.1\",\n        \"lodash.merge\": \"^4.6.2\",\n        \"minimatch\": \"^3.1.2\",\n        \"natural-compare\": \"^1.4.0\",\n        \"optionator\": \"^0.9.1\",\n        \"strip-ansi\": \"^6.0.1\",\n        \"strip-json-comments\": \"^3.1.0\",\n        \"text-table\": \"^0.2.0\"\n      },\n      \"dependencies\": {\n        \"ajv\": {\n          \"version\": \"6.12.6\",\n          \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz\",\n          \"integrity\": \"sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fast-deep-equal\": \"^3.1.1\",\n            \"fast-json-stable-stringify\": \"^2.0.0\",\n            \"json-schema-traverse\": \"^0.4.1\",\n            \"uri-js\": \"^4.2.2\"\n          }\n        },\n        \"eslint-scope\": {\n          \"version\": \"7.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz\",\n          \"integrity\": \"sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"esrecurse\": \"^4.3.0\",\n            \"estraverse\": \"^5.2.0\"\n          }\n        },\n        \"estraverse\": {\n          \"version\": \"5.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n          \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n          \"dev\": true\n        },\n        \"json-schema-traverse\": {\n          \"version\": \"0.4.1\",\n          \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz\",\n          \"integrity\": \"sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-import-resolver-node\": {\n      \"version\": \"0.3.7\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz\",\n      \"integrity\": \"sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"debug\": \"^3.2.7\",\n        \"is-core-module\": \"^2.11.0\",\n        \"resolve\": \"^1.22.1\"\n      },\n      \"dependencies\": {\n        \"debug\": {\n          \"version\": \"3.2.7\",\n          \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n          \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ms\": \"^2.1.1\"\n          }\n        }\n      }\n    },\n    \"eslint-module-utils\": {\n      \"version\": \"2.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz\",\n      \"integrity\": \"sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"debug\": \"^3.2.7\"\n      },\n      \"dependencies\": {\n        \"debug\": {\n          \"version\": \"3.2.7\",\n          \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n          \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ms\": \"^2.1.1\"\n          }\n        }\n      }\n    },\n    \"eslint-plugin-antfu\": {\n      \"version\": \"0.35.3\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-0.35.3.tgz\",\n      \"integrity\": \"sha512-90Xct24s2n3aQhuuFFcPLhF5E6lU5s225B0VXupSjvDTuF+CmSQQLQG6KcqcdpA8O6dMbeXB9zy3SJ4aO7lndw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/utils\": \"^5.53.0\"\n      }\n    },\n    \"eslint-plugin-es\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz\",\n      \"integrity\": \"sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-utils\": \"^2.0.0\",\n        \"regexpp\": \"^3.0.0\"\n      },\n      \"dependencies\": {\n        \"eslint-utils\": {\n          \"version\": \"2.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz\",\n          \"integrity\": \"sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"eslint-visitor-keys\": \"^1.1.0\"\n          }\n        },\n        \"eslint-visitor-keys\": {\n          \"version\": \"1.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz\",\n          \"integrity\": \"sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-plugin-eslint-comments\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz\",\n      \"integrity\": \"sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"escape-string-regexp\": \"^1.0.5\",\n        \"ignore\": \"^5.0.5\"\n      },\n      \"dependencies\": {\n        \"escape-string-regexp\": {\n          \"version\": \"1.0.5\",\n          \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n          \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-plugin-html\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz\",\n      \"integrity\": \"sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"htmlparser2\": \"^8.0.1\"\n      }\n    },\n    \"eslint-plugin-import\": {\n      \"version\": \"2.27.5\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz\",\n      \"integrity\": \"sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==\",\n      \"dev\": true,\n      \"requires\": {\n        \"array-includes\": \"^3.1.6\",\n        \"array.prototype.flat\": \"^1.3.1\",\n        \"array.prototype.flatmap\": \"^1.3.1\",\n        \"debug\": \"^3.2.7\",\n        \"doctrine\": \"^2.1.0\",\n        \"eslint-import-resolver-node\": \"^0.3.7\",\n        \"eslint-module-utils\": \"^2.7.4\",\n        \"has\": \"^1.0.3\",\n        \"is-core-module\": \"^2.11.0\",\n        \"is-glob\": \"^4.0.3\",\n        \"minimatch\": \"^3.1.2\",\n        \"object.values\": \"^1.1.6\",\n        \"resolve\": \"^1.22.1\",\n        \"semver\": \"^6.3.0\",\n        \"tsconfig-paths\": \"^3.14.1\"\n      },\n      \"dependencies\": {\n        \"debug\": {\n          \"version\": \"3.2.7\",\n          \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n          \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ms\": \"^2.1.1\"\n          }\n        },\n        \"doctrine\": {\n          \"version\": \"2.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz\",\n          \"integrity\": \"sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"esutils\": \"^2.0.2\"\n          }\n        },\n        \"semver\": {\n          \"version\": \"6.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.0.tgz\",\n          \"integrity\": \"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-plugin-jest\": {\n      \"version\": \"27.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz\",\n      \"integrity\": \"sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@typescript-eslint/utils\": \"^5.10.0\"\n      }\n    },\n    \"eslint-plugin-jsonc\": {\n      \"version\": \"2.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.7.0.tgz\",\n      \"integrity\": \"sha512-DZgC71h/hZ9t5k/OGAKOMdJCleg2neZLL7No+YYi2ZMroCN4X5huZdrLf1USbrc6UTHwYujd1EDwXHg1qJ6CYw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@eslint-community/eslint-utils\": \"^4.2.0\",\n        \"jsonc-eslint-parser\": \"^2.0.4\",\n        \"natural-compare\": \"^1.4.0\"\n      }\n    },\n    \"eslint-plugin-markdown\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.0.tgz\",\n      \"integrity\": \"sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"mdast-util-from-markdown\": \"^0.8.5\"\n      }\n    },\n    \"eslint-plugin-n\": {\n      \"version\": \"15.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz\",\n      \"integrity\": \"sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"builtins\": \"^5.0.1\",\n        \"eslint-plugin-es\": \"^4.1.0\",\n        \"eslint-utils\": \"^3.0.0\",\n        \"ignore\": \"^5.1.1\",\n        \"is-core-module\": \"^2.11.0\",\n        \"minimatch\": \"^3.1.2\",\n        \"resolve\": \"^1.22.1\",\n        \"semver\": \"^7.3.8\"\n      }\n    },\n    \"eslint-plugin-no-only-tests\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz\",\n      \"integrity\": \"sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==\",\n      \"dev\": true\n    },\n    \"eslint-plugin-promise\": {\n      \"version\": \"6.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz\",\n      \"integrity\": \"sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==\",\n      \"dev\": true,\n      \"requires\": {}\n    },\n    \"eslint-plugin-unicorn\": {\n      \"version\": \"45.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz\",\n      \"integrity\": \"sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/helper-validator-identifier\": \"^7.19.1\",\n        \"@eslint-community/eslint-utils\": \"^4.1.2\",\n        \"ci-info\": \"^3.6.1\",\n        \"clean-regexp\": \"^1.0.0\",\n        \"esquery\": \"^1.4.0\",\n        \"indent-string\": \"^4.0.0\",\n        \"is-builtin-module\": \"^3.2.0\",\n        \"jsesc\": \"^3.0.2\",\n        \"lodash\": \"^4.17.21\",\n        \"pluralize\": \"^8.0.0\",\n        \"read-pkg-up\": \"^7.0.1\",\n        \"regexp-tree\": \"^0.1.24\",\n        \"regjsparser\": \"^0.9.1\",\n        \"safe-regex\": \"^2.1.1\",\n        \"semver\": \"^7.3.8\",\n        \"strip-indent\": \"^3.0.0\"\n      }\n    },\n    \"eslint-plugin-unused-imports\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz\",\n      \"integrity\": \"sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-rule-composer\": \"^0.3.0\"\n      }\n    },\n    \"eslint-plugin-vue\": {\n      \"version\": \"9.11.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.0.tgz\",\n      \"integrity\": \"sha512-bBCJAZnkBV7ATH4Z1E7CvN3nmtS4H7QUU3UBxPdo8WohRU+yHjnQRALpTbxMVcz0e4Mx3IyxIdP5HYODMxK9cQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@eslint-community/eslint-utils\": \"^4.3.0\",\n        \"natural-compare\": \"^1.4.0\",\n        \"nth-check\": \"^2.0.1\",\n        \"postcss-selector-parser\": \"^6.0.9\",\n        \"semver\": \"^7.3.5\",\n        \"vue-eslint-parser\": \"^9.0.1\",\n        \"xml-name-validator\": \"^4.0.0\"\n      }\n    },\n    \"eslint-plugin-yml\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.5.0.tgz\",\n      \"integrity\": \"sha512-iygN054g+ZrnYmtOXMnT+sx9iDNXt89/m0+506cQHeG0+5jJN8hY5iOPQLd3yfd50AfK/mSasajBWruf1SoHpQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"debug\": \"^4.3.2\",\n        \"lodash\": \"^4.17.21\",\n        \"natural-compare\": \"^1.4.0\",\n        \"yaml-eslint-parser\": \"^1.1.0\"\n      }\n    },\n    \"eslint-rule-composer\": {\n      \"version\": \"0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz\",\n      \"integrity\": \"sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==\",\n      \"dev\": true\n    },\n    \"eslint-scope\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz\",\n      \"integrity\": \"sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"esrecurse\": \"^4.3.0\",\n        \"estraverse\": \"^4.1.1\"\n      }\n    },\n    \"eslint-utils\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz\",\n      \"integrity\": \"sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-visitor-keys\": \"^2.0.0\"\n      },\n      \"dependencies\": {\n        \"eslint-visitor-keys\": {\n          \"version\": \"2.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz\",\n          \"integrity\": \"sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-visitor-keys\": {\n      \"version\": \"3.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz\",\n      \"integrity\": \"sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==\",\n      \"dev\": true\n    },\n    \"espree\": {\n      \"version\": \"9.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/espree/-/espree-9.5.1.tgz\",\n      \"integrity\": \"sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"acorn\": \"^8.8.0\",\n        \"acorn-jsx\": \"^5.3.2\",\n        \"eslint-visitor-keys\": \"^3.4.0\"\n      }\n    },\n    \"esquery\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz\",\n      \"integrity\": \"sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"estraverse\": \"^5.1.0\"\n      },\n      \"dependencies\": {\n        \"estraverse\": {\n          \"version\": \"5.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n          \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"esrecurse\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz\",\n      \"integrity\": \"sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==\",\n      \"dev\": true,\n      \"requires\": {\n        \"estraverse\": \"^5.2.0\"\n      },\n      \"dependencies\": {\n        \"estraverse\": {\n          \"version\": \"5.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n          \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"estraverse\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz\",\n      \"integrity\": \"sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==\",\n      \"dev\": true\n    },\n    \"estree-walker\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz\",\n      \"integrity\": \"sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==\"\n    },\n    \"esutils\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz\",\n      \"integrity\": \"sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==\",\n      \"dev\": true\n    },\n    \"evtd\": {\n      \"version\": \"0.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/evtd/-/evtd-0.2.4.tgz\",\n      \"integrity\": \"sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==\"\n    },\n    \"execa\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/execa/-/execa-5.1.1.tgz\",\n      \"integrity\": \"sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"cross-spawn\": \"^7.0.3\",\n        \"get-stream\": \"^6.0.0\",\n        \"human-signals\": \"^2.1.0\",\n        \"is-stream\": \"^2.0.0\",\n        \"merge-stream\": \"^2.0.0\",\n        \"npm-run-path\": \"^4.0.1\",\n        \"onetime\": \"^5.1.2\",\n        \"signal-exit\": \"^3.0.3\",\n        \"strip-final-newline\": \"^2.0.0\"\n      }\n    },\n    \"fast-deep-equal\": {\n      \"version\": \"3.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz\",\n      \"integrity\": \"sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==\",\n      \"dev\": true\n    },\n    \"fast-glob\": {\n      \"version\": \"3.2.12\",\n      \"resolved\": \"https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz\",\n      \"integrity\": \"sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@nodelib/fs.stat\": \"^2.0.2\",\n        \"@nodelib/fs.walk\": \"^1.2.3\",\n        \"glob-parent\": \"^5.1.2\",\n        \"merge2\": \"^1.3.0\",\n        \"micromatch\": \"^4.0.4\"\n      },\n      \"dependencies\": {\n        \"glob-parent\": {\n          \"version\": \"5.1.2\",\n          \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz\",\n          \"integrity\": \"sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==\",\n          \"dev\": true,\n          \"requires\": {\n            \"is-glob\": \"^4.0.1\"\n          }\n        }\n      }\n    },\n    \"fast-json-stable-stringify\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz\",\n      \"integrity\": \"sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==\",\n      \"dev\": true\n    },\n    \"fast-levenshtein\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz\",\n      \"integrity\": \"sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==\",\n      \"dev\": true\n    },\n    \"fastq\": {\n      \"version\": \"1.15.0\",\n      \"resolved\": \"https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz\",\n      \"integrity\": \"sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"reusify\": \"^1.0.4\"\n      }\n    },\n    \"file-entry-cache\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz\",\n      \"integrity\": \"sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"flat-cache\": \"^3.0.4\"\n      }\n    },\n    \"filelist\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz\",\n      \"integrity\": \"sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"minimatch\": \"^5.0.1\"\n      },\n      \"dependencies\": {\n        \"brace-expansion\": {\n          \"version\": \"2.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n          \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"balanced-match\": \"^1.0.0\"\n          }\n        },\n        \"minimatch\": {\n          \"version\": \"5.1.6\",\n          \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz\",\n          \"integrity\": \"sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"brace-expansion\": \"^2.0.1\"\n          }\n        }\n      }\n    },\n    \"fill-range\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz\",\n      \"integrity\": \"sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"to-regex-range\": \"^5.0.1\"\n      }\n    },\n    \"find-up\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz\",\n      \"integrity\": \"sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==\",\n      \"dev\": true,\n      \"requires\": {\n        \"locate-path\": \"^6.0.0\",\n        \"path-exists\": \"^4.0.0\"\n      }\n    },\n    \"flat-cache\": {\n      \"version\": \"3.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz\",\n      \"integrity\": \"sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"flatted\": \"^3.1.0\",\n        \"rimraf\": \"^3.0.2\"\n      },\n      \"dependencies\": {\n        \"glob\": {\n          \"version\": \"7.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.2.3.tgz\",\n          \"integrity\": \"sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fs.realpath\": \"^1.0.0\",\n            \"inflight\": \"^1.0.4\",\n            \"inherits\": \"2\",\n            \"minimatch\": \"^3.1.1\",\n            \"once\": \"^1.3.0\",\n            \"path-is-absolute\": \"^1.0.0\"\n          }\n        },\n        \"rimraf\": {\n          \"version\": \"3.0.2\",\n          \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz\",\n          \"integrity\": \"sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"glob\": \"^7.1.3\"\n          }\n        }\n      }\n    },\n    \"flatted\": {\n      \"version\": \"3.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz\",\n      \"integrity\": \"sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==\",\n      \"dev\": true\n    },\n    \"follow-redirects\": {\n      \"version\": \"1.15.2\",\n      \"resolved\": \"https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz\",\n      \"integrity\": \"sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==\",\n      \"dev\": true\n    },\n    \"for-each\": {\n      \"version\": \"0.3.3\",\n      \"resolved\": \"https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz\",\n      \"integrity\": \"sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-callable\": \"^1.1.3\"\n      }\n    },\n    \"form-data\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz\",\n      \"integrity\": \"sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==\",\n      \"dev\": true,\n      \"requires\": {\n        \"asynckit\": \"^0.4.0\",\n        \"combined-stream\": \"^1.0.8\",\n        \"mime-types\": \"^2.1.12\"\n      }\n    },\n    \"fraction.js\": {\n      \"version\": \"4.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz\",\n      \"integrity\": \"sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==\",\n      \"dev\": true\n    },\n    \"fs-extra\": {\n      \"version\": \"11.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz\",\n      \"integrity\": \"sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      }\n    },\n    \"fs.realpath\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz\",\n      \"integrity\": \"sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==\",\n      \"dev\": true\n    },\n    \"fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"function-bind\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz\",\n      \"integrity\": \"sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==\",\n      \"dev\": true\n    },\n    \"function.prototype.name\": {\n      \"version\": \"1.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz\",\n      \"integrity\": \"sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.3\",\n        \"es-abstract\": \"^1.19.0\",\n        \"functions-have-names\": \"^1.2.2\"\n      }\n    },\n    \"functions-have-names\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz\",\n      \"integrity\": \"sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==\",\n      \"dev\": true\n    },\n    \"gensync\": {\n      \"version\": \"1.0.0-beta.2\",\n      \"resolved\": \"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz\",\n      \"integrity\": \"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==\",\n      \"dev\": true\n    },\n    \"get-caller-file\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz\",\n      \"integrity\": \"sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==\",\n      \"dev\": true\n    },\n    \"get-intrinsic\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz\",\n      \"integrity\": \"sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"function-bind\": \"^1.1.1\",\n        \"has\": \"^1.0.3\",\n        \"has-symbols\": \"^1.0.3\"\n      }\n    },\n    \"get-own-enumerable-property-symbols\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz\",\n      \"integrity\": \"sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==\",\n      \"dev\": true\n    },\n    \"get-stream\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz\",\n      \"integrity\": \"sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==\",\n      \"dev\": true\n    },\n    \"get-symbol-description\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz\",\n      \"integrity\": \"sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.1.1\"\n      }\n    },\n    \"git-raw-commits\": {\n      \"version\": \"2.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz\",\n      \"integrity\": \"sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"dargs\": \"^7.0.0\",\n        \"lodash\": \"^4.17.15\",\n        \"meow\": \"^8.0.0\",\n        \"split2\": \"^3.0.0\",\n        \"through2\": \"^4.0.0\"\n      }\n    },\n    \"glob\": {\n      \"version\": \"9.3.5\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-9.3.5.tgz\",\n      \"integrity\": \"sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"fs.realpath\": \"^1.0.0\",\n        \"minimatch\": \"^8.0.2\",\n        \"minipass\": \"^4.2.4\",\n        \"path-scurry\": \"^1.6.1\"\n      },\n      \"dependencies\": {\n        \"brace-expansion\": {\n          \"version\": \"2.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz\",\n          \"integrity\": \"sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"balanced-match\": \"^1.0.0\"\n          }\n        },\n        \"minimatch\": {\n          \"version\": \"8.0.4\",\n          \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz\",\n          \"integrity\": \"sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"brace-expansion\": \"^2.0.1\"\n          }\n        }\n      }\n    },\n    \"glob-parent\": {\n      \"version\": \"6.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz\",\n      \"integrity\": \"sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-glob\": \"^4.0.3\"\n      }\n    },\n    \"global-dirs\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz\",\n      \"integrity\": \"sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ini\": \"^1.3.4\"\n      }\n    },\n    \"globals\": {\n      \"version\": \"13.20.0\",\n      \"resolved\": \"https://registry.npmjs.org/globals/-/globals-13.20.0.tgz\",\n      \"integrity\": \"sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"type-fest\": \"^0.20.2\"\n      }\n    },\n    \"globalthis\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz\",\n      \"integrity\": \"sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"define-properties\": \"^1.1.3\"\n      }\n    },\n    \"globby\": {\n      \"version\": \"11.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/globby/-/globby-11.1.0.tgz\",\n      \"integrity\": \"sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"array-union\": \"^2.1.0\",\n        \"dir-glob\": \"^3.0.1\",\n        \"fast-glob\": \"^3.2.9\",\n        \"ignore\": \"^5.2.0\",\n        \"merge2\": \"^1.4.1\",\n        \"slash\": \"^3.0.0\"\n      }\n    },\n    \"gopd\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz\",\n      \"integrity\": \"sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"get-intrinsic\": \"^1.1.3\"\n      }\n    },\n    \"graceful-fs\": {\n      \"version\": \"4.2.11\",\n      \"resolved\": \"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz\",\n      \"integrity\": \"sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==\",\n      \"dev\": true\n    },\n    \"grapheme-splitter\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz\",\n      \"integrity\": \"sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==\",\n      \"dev\": true\n    },\n    \"hard-rejection\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz\",\n      \"integrity\": \"sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==\",\n      \"dev\": true\n    },\n    \"has\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/has/-/has-1.0.3.tgz\",\n      \"integrity\": \"sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"function-bind\": \"^1.1.1\"\n      }\n    },\n    \"has-bigints\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz\",\n      \"integrity\": \"sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==\",\n      \"dev\": true\n    },\n    \"has-flag\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz\",\n      \"integrity\": \"sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==\",\n      \"dev\": true\n    },\n    \"has-property-descriptors\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz\",\n      \"integrity\": \"sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"get-intrinsic\": \"^1.1.1\"\n      }\n    },\n    \"has-proto\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz\",\n      \"integrity\": \"sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==\",\n      \"dev\": true\n    },\n    \"has-symbols\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz\",\n      \"integrity\": \"sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==\",\n      \"dev\": true\n    },\n    \"has-tostringtag\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz\",\n      \"integrity\": \"sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-symbols\": \"^1.0.2\"\n      }\n    },\n    \"he\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/he/-/he-1.2.0.tgz\",\n      \"integrity\": \"sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==\",\n      \"dev\": true\n    },\n    \"highlight.js\": {\n      \"version\": \"11.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz\",\n      \"integrity\": \"sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==\"\n    },\n    \"hosted-git-info\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz\",\n      \"integrity\": \"sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"lru-cache\": \"^6.0.0\"\n      }\n    },\n    \"html2canvas\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz\",\n      \"integrity\": \"sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==\",\n      \"requires\": {\n        \"css-line-break\": \"^2.1.0\",\n        \"text-segmentation\": \"^1.0.3\"\n      }\n    },\n    \"htmlparser2\": {\n      \"version\": \"8.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz\",\n      \"integrity\": \"sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\",\n        \"entities\": \"^4.4.0\"\n      }\n    },\n    \"human-signals\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz\",\n      \"integrity\": \"sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==\",\n      \"dev\": true\n    },\n    \"husky\": {\n      \"version\": \"8.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/husky/-/husky-8.0.3.tgz\",\n      \"integrity\": \"sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==\",\n      \"dev\": true\n    },\n    \"iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"requires\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      }\n    },\n    \"idb\": {\n      \"version\": \"7.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/idb/-/idb-7.1.1.tgz\",\n      \"integrity\": \"sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==\",\n      \"dev\": true\n    },\n    \"ignore\": {\n      \"version\": \"5.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz\",\n      \"integrity\": \"sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==\",\n      \"dev\": true\n    },\n    \"image-size\": {\n      \"version\": \"0.5.5\",\n      \"resolved\": \"https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz\",\n      \"integrity\": \"sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"import-fresh\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz\",\n      \"integrity\": \"sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"parent-module\": \"^1.0.0\",\n        \"resolve-from\": \"^4.0.0\"\n      },\n      \"dependencies\": {\n        \"resolve-from\": {\n          \"version\": \"4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz\",\n          \"integrity\": \"sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"imurmurhash\": {\n      \"version\": \"0.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz\",\n      \"integrity\": \"sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==\",\n      \"dev\": true\n    },\n    \"indent-string\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz\",\n      \"integrity\": \"sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==\",\n      \"dev\": true\n    },\n    \"inflight\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz\",\n      \"integrity\": \"sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"once\": \"^1.3.0\",\n        \"wrappy\": \"1\"\n      }\n    },\n    \"inherits\": {\n      \"version\": \"2.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz\",\n      \"integrity\": \"sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==\",\n      \"dev\": true\n    },\n    \"ini\": {\n      \"version\": \"1.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/ini/-/ini-1.3.8.tgz\",\n      \"integrity\": \"sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==\",\n      \"dev\": true\n    },\n    \"internal-slot\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz\",\n      \"integrity\": \"sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"get-intrinsic\": \"^1.2.0\",\n        \"has\": \"^1.0.3\",\n        \"side-channel\": \"^1.0.4\"\n      }\n    },\n    \"is-alphabetical\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz\",\n      \"integrity\": \"sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==\",\n      \"dev\": true\n    },\n    \"is-alphanumerical\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz\",\n      \"integrity\": \"sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-alphabetical\": \"^1.0.0\",\n        \"is-decimal\": \"^1.0.0\"\n      }\n    },\n    \"is-array-buffer\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz\",\n      \"integrity\": \"sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.2.0\",\n        \"is-typed-array\": \"^1.1.10\"\n      }\n    },\n    \"is-arrayish\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz\",\n      \"integrity\": \"sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==\",\n      \"dev\": true\n    },\n    \"is-bigint\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz\",\n      \"integrity\": \"sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-bigints\": \"^1.0.1\"\n      }\n    },\n    \"is-binary-path\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz\",\n      \"integrity\": \"sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"binary-extensions\": \"^2.0.0\"\n      }\n    },\n    \"is-boolean-object\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz\",\n      \"integrity\": \"sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-builtin-module\": {\n      \"version\": \"3.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz\",\n      \"integrity\": \"sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"builtin-modules\": \"^3.3.0\"\n      }\n    },\n    \"is-callable\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz\",\n      \"integrity\": \"sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==\",\n      \"dev\": true\n    },\n    \"is-core-module\": {\n      \"version\": \"2.12.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz\",\n      \"integrity\": \"sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has\": \"^1.0.3\"\n      }\n    },\n    \"is-date-object\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz\",\n      \"integrity\": \"sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-decimal\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz\",\n      \"integrity\": \"sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==\",\n      \"dev\": true\n    },\n    \"is-extglob\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz\",\n      \"integrity\": \"sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==\",\n      \"dev\": true\n    },\n    \"is-fullwidth-code-point\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz\",\n      \"integrity\": \"sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==\",\n      \"dev\": true\n    },\n    \"is-glob\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz\",\n      \"integrity\": \"sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-extglob\": \"^2.1.1\"\n      }\n    },\n    \"is-hexadecimal\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz\",\n      \"integrity\": \"sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==\",\n      \"dev\": true\n    },\n    \"is-module\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz\",\n      \"integrity\": \"sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==\",\n      \"dev\": true\n    },\n    \"is-negative-zero\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz\",\n      \"integrity\": \"sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==\",\n      \"dev\": true\n    },\n    \"is-number\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz\",\n      \"integrity\": \"sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==\",\n      \"dev\": true\n    },\n    \"is-number-object\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz\",\n      \"integrity\": \"sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-obj\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz\",\n      \"integrity\": \"sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==\",\n      \"dev\": true\n    },\n    \"is-path-inside\": {\n      \"version\": \"3.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz\",\n      \"integrity\": \"sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==\",\n      \"dev\": true\n    },\n    \"is-plain-obj\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz\",\n      \"integrity\": \"sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==\",\n      \"dev\": true\n    },\n    \"is-regex\": {\n      \"version\": \"1.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz\",\n      \"integrity\": \"sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-regexp\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz\",\n      \"integrity\": \"sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==\",\n      \"dev\": true\n    },\n    \"is-shared-array-buffer\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz\",\n      \"integrity\": \"sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\"\n      }\n    },\n    \"is-stream\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz\",\n      \"integrity\": \"sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==\",\n      \"dev\": true\n    },\n    \"is-string\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz\",\n      \"integrity\": \"sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-symbol\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz\",\n      \"integrity\": \"sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-symbols\": \"^1.0.2\"\n      }\n    },\n    \"is-text-path\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz\",\n      \"integrity\": \"sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"text-extensions\": \"^1.0.0\"\n      }\n    },\n    \"is-typed-array\": {\n      \"version\": \"1.1.10\",\n      \"resolved\": \"https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz\",\n      \"integrity\": \"sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has-tostringtag\": \"^1.0.0\"\n      }\n    },\n    \"is-weakref\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz\",\n      \"integrity\": \"sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\"\n      }\n    },\n    \"is-what\": {\n      \"version\": \"3.14.1\",\n      \"resolved\": \"https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz\",\n      \"integrity\": \"sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==\",\n      \"dev\": true\n    },\n    \"isexe\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\",\n      \"integrity\": \"sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==\",\n      \"dev\": true\n    },\n    \"jake\": {\n      \"version\": \"10.8.5\",\n      \"resolved\": \"https://registry.npmjs.org/jake/-/jake-10.8.5.tgz\",\n      \"integrity\": \"sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"async\": \"^3.2.3\",\n        \"chalk\": \"^4.0.2\",\n        \"filelist\": \"^1.0.1\",\n        \"minimatch\": \"^3.0.4\"\n      }\n    },\n    \"jest-worker\": {\n      \"version\": \"26.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz\",\n      \"integrity\": \"sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/node\": \"*\",\n        \"merge-stream\": \"^2.0.0\",\n        \"supports-color\": \"^7.0.0\"\n      }\n    },\n    \"jiti\": {\n      \"version\": \"1.18.2\",\n      \"resolved\": \"https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz\",\n      \"integrity\": \"sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==\",\n      \"dev\": true\n    },\n    \"js-sdsl\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz\",\n      \"integrity\": \"sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==\",\n      \"dev\": true\n    },\n    \"js-tokens\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz\",\n      \"integrity\": \"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==\",\n      \"dev\": true\n    },\n    \"js-yaml\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz\",\n      \"integrity\": \"sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"argparse\": \"^2.0.1\"\n      }\n    },\n    \"jsesc\": {\n      \"version\": \"3.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz\",\n      \"integrity\": \"sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==\",\n      \"dev\": true\n    },\n    \"json-parse-better-errors\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz\",\n      \"integrity\": \"sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==\",\n      \"dev\": true\n    },\n    \"json-parse-even-better-errors\": {\n      \"version\": \"2.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz\",\n      \"integrity\": \"sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==\",\n      \"dev\": true\n    },\n    \"json-schema\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz\",\n      \"integrity\": \"sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==\",\n      \"dev\": true\n    },\n    \"json-schema-traverse\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz\",\n      \"integrity\": \"sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==\",\n      \"dev\": true\n    },\n    \"json-stable-stringify-without-jsonify\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz\",\n      \"integrity\": \"sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==\",\n      \"dev\": true\n    },\n    \"json5\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/json5/-/json5-1.0.2.tgz\",\n      \"integrity\": \"sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"minimist\": \"^1.2.0\"\n      }\n    },\n    \"jsonc-eslint-parser\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.2.0.tgz\",\n      \"integrity\": \"sha512-x5QjzBOORd+T2EjErIxJnkOEbLVEdD1ILEeBbIJt8Eq/zUn7P7M8qdnWiNVBK5f8oxnJpc6SBHOeeIEl/swPjg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"acorn\": \"^8.5.0\",\n        \"eslint-visitor-keys\": \"^3.0.0\",\n        \"espree\": \"^9.0.0\",\n        \"semver\": \"^7.3.5\"\n      }\n    },\n    \"jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"graceful-fs\": \"^4.1.6\",\n        \"universalify\": \"^2.0.0\"\n      }\n    },\n    \"jsonparse\": {\n      \"version\": \"1.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz\",\n      \"integrity\": \"sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==\",\n      \"dev\": true\n    },\n    \"jsonpointer\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz\",\n      \"integrity\": \"sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==\",\n      \"dev\": true\n    },\n    \"JSONStream\": {\n      \"version\": \"1.3.5\",\n      \"resolved\": \"https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz\",\n      \"integrity\": \"sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"jsonparse\": \"^1.2.0\",\n        \"through\": \">=2.2.7 <3\"\n      }\n    },\n    \"katex\": {\n      \"version\": \"0.16.6\",\n      \"resolved\": \"https://registry.npmjs.org/katex/-/katex-0.16.6.tgz\",\n      \"integrity\": \"sha512-XVB7X8jEogjJ+OY+a9JdE+VOk9i7znela0HP6WaDbpB4sUh8ghrG0Ccluu2MA2tcJbFAViBC9aVXus2UvkEr8A==\",\n      \"requires\": {\n        \"commander\": \"^8.3.0\"\n      }\n    },\n    \"kind-of\": {\n      \"version\": \"6.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz\",\n      \"integrity\": \"sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==\",\n      \"dev\": true\n    },\n    \"less\": {\n      \"version\": \"4.1.3\",\n      \"resolved\": \"https://registry.npmjs.org/less/-/less-4.1.3.tgz\",\n      \"integrity\": \"sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"copy-anything\": \"^2.0.1\",\n        \"errno\": \"^0.1.1\",\n        \"graceful-fs\": \"^4.1.2\",\n        \"image-size\": \"~0.5.0\",\n        \"make-dir\": \"^2.1.0\",\n        \"mime\": \"^1.4.1\",\n        \"needle\": \"^3.1.0\",\n        \"parse-node-version\": \"^1.0.1\",\n        \"source-map\": \"~0.6.0\",\n        \"tslib\": \"^2.3.0\"\n      }\n    },\n    \"leven\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/leven/-/leven-3.1.0.tgz\",\n      \"integrity\": \"sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==\",\n      \"dev\": true\n    },\n    \"levn\": {\n      \"version\": \"0.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/levn/-/levn-0.4.1.tgz\",\n      \"integrity\": \"sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"prelude-ls\": \"^1.2.1\",\n        \"type-check\": \"~0.4.0\"\n      }\n    },\n    \"lilconfig\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz\",\n      \"integrity\": \"sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==\",\n      \"dev\": true\n    },\n    \"lines-and-columns\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz\",\n      \"integrity\": \"sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==\",\n      \"dev\": true\n    },\n    \"linkify-it\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz\",\n      \"integrity\": \"sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==\",\n      \"requires\": {\n        \"uc.micro\": \"^1.0.1\"\n      }\n    },\n    \"lint-staged\": {\n      \"version\": \"13.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.1.tgz\",\n      \"integrity\": \"sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"chalk\": \"5.2.0\",\n        \"cli-truncate\": \"^3.1.0\",\n        \"commander\": \"^10.0.0\",\n        \"debug\": \"^4.3.4\",\n        \"execa\": \"^7.0.0\",\n        \"lilconfig\": \"2.1.0\",\n        \"listr2\": \"^5.0.7\",\n        \"micromatch\": \"^4.0.5\",\n        \"normalize-path\": \"^3.0.0\",\n        \"object-inspect\": \"^1.12.3\",\n        \"pidtree\": \"^0.6.0\",\n        \"string-argv\": \"^0.3.1\",\n        \"yaml\": \"^2.2.1\"\n      },\n      \"dependencies\": {\n        \"chalk\": {\n          \"version\": \"5.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz\",\n          \"integrity\": \"sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==\",\n          \"dev\": true\n        },\n        \"commander\": {\n          \"version\": \"10.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/commander/-/commander-10.0.1.tgz\",\n          \"integrity\": \"sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==\",\n          \"dev\": true\n        },\n        \"execa\": {\n          \"version\": \"7.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/execa/-/execa-7.1.1.tgz\",\n          \"integrity\": \"sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==\",\n          \"dev\": true,\n          \"requires\": {\n            \"cross-spawn\": \"^7.0.3\",\n            \"get-stream\": \"^6.0.1\",\n            \"human-signals\": \"^4.3.0\",\n            \"is-stream\": \"^3.0.0\",\n            \"merge-stream\": \"^2.0.0\",\n            \"npm-run-path\": \"^5.1.0\",\n            \"onetime\": \"^6.0.0\",\n            \"signal-exit\": \"^3.0.7\",\n            \"strip-final-newline\": \"^3.0.0\"\n          }\n        },\n        \"human-signals\": {\n          \"version\": \"4.3.1\",\n          \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz\",\n          \"integrity\": \"sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==\",\n          \"dev\": true\n        },\n        \"is-stream\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz\",\n          \"integrity\": \"sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==\",\n          \"dev\": true\n        },\n        \"mimic-fn\": {\n          \"version\": \"4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz\",\n          \"integrity\": \"sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==\",\n          \"dev\": true\n        },\n        \"npm-run-path\": {\n          \"version\": \"5.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz\",\n          \"integrity\": \"sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==\",\n          \"dev\": true,\n          \"requires\": {\n            \"path-key\": \"^4.0.0\"\n          }\n        },\n        \"onetime\": {\n          \"version\": \"6.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz\",\n          \"integrity\": \"sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"mimic-fn\": \"^4.0.0\"\n          }\n        },\n        \"path-key\": {\n          \"version\": \"4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz\",\n          \"integrity\": \"sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==\",\n          \"dev\": true\n        },\n        \"strip-final-newline\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz\",\n          \"integrity\": \"sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"listr2\": {\n      \"version\": \"5.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz\",\n      \"integrity\": \"sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"cli-truncate\": \"^2.1.0\",\n        \"colorette\": \"^2.0.19\",\n        \"log-update\": \"^4.0.0\",\n        \"p-map\": \"^4.0.0\",\n        \"rfdc\": \"^1.3.0\",\n        \"rxjs\": \"^7.8.0\",\n        \"through\": \"^2.3.8\",\n        \"wrap-ansi\": \"^7.0.0\"\n      },\n      \"dependencies\": {\n        \"cli-truncate\": {\n          \"version\": \"2.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz\",\n          \"integrity\": \"sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"slice-ansi\": \"^3.0.0\",\n            \"string-width\": \"^4.2.0\"\n          }\n        },\n        \"emoji-regex\": {\n          \"version\": \"8.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n          \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n          \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n          \"dev\": true\n        },\n        \"slice-ansi\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz\",\n          \"integrity\": \"sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-styles\": \"^4.0.0\",\n            \"astral-regex\": \"^2.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\"\n          }\n        },\n        \"string-width\": {\n          \"version\": \"4.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n          \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"emoji-regex\": \"^8.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\",\n            \"strip-ansi\": \"^6.0.1\"\n          }\n        }\n      }\n    },\n    \"load-json-file\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz\",\n      \"integrity\": \"sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"graceful-fs\": \"^4.1.2\",\n        \"parse-json\": \"^4.0.0\",\n        \"pify\": \"^3.0.0\",\n        \"strip-bom\": \"^3.0.0\"\n      },\n      \"dependencies\": {\n        \"parse-json\": {\n          \"version\": \"4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz\",\n          \"integrity\": \"sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"error-ex\": \"^1.3.1\",\n            \"json-parse-better-errors\": \"^1.0.1\"\n          }\n        },\n        \"pify\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/pify/-/pify-3.0.0.tgz\",\n          \"integrity\": \"sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"local-pkg\": {\n      \"version\": \"0.4.3\",\n      \"resolved\": \"https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz\",\n      \"integrity\": \"sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==\",\n      \"dev\": true\n    },\n    \"locate-path\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz\",\n      \"integrity\": \"sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"p-locate\": \"^5.0.0\"\n      }\n    },\n    \"lodash\": {\n      \"version\": \"4.17.21\",\n      \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz\",\n      \"integrity\": \"sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==\"\n    },\n    \"lodash-es\": {\n      \"version\": \"4.17.21\",\n      \"resolved\": \"https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz\",\n      \"integrity\": \"sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==\"\n    },\n    \"lodash.camelcase\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz\",\n      \"integrity\": \"sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==\",\n      \"dev\": true\n    },\n    \"lodash.debounce\": {\n      \"version\": \"4.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz\",\n      \"integrity\": \"sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==\",\n      \"dev\": true\n    },\n    \"lodash.isfunction\": {\n      \"version\": \"3.0.9\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz\",\n      \"integrity\": \"sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==\",\n      \"dev\": true\n    },\n    \"lodash.isplainobject\": {\n      \"version\": \"4.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz\",\n      \"integrity\": \"sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==\",\n      \"dev\": true\n    },\n    \"lodash.kebabcase\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz\",\n      \"integrity\": \"sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==\",\n      \"dev\": true\n    },\n    \"lodash.merge\": {\n      \"version\": \"4.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz\",\n      \"integrity\": \"sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==\",\n      \"dev\": true\n    },\n    \"lodash.mergewith\": {\n      \"version\": \"4.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz\",\n      \"integrity\": \"sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==\",\n      \"dev\": true\n    },\n    \"lodash.snakecase\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz\",\n      \"integrity\": \"sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==\",\n      \"dev\": true\n    },\n    \"lodash.sortby\": {\n      \"version\": \"4.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz\",\n      \"integrity\": \"sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==\",\n      \"dev\": true\n    },\n    \"lodash.startcase\": {\n      \"version\": \"4.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz\",\n      \"integrity\": \"sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==\",\n      \"dev\": true\n    },\n    \"lodash.uniq\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz\",\n      \"integrity\": \"sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==\",\n      \"dev\": true\n    },\n    \"lodash.upperfirst\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz\",\n      \"integrity\": \"sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==\",\n      \"dev\": true\n    },\n    \"log-update\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz\",\n      \"integrity\": \"sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-escapes\": \"^4.3.0\",\n        \"cli-cursor\": \"^3.1.0\",\n        \"slice-ansi\": \"^4.0.0\",\n        \"wrap-ansi\": \"^6.2.0\"\n      },\n      \"dependencies\": {\n        \"emoji-regex\": {\n          \"version\": \"8.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n          \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n          \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n          \"dev\": true\n        },\n        \"slice-ansi\": {\n          \"version\": \"4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz\",\n          \"integrity\": \"sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-styles\": \"^4.0.0\",\n            \"astral-regex\": \"^2.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\"\n          }\n        },\n        \"string-width\": {\n          \"version\": \"4.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n          \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"emoji-regex\": \"^8.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\",\n            \"strip-ansi\": \"^6.0.1\"\n          }\n        },\n        \"wrap-ansi\": {\n          \"version\": \"6.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz\",\n          \"integrity\": \"sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-styles\": \"^4.0.0\",\n            \"string-width\": \"^4.1.0\",\n            \"strip-ansi\": \"^6.0.0\"\n          }\n        }\n      }\n    },\n    \"lru-cache\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz\",\n      \"integrity\": \"sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"yallist\": \"^4.0.0\"\n      }\n    },\n    \"magic-string\": {\n      \"version\": \"0.27.0\",\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz\",\n      \"integrity\": \"sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/sourcemap-codec\": \"^1.4.13\"\n      }\n    },\n    \"make-dir\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz\",\n      \"integrity\": \"sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"requires\": {\n        \"pify\": \"^4.0.1\",\n        \"semver\": \"^5.6.0\"\n      },\n      \"dependencies\": {\n        \"semver\": {\n          \"version\": \"5.7.1\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n          \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n          \"dev\": true,\n          \"optional\": true\n        }\n      }\n    },\n    \"make-error\": {\n      \"version\": \"1.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz\",\n      \"integrity\": \"sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==\",\n      \"dev\": true\n    },\n    \"map-obj\": {\n      \"version\": \"4.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz\",\n      \"integrity\": \"sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==\",\n      \"dev\": true\n    },\n    \"markdown-it\": {\n      \"version\": \"13.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz\",\n      \"integrity\": \"sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==\",\n      \"requires\": {\n        \"argparse\": \"^2.0.1\",\n        \"entities\": \"~3.0.1\",\n        \"linkify-it\": \"^4.0.1\",\n        \"mdurl\": \"^1.0.1\",\n        \"uc.micro\": \"^1.0.5\"\n      },\n      \"dependencies\": {\n        \"entities\": {\n          \"version\": \"3.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/entities/-/entities-3.0.1.tgz\",\n          \"integrity\": \"sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==\"\n        }\n      }\n    },\n    \"markdown-it-link-attributes\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz\",\n      \"integrity\": \"sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ==\",\n      \"dev\": true\n    },\n    \"mdast-util-from-markdown\": {\n      \"version\": \"0.8.5\",\n      \"resolved\": \"https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz\",\n      \"integrity\": \"sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/mdast\": \"^3.0.0\",\n        \"mdast-util-to-string\": \"^2.0.0\",\n        \"micromark\": \"~2.11.0\",\n        \"parse-entities\": \"^2.0.0\",\n        \"unist-util-stringify-position\": \"^2.0.0\"\n      }\n    },\n    \"mdast-util-to-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==\",\n      \"dev\": true\n    },\n    \"mdurl\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz\",\n      \"integrity\": \"sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==\"\n    },\n    \"memorystream\": {\n      \"version\": \"0.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz\",\n      \"integrity\": \"sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==\",\n      \"dev\": true\n    },\n    \"meow\": {\n      \"version\": \"8.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/meow/-/meow-8.1.2.tgz\",\n      \"integrity\": \"sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/minimist\": \"^1.2.0\",\n        \"camelcase-keys\": \"^6.2.2\",\n        \"decamelize-keys\": \"^1.1.0\",\n        \"hard-rejection\": \"^2.1.0\",\n        \"minimist-options\": \"4.1.0\",\n        \"normalize-package-data\": \"^3.0.0\",\n        \"read-pkg-up\": \"^7.0.1\",\n        \"redent\": \"^3.0.0\",\n        \"trim-newlines\": \"^3.0.0\",\n        \"type-fest\": \"^0.18.0\",\n        \"yargs-parser\": \"^20.2.3\"\n      },\n      \"dependencies\": {\n        \"type-fest\": {\n          \"version\": \"0.18.1\",\n          \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz\",\n          \"integrity\": \"sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"merge-stream\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz\",\n      \"integrity\": \"sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==\",\n      \"dev\": true\n    },\n    \"merge2\": {\n      \"version\": \"1.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz\",\n      \"integrity\": \"sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==\",\n      \"dev\": true\n    },\n    \"micromark\": {\n      \"version\": \"2.11.4\",\n      \"resolved\": \"https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz\",\n      \"integrity\": \"sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"debug\": \"^4.0.0\",\n        \"parse-entities\": \"^2.0.0\"\n      }\n    },\n    \"micromatch\": {\n      \"version\": \"4.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz\",\n      \"integrity\": \"sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"braces\": \"^3.0.2\",\n        \"picomatch\": \"^2.3.1\"\n      }\n    },\n    \"mime\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime/-/mime-1.6.0.tgz\",\n      \"integrity\": \"sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"mime-db\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz\",\n      \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\",\n      \"dev\": true\n    },\n    \"mime-types\": {\n      \"version\": \"2.1.35\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz\",\n      \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"mime-db\": \"1.52.0\"\n      }\n    },\n    \"mimic-fn\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz\",\n      \"integrity\": \"sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==\",\n      \"dev\": true\n    },\n    \"min-indent\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz\",\n      \"integrity\": \"sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==\",\n      \"dev\": true\n    },\n    \"minimatch\": {\n      \"version\": \"3.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz\",\n      \"integrity\": \"sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"brace-expansion\": \"^1.1.7\"\n      }\n    },\n    \"minimist\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz\",\n      \"integrity\": \"sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==\",\n      \"dev\": true\n    },\n    \"minimist-options\": {\n      \"version\": \"4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz\",\n      \"integrity\": \"sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"arrify\": \"^1.0.1\",\n        \"is-plain-obj\": \"^1.1.0\",\n        \"kind-of\": \"^6.0.3\"\n      }\n    },\n    \"minipass\": {\n      \"version\": \"4.2.8\",\n      \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz\",\n      \"integrity\": \"sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==\",\n      \"dev\": true\n    },\n    \"ms\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.2.tgz\",\n      \"integrity\": \"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==\",\n      \"dev\": true\n    },\n    \"muggle-string\": {\n      \"version\": \"0.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/muggle-string/-/muggle-string-0.2.2.tgz\",\n      \"integrity\": \"sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==\",\n      \"dev\": true\n    },\n    \"mz\": {\n      \"version\": \"2.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/mz/-/mz-2.7.0.tgz\",\n      \"integrity\": \"sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"any-promise\": \"^1.0.0\",\n        \"object-assign\": \"^4.0.1\",\n        \"thenify-all\": \"^1.0.0\"\n      }\n    },\n    \"naive-ui\": {\n      \"version\": \"2.34.3\",\n      \"resolved\": \"https://registry.npmjs.org/naive-ui/-/naive-ui-2.34.3.tgz\",\n      \"integrity\": \"sha512-fUMr0dzb/iGsOTWgoblPVobY5X5dihQ1eam5dA+H74oyLYAvgX4pL96xQFPBLIYqvyRFBAsN85kHN5pLqdtpxA==\",\n      \"requires\": {\n        \"@css-render/plugin-bem\": \"^0.15.10\",\n        \"@css-render/vue3-ssr\": \"^0.15.10\",\n        \"@types/katex\": \"^0.14.0\",\n        \"@types/lodash\": \"^4.14.181\",\n        \"@types/lodash-es\": \"^4.17.6\",\n        \"async-validator\": \"^4.0.7\",\n        \"css-render\": \"^0.15.10\",\n        \"date-fns\": \"^2.28.0\",\n        \"date-fns-tz\": \"^1.3.3\",\n        \"evtd\": \"^0.2.4\",\n        \"highlight.js\": \"^11.5.0\",\n        \"lodash\": \"^4.17.21\",\n        \"lodash-es\": \"^4.17.21\",\n        \"seemly\": \"^0.3.6\",\n        \"treemate\": \"^0.3.11\",\n        \"vdirs\": \"^0.1.8\",\n        \"vooks\": \"^0.2.12\",\n        \"vueuc\": \"^0.4.47\"\n      },\n      \"dependencies\": {\n        \"@types/katex\": {\n          \"version\": \"0.14.0\",\n          \"resolved\": \"https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz\",\n          \"integrity\": \"sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==\"\n        }\n      }\n    },\n    \"nanoid\": {\n      \"version\": \"3.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz\",\n      \"integrity\": \"sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==\"\n    },\n    \"natural-compare\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz\",\n      \"integrity\": \"sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==\",\n      \"dev\": true\n    },\n    \"natural-compare-lite\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz\",\n      \"integrity\": \"sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==\",\n      \"dev\": true\n    },\n    \"needle\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/needle/-/needle-3.2.0.tgz\",\n      \"integrity\": \"sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==\",\n      \"dev\": true,\n      \"optional\": true,\n      \"requires\": {\n        \"debug\": \"^3.2.6\",\n        \"iconv-lite\": \"^0.6.3\",\n        \"sax\": \"^1.2.4\"\n      },\n      \"dependencies\": {\n        \"debug\": {\n          \"version\": \"3.2.7\",\n          \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.2.7.tgz\",\n          \"integrity\": \"sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==\",\n          \"dev\": true,\n          \"optional\": true,\n          \"requires\": {\n            \"ms\": \"^2.1.1\"\n          }\n        }\n      }\n    },\n    \"nice-try\": {\n      \"version\": \"1.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz\",\n      \"integrity\": \"sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==\",\n      \"dev\": true\n    },\n    \"node-releases\": {\n      \"version\": \"2.0.10\",\n      \"resolved\": \"https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz\",\n      \"integrity\": \"sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==\",\n      \"dev\": true\n    },\n    \"normalize-package-data\": {\n      \"version\": \"3.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz\",\n      \"integrity\": \"sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"hosted-git-info\": \"^4.0.1\",\n        \"is-core-module\": \"^2.5.0\",\n        \"semver\": \"^7.3.4\",\n        \"validate-npm-package-license\": \"^3.0.1\"\n      }\n    },\n    \"normalize-path\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz\",\n      \"integrity\": \"sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==\",\n      \"dev\": true\n    },\n    \"normalize-range\": {\n      \"version\": \"0.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz\",\n      \"integrity\": \"sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==\",\n      \"dev\": true\n    },\n    \"npm-run-all\": {\n      \"version\": \"4.1.5\",\n      \"resolved\": \"https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz\",\n      \"integrity\": \"sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-styles\": \"^3.2.1\",\n        \"chalk\": \"^2.4.1\",\n        \"cross-spawn\": \"^6.0.5\",\n        \"memorystream\": \"^0.3.1\",\n        \"minimatch\": \"^3.0.4\",\n        \"pidtree\": \"^0.3.0\",\n        \"read-pkg\": \"^3.0.0\",\n        \"shell-quote\": \"^1.6.1\",\n        \"string.prototype.padend\": \"^3.0.0\"\n      },\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"3.2.1\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz\",\n          \"integrity\": \"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"color-convert\": \"^1.9.0\"\n          }\n        },\n        \"chalk\": {\n          \"version\": \"2.4.2\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz\",\n          \"integrity\": \"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-styles\": \"^3.2.1\",\n            \"escape-string-regexp\": \"^1.0.5\",\n            \"supports-color\": \"^5.3.0\"\n          }\n        },\n        \"color-convert\": {\n          \"version\": \"1.9.3\",\n          \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz\",\n          \"integrity\": \"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"color-name\": \"1.1.3\"\n          }\n        },\n        \"color-name\": {\n          \"version\": \"1.1.3\",\n          \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz\",\n          \"integrity\": \"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==\",\n          \"dev\": true\n        },\n        \"cross-spawn\": {\n          \"version\": \"6.0.5\",\n          \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz\",\n          \"integrity\": \"sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"nice-try\": \"^1.0.4\",\n            \"path-key\": \"^2.0.1\",\n            \"semver\": \"^5.5.0\",\n            \"shebang-command\": \"^1.2.0\",\n            \"which\": \"^1.2.9\"\n          }\n        },\n        \"escape-string-regexp\": {\n          \"version\": \"1.0.5\",\n          \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\",\n          \"integrity\": \"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==\",\n          \"dev\": true\n        },\n        \"has-flag\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz\",\n          \"integrity\": \"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==\",\n          \"dev\": true\n        },\n        \"path-key\": {\n          \"version\": \"2.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz\",\n          \"integrity\": \"sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==\",\n          \"dev\": true\n        },\n        \"pidtree\": {\n          \"version\": \"0.3.1\",\n          \"resolved\": \"https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz\",\n          \"integrity\": \"sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==\",\n          \"dev\": true\n        },\n        \"semver\": {\n          \"version\": \"5.7.1\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n          \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n          \"dev\": true\n        },\n        \"shebang-command\": {\n          \"version\": \"1.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz\",\n          \"integrity\": \"sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"shebang-regex\": \"^1.0.0\"\n          }\n        },\n        \"shebang-regex\": {\n          \"version\": \"1.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz\",\n          \"integrity\": \"sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"5.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz\",\n          \"integrity\": \"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==\",\n          \"dev\": true,\n          \"requires\": {\n            \"has-flag\": \"^3.0.0\"\n          }\n        },\n        \"which\": {\n          \"version\": \"1.3.1\",\n          \"resolved\": \"https://registry.npmjs.org/which/-/which-1.3.1.tgz\",\n          \"integrity\": \"sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"isexe\": \"^2.0.0\"\n          }\n        }\n      }\n    },\n    \"npm-run-path\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz\",\n      \"integrity\": \"sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"path-key\": \"^3.0.0\"\n      }\n    },\n    \"nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"boolbase\": \"^1.0.0\"\n      }\n    },\n    \"object-assign\": {\n      \"version\": \"4.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz\",\n      \"integrity\": \"sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==\",\n      \"dev\": true\n    },\n    \"object-hash\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz\",\n      \"integrity\": \"sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==\",\n      \"dev\": true\n    },\n    \"object-inspect\": {\n      \"version\": \"1.12.3\",\n      \"resolved\": \"https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz\",\n      \"integrity\": \"sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==\",\n      \"dev\": true\n    },\n    \"object-keys\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz\",\n      \"integrity\": \"sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==\",\n      \"dev\": true\n    },\n    \"object.assign\": {\n      \"version\": \"4.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz\",\n      \"integrity\": \"sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"has-symbols\": \"^1.0.3\",\n        \"object-keys\": \"^1.1.1\"\n      }\n    },\n    \"object.values\": {\n      \"version\": \"1.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz\",\n      \"integrity\": \"sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      }\n    },\n    \"once\": {\n      \"version\": \"1.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/once/-/once-1.4.0.tgz\",\n      \"integrity\": \"sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"wrappy\": \"1\"\n      }\n    },\n    \"onetime\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz\",\n      \"integrity\": \"sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"mimic-fn\": \"^2.1.0\"\n      }\n    },\n    \"optionator\": {\n      \"version\": \"0.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz\",\n      \"integrity\": \"sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"deep-is\": \"^0.1.3\",\n        \"fast-levenshtein\": \"^2.0.6\",\n        \"levn\": \"^0.4.1\",\n        \"prelude-ls\": \"^1.2.1\",\n        \"type-check\": \"^0.4.0\",\n        \"word-wrap\": \"^1.2.3\"\n      }\n    },\n    \"p-limit\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz\",\n      \"integrity\": \"sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"yocto-queue\": \"^0.1.0\"\n      }\n    },\n    \"p-locate\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz\",\n      \"integrity\": \"sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"p-limit\": \"^3.0.2\"\n      }\n    },\n    \"p-map\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz\",\n      \"integrity\": \"sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"aggregate-error\": \"^3.0.0\"\n      }\n    },\n    \"p-try\": {\n      \"version\": \"2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz\",\n      \"integrity\": \"sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==\",\n      \"dev\": true\n    },\n    \"parent-module\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz\",\n      \"integrity\": \"sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"callsites\": \"^3.0.0\"\n      }\n    },\n    \"parse-entities\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz\",\n      \"integrity\": \"sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"character-entities\": \"^1.0.0\",\n        \"character-entities-legacy\": \"^1.0.0\",\n        \"character-reference-invalid\": \"^1.0.0\",\n        \"is-alphanumerical\": \"^1.0.0\",\n        \"is-decimal\": \"^1.0.0\",\n        \"is-hexadecimal\": \"^1.0.0\"\n      }\n    },\n    \"parse-json\": {\n      \"version\": \"5.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz\",\n      \"integrity\": \"sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/code-frame\": \"^7.0.0\",\n        \"error-ex\": \"^1.3.1\",\n        \"json-parse-even-better-errors\": \"^2.3.0\",\n        \"lines-and-columns\": \"^1.1.6\"\n      }\n    },\n    \"parse-node-version\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz\",\n      \"integrity\": \"sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==\",\n      \"dev\": true\n    },\n    \"path-exists\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz\",\n      \"integrity\": \"sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==\",\n      \"dev\": true\n    },\n    \"path-is-absolute\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz\",\n      \"integrity\": \"sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==\",\n      \"dev\": true\n    },\n    \"path-key\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz\",\n      \"integrity\": \"sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==\",\n      \"dev\": true\n    },\n    \"path-parse\": {\n      \"version\": \"1.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz\",\n      \"integrity\": \"sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==\",\n      \"dev\": true\n    },\n    \"path-scurry\": {\n      \"version\": \"1.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz\",\n      \"integrity\": \"sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"lru-cache\": \"^9.0.0\",\n        \"minipass\": \"^5.0.0\"\n      },\n      \"dependencies\": {\n        \"lru-cache\": {\n          \"version\": \"9.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz\",\n          \"integrity\": \"sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==\",\n          \"dev\": true\n        },\n        \"minipass\": {\n          \"version\": \"5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz\",\n          \"integrity\": \"sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"path-type\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz\",\n      \"integrity\": \"sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==\",\n      \"dev\": true\n    },\n    \"picocolors\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz\",\n      \"integrity\": \"sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==\"\n    },\n    \"picomatch\": {\n      \"version\": \"2.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz\",\n      \"integrity\": \"sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==\",\n      \"dev\": true\n    },\n    \"pidtree\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz\",\n      \"integrity\": \"sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==\",\n      \"dev\": true\n    },\n    \"pify\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-4.0.1.tgz\",\n      \"integrity\": \"sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"pinia\": {\n      \"version\": \"2.0.35\",\n      \"resolved\": \"https://registry.npmjs.org/pinia/-/pinia-2.0.35.tgz\",\n      \"integrity\": \"sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==\",\n      \"requires\": {\n        \"@vue/devtools-api\": \"^6.5.0\",\n        \"vue-demi\": \"*\"\n      },\n      \"dependencies\": {\n        \"vue-demi\": {\n          \"version\": \"0.14.0\",\n          \"resolved\": \"https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz\",\n          \"integrity\": \"sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==\",\n          \"requires\": {}\n        }\n      }\n    },\n    \"pirates\": {\n      \"version\": \"4.0.5\",\n      \"resolved\": \"https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz\",\n      \"integrity\": \"sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==\",\n      \"dev\": true\n    },\n    \"pluralize\": {\n      \"version\": \"8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz\",\n      \"integrity\": \"sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==\",\n      \"dev\": true\n    },\n    \"postcss\": {\n      \"version\": \"8.4.23\",\n      \"resolved\": \"https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz\",\n      \"integrity\": \"sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==\",\n      \"requires\": {\n        \"nanoid\": \"^3.3.6\",\n        \"picocolors\": \"^1.0.0\",\n        \"source-map-js\": \"^1.0.2\"\n      }\n    },\n    \"postcss-import\": {\n      \"version\": \"14.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz\",\n      \"integrity\": \"sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"postcss-value-parser\": \"^4.0.0\",\n        \"read-cache\": \"^1.0.0\",\n        \"resolve\": \"^1.1.7\"\n      }\n    },\n    \"postcss-js\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz\",\n      \"integrity\": \"sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"camelcase-css\": \"^2.0.1\"\n      }\n    },\n    \"postcss-load-config\": {\n      \"version\": \"3.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz\",\n      \"integrity\": \"sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"lilconfig\": \"^2.0.5\",\n        \"yaml\": \"^1.10.2\"\n      },\n      \"dependencies\": {\n        \"yaml\": {\n          \"version\": \"1.10.2\",\n          \"resolved\": \"https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz\",\n          \"integrity\": \"sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"postcss-nested\": {\n      \"version\": \"6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz\",\n      \"integrity\": \"sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"postcss-selector-parser\": \"^6.0.10\"\n      }\n    },\n    \"postcss-selector-parser\": {\n      \"version\": \"6.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz\",\n      \"integrity\": \"sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"cssesc\": \"^3.0.0\",\n        \"util-deprecate\": \"^1.0.2\"\n      }\n    },\n    \"postcss-value-parser\": {\n      \"version\": \"4.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz\",\n      \"integrity\": \"sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==\",\n      \"dev\": true\n    },\n    \"prelude-ls\": {\n      \"version\": \"1.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz\",\n      \"integrity\": \"sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==\",\n      \"dev\": true\n    },\n    \"pretty-bytes\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.0.tgz\",\n      \"integrity\": \"sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==\",\n      \"dev\": true\n    },\n    \"proxy-from-env\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz\",\n      \"integrity\": \"sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==\",\n      \"dev\": true\n    },\n    \"prr\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/prr/-/prr-1.0.1.tgz\",\n      \"integrity\": \"sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"punycode\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz\",\n      \"integrity\": \"sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==\",\n      \"dev\": true\n    },\n    \"q\": {\n      \"version\": \"1.5.1\",\n      \"resolved\": \"https://registry.npmjs.org/q/-/q-1.5.1.tgz\",\n      \"integrity\": \"sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==\",\n      \"dev\": true\n    },\n    \"queue-microtask\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz\",\n      \"integrity\": \"sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==\",\n      \"dev\": true\n    },\n    \"quick-lru\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz\",\n      \"integrity\": \"sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==\",\n      \"dev\": true\n    },\n    \"randombytes\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz\",\n      \"integrity\": \"sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"safe-buffer\": \"^5.1.0\"\n      }\n    },\n    \"read-cache\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz\",\n      \"integrity\": \"sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"pify\": \"^2.3.0\"\n      },\n      \"dependencies\": {\n        \"pify\": {\n          \"version\": \"2.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/pify/-/pify-2.3.0.tgz\",\n          \"integrity\": \"sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"read-pkg\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz\",\n      \"integrity\": \"sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"load-json-file\": \"^4.0.0\",\n        \"normalize-package-data\": \"^2.3.2\",\n        \"path-type\": \"^3.0.0\"\n      },\n      \"dependencies\": {\n        \"hosted-git-info\": {\n          \"version\": \"2.8.9\",\n          \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz\",\n          \"integrity\": \"sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==\",\n          \"dev\": true\n        },\n        \"normalize-package-data\": {\n          \"version\": \"2.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz\",\n          \"integrity\": \"sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"hosted-git-info\": \"^2.1.4\",\n            \"resolve\": \"^1.10.0\",\n            \"semver\": \"2 || 3 || 4 || 5\",\n            \"validate-npm-package-license\": \"^3.0.1\"\n          }\n        },\n        \"path-type\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz\",\n          \"integrity\": \"sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"pify\": \"^3.0.0\"\n          }\n        },\n        \"pify\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/pify/-/pify-3.0.0.tgz\",\n          \"integrity\": \"sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==\",\n          \"dev\": true\n        },\n        \"semver\": {\n          \"version\": \"5.7.1\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n          \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"read-pkg-up\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz\",\n      \"integrity\": \"sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"find-up\": \"^4.1.0\",\n        \"read-pkg\": \"^5.2.0\",\n        \"type-fest\": \"^0.8.1\"\n      },\n      \"dependencies\": {\n        \"find-up\": {\n          \"version\": \"4.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz\",\n          \"integrity\": \"sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"locate-path\": \"^5.0.0\",\n            \"path-exists\": \"^4.0.0\"\n          }\n        },\n        \"hosted-git-info\": {\n          \"version\": \"2.8.9\",\n          \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz\",\n          \"integrity\": \"sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==\",\n          \"dev\": true\n        },\n        \"locate-path\": {\n          \"version\": \"5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz\",\n          \"integrity\": \"sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"p-locate\": \"^4.1.0\"\n          }\n        },\n        \"normalize-package-data\": {\n          \"version\": \"2.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz\",\n          \"integrity\": \"sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"hosted-git-info\": \"^2.1.4\",\n            \"resolve\": \"^1.10.0\",\n            \"semver\": \"2 || 3 || 4 || 5\",\n            \"validate-npm-package-license\": \"^3.0.1\"\n          }\n        },\n        \"p-limit\": {\n          \"version\": \"2.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz\",\n          \"integrity\": \"sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==\",\n          \"dev\": true,\n          \"requires\": {\n            \"p-try\": \"^2.0.0\"\n          }\n        },\n        \"p-locate\": {\n          \"version\": \"4.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz\",\n          \"integrity\": \"sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==\",\n          \"dev\": true,\n          \"requires\": {\n            \"p-limit\": \"^2.2.0\"\n          }\n        },\n        \"read-pkg\": {\n          \"version\": \"5.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz\",\n          \"integrity\": \"sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@types/normalize-package-data\": \"^2.4.0\",\n            \"normalize-package-data\": \"^2.5.0\",\n            \"parse-json\": \"^5.0.0\",\n            \"type-fest\": \"^0.6.0\"\n          },\n          \"dependencies\": {\n            \"type-fest\": {\n              \"version\": \"0.6.0\",\n              \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz\",\n              \"integrity\": \"sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==\",\n              \"dev\": true\n            }\n          }\n        },\n        \"semver\": {\n          \"version\": \"5.7.1\",\n          \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.7.1.tgz\",\n          \"integrity\": \"sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==\",\n          \"dev\": true\n        },\n        \"type-fest\": {\n          \"version\": \"0.8.1\",\n          \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz\",\n          \"integrity\": \"sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"readable-stream\": {\n      \"version\": \"3.6.2\",\n      \"resolved\": \"https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz\",\n      \"integrity\": \"sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"inherits\": \"^2.0.3\",\n        \"string_decoder\": \"^1.1.1\",\n        \"util-deprecate\": \"^1.0.1\"\n      }\n    },\n    \"readdirp\": {\n      \"version\": \"3.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz\",\n      \"integrity\": \"sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"picomatch\": \"^2.2.1\"\n      }\n    },\n    \"redent\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/redent/-/redent-3.0.0.tgz\",\n      \"integrity\": \"sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"indent-string\": \"^4.0.0\",\n        \"strip-indent\": \"^3.0.0\"\n      }\n    },\n    \"regenerate\": {\n      \"version\": \"1.4.2\",\n      \"resolved\": \"https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz\",\n      \"integrity\": \"sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==\",\n      \"dev\": true\n    },\n    \"regenerate-unicode-properties\": {\n      \"version\": \"10.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz\",\n      \"integrity\": \"sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"regenerate\": \"^1.4.2\"\n      }\n    },\n    \"regenerator-runtime\": {\n      \"version\": \"0.13.11\",\n      \"resolved\": \"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz\",\n      \"integrity\": \"sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==\",\n      \"dev\": true\n    },\n    \"regenerator-transform\": {\n      \"version\": \"0.15.1\",\n      \"resolved\": \"https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz\",\n      \"integrity\": \"sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/runtime\": \"^7.8.4\"\n      }\n    },\n    \"regexp-tree\": {\n      \"version\": \"0.1.25\",\n      \"resolved\": \"https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.25.tgz\",\n      \"integrity\": \"sha512-szcL3aqw+vEeuxhL1AMYRyeMP+goYF5I/guaH10uJX5xbGyeQeNPPneaj3ZWVmGLCDxrVaaYekkr5R12gk4dJw==\",\n      \"dev\": true\n    },\n    \"regexp.prototype.flags\": {\n      \"version\": \"1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz\",\n      \"integrity\": \"sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.2.0\",\n        \"functions-have-names\": \"^1.2.3\"\n      }\n    },\n    \"regexpp\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz\",\n      \"integrity\": \"sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==\",\n      \"dev\": true\n    },\n    \"regexpu-core\": {\n      \"version\": \"5.3.2\",\n      \"resolved\": \"https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz\",\n      \"integrity\": \"sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@babel/regjsgen\": \"^0.8.0\",\n        \"regenerate\": \"^1.4.2\",\n        \"regenerate-unicode-properties\": \"^10.1.0\",\n        \"regjsparser\": \"^0.9.1\",\n        \"unicode-match-property-ecmascript\": \"^2.0.0\",\n        \"unicode-match-property-value-ecmascript\": \"^2.1.0\"\n      }\n    },\n    \"regjsparser\": {\n      \"version\": \"0.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz\",\n      \"integrity\": \"sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"jsesc\": \"~0.5.0\"\n      },\n      \"dependencies\": {\n        \"jsesc\": {\n          \"version\": \"0.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz\",\n          \"integrity\": \"sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"require-directory\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz\",\n      \"integrity\": \"sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==\",\n      \"dev\": true\n    },\n    \"require-from-string\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz\",\n      \"integrity\": \"sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==\",\n      \"dev\": true\n    },\n    \"resolve\": {\n      \"version\": \"1.22.2\",\n      \"resolved\": \"https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz\",\n      \"integrity\": \"sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-core-module\": \"^2.11.0\",\n        \"path-parse\": \"^1.0.7\",\n        \"supports-preserve-symlinks-flag\": \"^1.0.0\"\n      }\n    },\n    \"resolve-from\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz\",\n      \"integrity\": \"sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==\",\n      \"dev\": true\n    },\n    \"resolve-global\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz\",\n      \"integrity\": \"sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"global-dirs\": \"^0.1.1\"\n      }\n    },\n    \"restore-cursor\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz\",\n      \"integrity\": \"sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"onetime\": \"^5.1.0\",\n        \"signal-exit\": \"^3.0.2\"\n      }\n    },\n    \"reusify\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz\",\n      \"integrity\": \"sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==\",\n      \"dev\": true\n    },\n    \"rfdc\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz\",\n      \"integrity\": \"sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==\",\n      \"dev\": true\n    },\n    \"rimraf\": {\n      \"version\": \"4.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz\",\n      \"integrity\": \"sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==\",\n      \"dev\": true,\n      \"requires\": {\n        \"glob\": \"^9.2.0\"\n      }\n    },\n    \"rollup\": {\n      \"version\": \"3.20.7\",\n      \"resolved\": \"https://registry.npmjs.org/rollup/-/rollup-3.20.7.tgz\",\n      \"integrity\": \"sha512-P7E2zezKSLhWnTz46XxjSmInrbOCiul1yf+kJccMxT56vxjHwCbDfoLbiqFgu+WQoo9ij2PkraYaBstgB2prBA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"fsevents\": \"~2.3.2\"\n      }\n    },\n    \"run-parallel\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz\",\n      \"integrity\": \"sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"queue-microtask\": \"^1.2.2\"\n      }\n    },\n    \"rxjs\": {\n      \"version\": \"7.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz\",\n      \"integrity\": \"sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"tslib\": \"^2.1.0\"\n      }\n    },\n    \"safe-buffer\": {\n      \"version\": \"5.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz\",\n      \"integrity\": \"sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==\",\n      \"dev\": true\n    },\n    \"safe-regex\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz\",\n      \"integrity\": \"sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"regexp-tree\": \"~0.1.1\"\n      }\n    },\n    \"safe-regex-test\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz\",\n      \"integrity\": \"sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"is-regex\": \"^1.1.4\"\n      }\n    },\n    \"safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"sax\": {\n      \"version\": \"1.2.4\",\n      \"resolved\": \"https://registry.npmjs.org/sax/-/sax-1.2.4.tgz\",\n      \"integrity\": \"sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"seemly\": {\n      \"version\": \"0.3.6\",\n      \"resolved\": \"https://registry.npmjs.org/seemly/-/seemly-0.3.6.tgz\",\n      \"integrity\": \"sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==\"\n    },\n    \"semver\": {\n      \"version\": \"7.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-7.3.8.tgz\",\n      \"integrity\": \"sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"lru-cache\": \"^6.0.0\"\n      }\n    },\n    \"serialize-javascript\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz\",\n      \"integrity\": \"sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"randombytes\": \"^2.1.0\"\n      }\n    },\n    \"shebang-command\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz\",\n      \"integrity\": \"sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"shebang-regex\": \"^3.0.0\"\n      }\n    },\n    \"shebang-regex\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz\",\n      \"integrity\": \"sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==\",\n      \"dev\": true\n    },\n    \"shell-quote\": {\n      \"version\": \"1.8.1\",\n      \"resolved\": \"https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz\",\n      \"integrity\": \"sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==\",\n      \"dev\": true\n    },\n    \"side-channel\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz\",\n      \"integrity\": \"sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.0\",\n        \"get-intrinsic\": \"^1.0.2\",\n        \"object-inspect\": \"^1.9.0\"\n      }\n    },\n    \"signal-exit\": {\n      \"version\": \"3.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz\",\n      \"integrity\": \"sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==\",\n      \"dev\": true\n    },\n    \"slash\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slash/-/slash-3.0.0.tgz\",\n      \"integrity\": \"sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==\",\n      \"dev\": true\n    },\n    \"slice-ansi\": {\n      \"version\": \"5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz\",\n      \"integrity\": \"sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-styles\": \"^6.0.0\",\n        \"is-fullwidth-code-point\": \"^4.0.0\"\n      },\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"6.2.1\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz\",\n          \"integrity\": \"sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"source-map\": {\n      \"version\": \"0.6.1\",\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz\",\n      \"integrity\": \"sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==\"\n    },\n    \"source-map-js\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz\",\n      \"integrity\": \"sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==\"\n    },\n    \"source-map-support\": {\n      \"version\": \"0.5.21\",\n      \"resolved\": \"https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz\",\n      \"integrity\": \"sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==\",\n      \"dev\": true,\n      \"requires\": {\n        \"buffer-from\": \"^1.0.0\",\n        \"source-map\": \"^0.6.0\"\n      }\n    },\n    \"sourcemap-codec\": {\n      \"version\": \"1.4.8\",\n      \"resolved\": \"https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz\",\n      \"integrity\": \"sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==\"\n    },\n    \"spdx-correct\": {\n      \"version\": \"3.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz\",\n      \"integrity\": \"sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"spdx-expression-parse\": \"^3.0.0\",\n        \"spdx-license-ids\": \"^3.0.0\"\n      }\n    },\n    \"spdx-exceptions\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz\",\n      \"integrity\": \"sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==\",\n      \"dev\": true\n    },\n    \"spdx-expression-parse\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz\",\n      \"integrity\": \"sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"spdx-exceptions\": \"^2.1.0\",\n        \"spdx-license-ids\": \"^3.0.0\"\n      }\n    },\n    \"spdx-license-ids\": {\n      \"version\": \"3.0.13\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz\",\n      \"integrity\": \"sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==\",\n      \"dev\": true\n    },\n    \"split2\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/split2/-/split2-3.2.2.tgz\",\n      \"integrity\": \"sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"readable-stream\": \"^3.0.0\"\n      }\n    },\n    \"string_decoder\": {\n      \"version\": \"1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz\",\n      \"integrity\": \"sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"safe-buffer\": \"~5.2.0\"\n      }\n    },\n    \"string-argv\": {\n      \"version\": \"0.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz\",\n      \"integrity\": \"sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==\",\n      \"dev\": true\n    },\n    \"string-width\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz\",\n      \"integrity\": \"sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eastasianwidth\": \"^0.2.0\",\n        \"emoji-regex\": \"^9.2.2\",\n        \"strip-ansi\": \"^7.0.1\"\n      },\n      \"dependencies\": {\n        \"ansi-regex\": {\n          \"version\": \"6.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz\",\n          \"integrity\": \"sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"7.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz\",\n          \"integrity\": \"sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"ansi-regex\": \"^6.0.1\"\n          }\n        }\n      }\n    },\n    \"string.prototype.matchall\": {\n      \"version\": \"4.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz\",\n      \"integrity\": \"sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\",\n        \"get-intrinsic\": \"^1.1.3\",\n        \"has-symbols\": \"^1.0.3\",\n        \"internal-slot\": \"^1.0.3\",\n        \"regexp.prototype.flags\": \"^1.4.3\",\n        \"side-channel\": \"^1.0.4\"\n      }\n    },\n    \"string.prototype.padend\": {\n      \"version\": \"3.1.4\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz\",\n      \"integrity\": \"sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      }\n    },\n    \"string.prototype.trim\": {\n      \"version\": \"1.2.7\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz\",\n      \"integrity\": \"sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      }\n    },\n    \"string.prototype.trimend\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz\",\n      \"integrity\": \"sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      }\n    },\n    \"string.prototype.trimstart\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz\",\n      \"integrity\": \"sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"define-properties\": \"^1.1.4\",\n        \"es-abstract\": \"^1.20.4\"\n      }\n    },\n    \"stringify-object\": {\n      \"version\": \"3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz\",\n      \"integrity\": \"sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"get-own-enumerable-property-symbols\": \"^3.0.0\",\n        \"is-obj\": \"^1.0.1\",\n        \"is-regexp\": \"^1.0.0\"\n      },\n      \"dependencies\": {\n        \"is-obj\": {\n          \"version\": \"1.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz\",\n          \"integrity\": \"sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"strip-ansi\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz\",\n      \"integrity\": \"sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-regex\": \"^5.0.1\"\n      }\n    },\n    \"strip-bom\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz\",\n      \"integrity\": \"sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==\",\n      \"dev\": true\n    },\n    \"strip-comments\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz\",\n      \"integrity\": \"sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==\",\n      \"dev\": true\n    },\n    \"strip-final-newline\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz\",\n      \"integrity\": \"sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==\",\n      \"dev\": true\n    },\n    \"strip-indent\": {\n      \"version\": \"3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz\",\n      \"integrity\": \"sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"min-indent\": \"^1.0.0\"\n      }\n    },\n    \"strip-json-comments\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz\",\n      \"integrity\": \"sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==\",\n      \"dev\": true\n    },\n    \"sucrase\": {\n      \"version\": \"3.32.0\",\n      \"resolved\": \"https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz\",\n      \"integrity\": \"sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/gen-mapping\": \"^0.3.2\",\n        \"commander\": \"^4.0.0\",\n        \"glob\": \"7.1.6\",\n        \"lines-and-columns\": \"^1.1.6\",\n        \"mz\": \"^2.7.0\",\n        \"pirates\": \"^4.0.1\",\n        \"ts-interface-checker\": \"^0.1.9\"\n      },\n      \"dependencies\": {\n        \"commander\": {\n          \"version\": \"4.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/commander/-/commander-4.1.1.tgz\",\n          \"integrity\": \"sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==\",\n          \"dev\": true\n        },\n        \"glob\": {\n          \"version\": \"7.1.6\",\n          \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.1.6.tgz\",\n          \"integrity\": \"sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fs.realpath\": \"^1.0.0\",\n            \"inflight\": \"^1.0.4\",\n            \"inherits\": \"2\",\n            \"minimatch\": \"^3.0.4\",\n            \"once\": \"^1.3.0\",\n            \"path-is-absolute\": \"^1.0.0\"\n          }\n        }\n      }\n    },\n    \"supports-color\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz\",\n      \"integrity\": \"sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"has-flag\": \"^4.0.0\"\n      }\n    },\n    \"supports-preserve-symlinks-flag\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz\",\n      \"integrity\": \"sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==\",\n      \"dev\": true\n    },\n    \"tailwindcss\": {\n      \"version\": \"3.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz\",\n      \"integrity\": \"sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"arg\": \"^5.0.2\",\n        \"chokidar\": \"^3.5.3\",\n        \"color-name\": \"^1.1.4\",\n        \"didyoumean\": \"^1.2.2\",\n        \"dlv\": \"^1.1.3\",\n        \"fast-glob\": \"^3.2.12\",\n        \"glob-parent\": \"^6.0.2\",\n        \"is-glob\": \"^4.0.3\",\n        \"jiti\": \"^1.17.2\",\n        \"lilconfig\": \"^2.0.6\",\n        \"micromatch\": \"^4.0.5\",\n        \"normalize-path\": \"^3.0.0\",\n        \"object-hash\": \"^3.0.0\",\n        \"picocolors\": \"^1.0.0\",\n        \"postcss\": \"^8.0.9\",\n        \"postcss-import\": \"^14.1.0\",\n        \"postcss-js\": \"^4.0.0\",\n        \"postcss-load-config\": \"^3.1.4\",\n        \"postcss-nested\": \"6.0.0\",\n        \"postcss-selector-parser\": \"^6.0.11\",\n        \"postcss-value-parser\": \"^4.2.0\",\n        \"quick-lru\": \"^5.1.1\",\n        \"resolve\": \"^1.22.1\",\n        \"sucrase\": \"^3.29.0\"\n      },\n      \"dependencies\": {\n        \"quick-lru\": {\n          \"version\": \"5.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz\",\n          \"integrity\": \"sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"temp-dir\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz\",\n      \"integrity\": \"sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==\",\n      \"dev\": true\n    },\n    \"tempy\": {\n      \"version\": \"0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz\",\n      \"integrity\": \"sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-stream\": \"^2.0.0\",\n        \"temp-dir\": \"^2.0.0\",\n        \"type-fest\": \"^0.16.0\",\n        \"unique-string\": \"^2.0.0\"\n      },\n      \"dependencies\": {\n        \"type-fest\": {\n          \"version\": \"0.16.0\",\n          \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz\",\n          \"integrity\": \"sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"terser\": {\n      \"version\": \"5.17.1\",\n      \"resolved\": \"https://registry.npmjs.org/terser/-/terser-5.17.1.tgz\",\n      \"integrity\": \"sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@jridgewell/source-map\": \"^0.3.2\",\n        \"acorn\": \"^8.5.0\",\n        \"commander\": \"^2.20.0\",\n        \"source-map-support\": \"~0.5.20\"\n      },\n      \"dependencies\": {\n        \"commander\": {\n          \"version\": \"2.20.3\",\n          \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.20.3.tgz\",\n          \"integrity\": \"sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"text-extensions\": {\n      \"version\": \"1.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz\",\n      \"integrity\": \"sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==\",\n      \"dev\": true\n    },\n    \"text-segmentation\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz\",\n      \"integrity\": \"sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==\",\n      \"requires\": {\n        \"utrie\": \"^1.0.2\"\n      }\n    },\n    \"text-table\": {\n      \"version\": \"0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz\",\n      \"integrity\": \"sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==\",\n      \"dev\": true\n    },\n    \"thenify\": {\n      \"version\": \"3.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz\",\n      \"integrity\": \"sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"any-promise\": \"^1.0.0\"\n      }\n    },\n    \"thenify-all\": {\n      \"version\": \"1.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz\",\n      \"integrity\": \"sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"thenify\": \">= 3.1.0 < 4\"\n      }\n    },\n    \"through\": {\n      \"version\": \"2.3.8\",\n      \"resolved\": \"https://registry.npmjs.org/through/-/through-2.3.8.tgz\",\n      \"integrity\": \"sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==\",\n      \"dev\": true\n    },\n    \"through2\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/through2/-/through2-4.0.2.tgz\",\n      \"integrity\": \"sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"readable-stream\": \"3\"\n      }\n    },\n    \"to-fast-properties\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz\",\n      \"integrity\": \"sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==\",\n      \"dev\": true\n    },\n    \"to-regex-range\": {\n      \"version\": \"5.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz\",\n      \"integrity\": \"sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-number\": \"^7.0.0\"\n      }\n    },\n    \"tr46\": {\n      \"version\": \"1.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz\",\n      \"integrity\": \"sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"punycode\": \"^2.1.0\"\n      }\n    },\n    \"treemate\": {\n      \"version\": \"0.3.11\",\n      \"resolved\": \"https://registry.npmjs.org/treemate/-/treemate-0.3.11.tgz\",\n      \"integrity\": \"sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==\"\n    },\n    \"trim-newlines\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz\",\n      \"integrity\": \"sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==\",\n      \"dev\": true\n    },\n    \"ts-interface-checker\": {\n      \"version\": \"0.1.13\",\n      \"resolved\": \"https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz\",\n      \"integrity\": \"sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==\",\n      \"dev\": true\n    },\n    \"ts-node\": {\n      \"version\": \"10.9.1\",\n      \"resolved\": \"https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz\",\n      \"integrity\": \"sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@cspotcode/source-map-support\": \"^0.8.0\",\n        \"@tsconfig/node10\": \"^1.0.7\",\n        \"@tsconfig/node12\": \"^1.0.7\",\n        \"@tsconfig/node14\": \"^1.0.0\",\n        \"@tsconfig/node16\": \"^1.0.2\",\n        \"acorn\": \"^8.4.1\",\n        \"acorn-walk\": \"^8.1.1\",\n        \"arg\": \"^4.1.0\",\n        \"create-require\": \"^1.1.0\",\n        \"diff\": \"^4.0.1\",\n        \"make-error\": \"^1.1.1\",\n        \"v8-compile-cache-lib\": \"^3.0.1\",\n        \"yn\": \"3.1.1\"\n      },\n      \"dependencies\": {\n        \"arg\": {\n          \"version\": \"4.1.3\",\n          \"resolved\": \"https://registry.npmjs.org/arg/-/arg-4.1.3.tgz\",\n          \"integrity\": \"sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"tsconfig-paths\": {\n      \"version\": \"3.14.2\",\n      \"resolved\": \"https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz\",\n      \"integrity\": \"sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/json5\": \"^0.0.29\",\n        \"json5\": \"^1.0.2\",\n        \"minimist\": \"^1.2.6\",\n        \"strip-bom\": \"^3.0.0\"\n      }\n    },\n    \"tslib\": {\n      \"version\": \"2.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz\",\n      \"integrity\": \"sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==\",\n      \"dev\": true\n    },\n    \"tsutils\": {\n      \"version\": \"3.21.0\",\n      \"resolved\": \"https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz\",\n      \"integrity\": \"sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"tslib\": \"^1.8.1\"\n      },\n      \"dependencies\": {\n        \"tslib\": {\n          \"version\": \"1.14.1\",\n          \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz\",\n          \"integrity\": \"sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"type-check\": {\n      \"version\": \"0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz\",\n      \"integrity\": \"sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==\",\n      \"dev\": true,\n      \"requires\": {\n        \"prelude-ls\": \"^1.2.1\"\n      }\n    },\n    \"type-fest\": {\n      \"version\": \"0.20.2\",\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz\",\n      \"integrity\": \"sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==\",\n      \"dev\": true\n    },\n    \"typed-array-length\": {\n      \"version\": \"1.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz\",\n      \"integrity\": \"sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"is-typed-array\": \"^1.1.9\"\n      }\n    },\n    \"typescript\": {\n      \"version\": \"4.9.5\",\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz\",\n      \"integrity\": \"sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==\",\n      \"devOptional\": true\n    },\n    \"uc.micro\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz\",\n      \"integrity\": \"sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==\"\n    },\n    \"unbox-primitive\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz\",\n      \"integrity\": \"sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"call-bind\": \"^1.0.2\",\n        \"has-bigints\": \"^1.0.2\",\n        \"has-symbols\": \"^1.0.3\",\n        \"which-boxed-primitive\": \"^1.0.2\"\n      }\n    },\n    \"unicode-canonical-property-names-ecmascript\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz\",\n      \"integrity\": \"sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==\",\n      \"dev\": true\n    },\n    \"unicode-match-property-ecmascript\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz\",\n      \"integrity\": \"sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"unicode-canonical-property-names-ecmascript\": \"^2.0.0\",\n        \"unicode-property-aliases-ecmascript\": \"^2.0.0\"\n      }\n    },\n    \"unicode-match-property-value-ecmascript\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz\",\n      \"integrity\": \"sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==\",\n      \"dev\": true\n    },\n    \"unicode-property-aliases-ecmascript\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz\",\n      \"integrity\": \"sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==\",\n      \"dev\": true\n    },\n    \"unique-string\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz\",\n      \"integrity\": \"sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"crypto-random-string\": \"^2.0.0\"\n      }\n    },\n    \"unist-util-stringify-position\": {\n      \"version\": \"2.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz\",\n      \"integrity\": \"sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/unist\": \"^2.0.2\"\n      }\n    },\n    \"universalify\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz\",\n      \"integrity\": \"sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==\",\n      \"dev\": true\n    },\n    \"upath\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/upath/-/upath-1.2.0.tgz\",\n      \"integrity\": \"sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==\",\n      \"dev\": true\n    },\n    \"update-browserslist-db\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz\",\n      \"integrity\": \"sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"escalade\": \"^3.1.1\",\n        \"picocolors\": \"^1.0.0\"\n      }\n    },\n    \"uri-js\": {\n      \"version\": \"4.4.1\",\n      \"resolved\": \"https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz\",\n      \"integrity\": \"sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"punycode\": \"^2.1.0\"\n      }\n    },\n    \"util-deprecate\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz\",\n      \"integrity\": \"sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==\",\n      \"dev\": true\n    },\n    \"utrie\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz\",\n      \"integrity\": \"sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==\",\n      \"requires\": {\n        \"base64-arraybuffer\": \"^1.0.2\"\n      }\n    },\n    \"v8-compile-cache-lib\": {\n      \"version\": \"3.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz\",\n      \"integrity\": \"sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==\",\n      \"dev\": true\n    },\n    \"validate-npm-package-license\": {\n      \"version\": \"3.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz\",\n      \"integrity\": \"sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==\",\n      \"dev\": true,\n      \"requires\": {\n        \"spdx-correct\": \"^3.0.0\",\n        \"spdx-expression-parse\": \"^3.0.0\"\n      }\n    },\n    \"vdirs\": {\n      \"version\": \"0.1.8\",\n      \"resolved\": \"https://registry.npmjs.org/vdirs/-/vdirs-0.1.8.tgz\",\n      \"integrity\": \"sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==\",\n      \"requires\": {\n        \"evtd\": \"^0.2.2\"\n      }\n    },\n    \"vite\": {\n      \"version\": \"4.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/vite/-/vite-4.3.1.tgz\",\n      \"integrity\": \"sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"esbuild\": \"^0.17.5\",\n        \"fsevents\": \"~2.3.2\",\n        \"postcss\": \"^8.4.21\",\n        \"rollup\": \"^3.20.2\"\n      }\n    },\n    \"vite-plugin-pwa\": {\n      \"version\": \"0.14.7\",\n      \"resolved\": \"https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.14.7.tgz\",\n      \"integrity\": \"sha512-dNJaf0fYOWncmjxv9HiSa2xrSjipjff7IkYE5oIUJ2x5HKu3cXgA8LRgzOwTc5MhwyFYRSU0xyN0Phbx3NsQYw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@rollup/plugin-replace\": \"^5.0.1\",\n        \"debug\": \"^4.3.4\",\n        \"fast-glob\": \"^3.2.12\",\n        \"pretty-bytes\": \"^6.0.0\",\n        \"rollup\": \"^3.7.2\",\n        \"workbox-build\": \"^6.5.4\",\n        \"workbox-window\": \"^6.5.4\"\n      }\n    },\n    \"vooks\": {\n      \"version\": \"0.2.12\",\n      \"resolved\": \"https://registry.npmjs.org/vooks/-/vooks-0.2.12.tgz\",\n      \"integrity\": \"sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==\",\n      \"requires\": {\n        \"evtd\": \"^0.2.2\"\n      }\n    },\n    \"vue\": {\n      \"version\": \"3.2.47\",\n      \"resolved\": \"https://registry.npmjs.org/vue/-/vue-3.2.47.tgz\",\n      \"integrity\": \"sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==\",\n      \"requires\": {\n        \"@vue/compiler-dom\": \"3.2.47\",\n        \"@vue/compiler-sfc\": \"3.2.47\",\n        \"@vue/runtime-dom\": \"3.2.47\",\n        \"@vue/server-renderer\": \"3.2.47\",\n        \"@vue/shared\": \"3.2.47\"\n      }\n    },\n    \"vue-eslint-parser\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz\",\n      \"integrity\": \"sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"debug\": \"^4.3.4\",\n        \"eslint-scope\": \"^7.1.1\",\n        \"eslint-visitor-keys\": \"^3.3.0\",\n        \"espree\": \"^9.3.1\",\n        \"esquery\": \"^1.4.0\",\n        \"lodash\": \"^4.17.21\",\n        \"semver\": \"^7.3.6\"\n      },\n      \"dependencies\": {\n        \"eslint-scope\": {\n          \"version\": \"7.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz\",\n          \"integrity\": \"sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"esrecurse\": \"^4.3.0\",\n            \"estraverse\": \"^5.2.0\"\n          }\n        },\n        \"estraverse\": {\n          \"version\": \"5.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz\",\n          \"integrity\": \"sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"vue-i18n\": {\n      \"version\": \"9.2.2\",\n      \"resolved\": \"https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.2.2.tgz\",\n      \"integrity\": \"sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==\",\n      \"requires\": {\n        \"@intlify/core-base\": \"9.2.2\",\n        \"@intlify/shared\": \"9.2.2\",\n        \"@intlify/vue-devtools\": \"9.2.2\",\n        \"@vue/devtools-api\": \"^6.2.1\"\n      }\n    },\n    \"vue-router\": {\n      \"version\": \"4.1.6\",\n      \"resolved\": \"https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz\",\n      \"integrity\": \"sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==\",\n      \"requires\": {\n        \"@vue/devtools-api\": \"^6.4.5\"\n      }\n    },\n    \"vue-template-compiler\": {\n      \"version\": \"2.7.14\",\n      \"resolved\": \"https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz\",\n      \"integrity\": \"sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"de-indent\": \"^1.0.2\",\n        \"he\": \"^1.2.0\"\n      }\n    },\n    \"vue-tsc\": {\n      \"version\": \"1.4.4\",\n      \"resolved\": \"https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.4.4.tgz\",\n      \"integrity\": \"sha512-2XsCjF2mLo6gwOVcOpngwJkP8GzYQjNh20A+Pr2FGdsWzr9jjXJ0k08/DfcslfncsuCrTrnWtb4KEL3gcDtlNA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@volar/vue-language-core\": \"1.4.4\",\n        \"@volar/vue-typescript\": \"1.4.4\",\n        \"semver\": \"^7.3.8\"\n      }\n    },\n    \"vueuc\": {\n      \"version\": \"0.4.51\",\n      \"resolved\": \"https://registry.npmjs.org/vueuc/-/vueuc-0.4.51.tgz\",\n      \"integrity\": \"sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==\",\n      \"requires\": {\n        \"@css-render/vue3-ssr\": \"^0.15.10\",\n        \"@juggle/resize-observer\": \"^3.3.1\",\n        \"css-render\": \"^0.15.10\",\n        \"evtd\": \"^0.2.4\",\n        \"seemly\": \"^0.3.6\",\n        \"vdirs\": \"^0.1.4\",\n        \"vooks\": \"^0.2.4\"\n      }\n    },\n    \"webidl-conversions\": {\n      \"version\": \"4.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz\",\n      \"integrity\": \"sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==\",\n      \"dev\": true\n    },\n    \"whatwg-url\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz\",\n      \"integrity\": \"sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"lodash.sortby\": \"^4.7.0\",\n        \"tr46\": \"^1.0.1\",\n        \"webidl-conversions\": \"^4.0.2\"\n      }\n    },\n    \"which\": {\n      \"version\": \"2.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-2.0.2.tgz\",\n      \"integrity\": \"sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"isexe\": \"^2.0.0\"\n      }\n    },\n    \"which-boxed-primitive\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz\",\n      \"integrity\": \"sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"is-bigint\": \"^1.0.1\",\n        \"is-boolean-object\": \"^1.1.0\",\n        \"is-number-object\": \"^1.0.4\",\n        \"is-string\": \"^1.0.5\",\n        \"is-symbol\": \"^1.0.3\"\n      }\n    },\n    \"which-typed-array\": {\n      \"version\": \"1.1.9\",\n      \"resolved\": \"https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz\",\n      \"integrity\": \"sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"available-typed-arrays\": \"^1.0.5\",\n        \"call-bind\": \"^1.0.2\",\n        \"for-each\": \"^0.3.3\",\n        \"gopd\": \"^1.0.1\",\n        \"has-tostringtag\": \"^1.0.0\",\n        \"is-typed-array\": \"^1.1.10\"\n      }\n    },\n    \"word-wrap\": {\n      \"version\": \"1.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz\",\n      \"integrity\": \"sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==\",\n      \"dev\": true\n    },\n    \"workbox-background-sync\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz\",\n      \"integrity\": \"sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==\",\n      \"dev\": true,\n      \"requires\": {\n        \"idb\": \"^7.0.1\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-broadcast-update\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz\",\n      \"integrity\": \"sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-build\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz\",\n      \"integrity\": \"sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@apideck/better-ajv-errors\": \"^0.3.1\",\n        \"@babel/core\": \"^7.11.1\",\n        \"@babel/preset-env\": \"^7.11.0\",\n        \"@babel/runtime\": \"^7.11.2\",\n        \"@rollup/plugin-babel\": \"^5.2.0\",\n        \"@rollup/plugin-node-resolve\": \"^11.2.1\",\n        \"@rollup/plugin-replace\": \"^2.4.1\",\n        \"@surma/rollup-plugin-off-main-thread\": \"^2.2.3\",\n        \"ajv\": \"^8.6.0\",\n        \"common-tags\": \"^1.8.0\",\n        \"fast-json-stable-stringify\": \"^2.1.0\",\n        \"fs-extra\": \"^9.0.1\",\n        \"glob\": \"^7.1.6\",\n        \"lodash\": \"^4.17.20\",\n        \"pretty-bytes\": \"^5.3.0\",\n        \"rollup\": \"^2.43.1\",\n        \"rollup-plugin-terser\": \"^7.0.0\",\n        \"source-map\": \"^0.8.0-beta.0\",\n        \"stringify-object\": \"^3.3.0\",\n        \"strip-comments\": \"^2.0.1\",\n        \"tempy\": \"^0.6.0\",\n        \"upath\": \"^1.2.0\",\n        \"workbox-background-sync\": \"6.5.4\",\n        \"workbox-broadcast-update\": \"6.5.4\",\n        \"workbox-cacheable-response\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-expiration\": \"6.5.4\",\n        \"workbox-google-analytics\": \"6.5.4\",\n        \"workbox-navigation-preload\": \"6.5.4\",\n        \"workbox-precaching\": \"6.5.4\",\n        \"workbox-range-requests\": \"6.5.4\",\n        \"workbox-recipes\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\",\n        \"workbox-streams\": \"6.5.4\",\n        \"workbox-sw\": \"6.5.4\",\n        \"workbox-window\": \"6.5.4\"\n      },\n      \"dependencies\": {\n        \"@rollup/plugin-babel\": {\n          \"version\": \"5.3.1\",\n          \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz\",\n          \"integrity\": \"sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@babel/helper-module-imports\": \"^7.10.4\",\n            \"@rollup/pluginutils\": \"^3.1.0\"\n          }\n        },\n        \"@rollup/plugin-node-resolve\": {\n          \"version\": \"11.2.1\",\n          \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz\",\n          \"integrity\": \"sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@rollup/pluginutils\": \"^3.1.0\",\n            \"@types/resolve\": \"1.17.1\",\n            \"builtin-modules\": \"^3.1.0\",\n            \"deepmerge\": \"^4.2.2\",\n            \"is-module\": \"^1.0.0\",\n            \"resolve\": \"^1.19.0\"\n          }\n        },\n        \"@rollup/plugin-replace\": {\n          \"version\": \"2.4.2\",\n          \"resolved\": \"https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz\",\n          \"integrity\": \"sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@rollup/pluginutils\": \"^3.1.0\",\n            \"magic-string\": \"^0.25.7\"\n          }\n        },\n        \"@rollup/pluginutils\": {\n          \"version\": \"3.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz\",\n          \"integrity\": \"sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@types/estree\": \"0.0.39\",\n            \"estree-walker\": \"^1.0.1\",\n            \"picomatch\": \"^2.2.2\"\n          }\n        },\n        \"@types/estree\": {\n          \"version\": \"0.0.39\",\n          \"resolved\": \"https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz\",\n          \"integrity\": \"sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==\",\n          \"dev\": true\n        },\n        \"estree-walker\": {\n          \"version\": \"1.0.1\",\n          \"resolved\": \"https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz\",\n          \"integrity\": \"sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==\",\n          \"dev\": true\n        },\n        \"fs-extra\": {\n          \"version\": \"9.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz\",\n          \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"at-least-node\": \"^1.0.0\",\n            \"graceful-fs\": \"^4.2.0\",\n            \"jsonfile\": \"^6.0.1\",\n            \"universalify\": \"^2.0.0\"\n          }\n        },\n        \"glob\": {\n          \"version\": \"7.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.2.3.tgz\",\n          \"integrity\": \"sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fs.realpath\": \"^1.0.0\",\n            \"inflight\": \"^1.0.4\",\n            \"inherits\": \"2\",\n            \"minimatch\": \"^3.1.1\",\n            \"once\": \"^1.3.0\",\n            \"path-is-absolute\": \"^1.0.0\"\n          }\n        },\n        \"magic-string\": {\n          \"version\": \"0.25.9\",\n          \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz\",\n          \"integrity\": \"sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"sourcemap-codec\": \"^1.4.8\"\n          }\n        },\n        \"pretty-bytes\": {\n          \"version\": \"5.6.0\",\n          \"resolved\": \"https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz\",\n          \"integrity\": \"sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==\",\n          \"dev\": true\n        },\n        \"rollup\": {\n          \"version\": \"2.79.1\",\n          \"resolved\": \"https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz\",\n          \"integrity\": \"sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==\",\n          \"dev\": true,\n          \"requires\": {\n            \"fsevents\": \"~2.3.2\"\n          }\n        },\n        \"rollup-plugin-terser\": {\n          \"version\": \"7.0.2\",\n          \"resolved\": \"https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz\",\n          \"integrity\": \"sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==\",\n          \"dev\": true,\n          \"requires\": {\n            \"@babel/code-frame\": \"^7.10.4\",\n            \"jest-worker\": \"^26.2.1\",\n            \"serialize-javascript\": \"^4.0.0\",\n            \"terser\": \"^5.0.0\"\n          }\n        },\n        \"source-map\": {\n          \"version\": \"0.8.0-beta.0\",\n          \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz\",\n          \"integrity\": \"sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==\",\n          \"dev\": true,\n          \"requires\": {\n            \"whatwg-url\": \"^7.0.0\"\n          }\n        }\n      }\n    },\n    \"workbox-cacheable-response\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz\",\n      \"integrity\": \"sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-core\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz\",\n      \"integrity\": \"sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==\",\n      \"dev\": true\n    },\n    \"workbox-expiration\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz\",\n      \"integrity\": \"sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==\",\n      \"dev\": true,\n      \"requires\": {\n        \"idb\": \"^7.0.1\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-google-analytics\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz\",\n      \"integrity\": \"sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-background-sync\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"workbox-navigation-preload\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz\",\n      \"integrity\": \"sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-precaching\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz\",\n      \"integrity\": \"sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"workbox-range-requests\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz\",\n      \"integrity\": \"sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-recipes\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz\",\n      \"integrity\": \"sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-cacheable-response\": \"6.5.4\",\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-expiration\": \"6.5.4\",\n        \"workbox-precaching\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\",\n        \"workbox-strategies\": \"6.5.4\"\n      }\n    },\n    \"workbox-routing\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz\",\n      \"integrity\": \"sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-strategies\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz\",\n      \"integrity\": \"sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"workbox-streams\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz\",\n      \"integrity\": \"sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"workbox-core\": \"6.5.4\",\n        \"workbox-routing\": \"6.5.4\"\n      }\n    },\n    \"workbox-sw\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz\",\n      \"integrity\": \"sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==\",\n      \"dev\": true\n    },\n    \"workbox-window\": {\n      \"version\": \"6.5.4\",\n      \"resolved\": \"https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz\",\n      \"integrity\": \"sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==\",\n      \"dev\": true,\n      \"requires\": {\n        \"@types/trusted-types\": \"^2.0.2\",\n        \"workbox-core\": \"6.5.4\"\n      }\n    },\n    \"wrap-ansi\": {\n      \"version\": \"7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz\",\n      \"integrity\": \"sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==\",\n      \"dev\": true,\n      \"requires\": {\n        \"ansi-styles\": \"^4.0.0\",\n        \"string-width\": \"^4.1.0\",\n        \"strip-ansi\": \"^6.0.0\"\n      },\n      \"dependencies\": {\n        \"emoji-regex\": {\n          \"version\": \"8.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n          \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n          \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n          \"dev\": true\n        },\n        \"string-width\": {\n          \"version\": \"4.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n          \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"emoji-regex\": \"^8.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\",\n            \"strip-ansi\": \"^6.0.1\"\n          }\n        }\n      }\n    },\n    \"wrappy\": {\n      \"version\": \"1.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\",\n      \"integrity\": \"sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==\",\n      \"dev\": true\n    },\n    \"xml-name-validator\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz\",\n      \"integrity\": \"sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==\",\n      \"dev\": true\n    },\n    \"y18n\": {\n      \"version\": \"5.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz\",\n      \"integrity\": \"sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==\",\n      \"dev\": true\n    },\n    \"yallist\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz\",\n      \"integrity\": \"sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==\",\n      \"dev\": true\n    },\n    \"yaml\": {\n      \"version\": \"2.2.1\",\n      \"resolved\": \"https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz\",\n      \"integrity\": \"sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==\",\n      \"dev\": true\n    },\n    \"yaml-eslint-parser\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.0.tgz\",\n      \"integrity\": \"sha512-OmuvQd5lyIJWfFALc39K5fGqp0aWNc+EtyhVgcQIPZaUKMnTb7An3RMp+QJizJ/x0F4kpgTNe6BL/ctdvoIwIg==\",\n      \"dev\": true,\n      \"requires\": {\n        \"eslint-visitor-keys\": \"^3.0.0\",\n        \"lodash\": \"^4.17.21\",\n        \"yaml\": \"^2.0.0\"\n      }\n    },\n    \"yargs\": {\n      \"version\": \"17.7.1\",\n      \"resolved\": \"https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz\",\n      \"integrity\": \"sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==\",\n      \"dev\": true,\n      \"requires\": {\n        \"cliui\": \"^8.0.1\",\n        \"escalade\": \"^3.1.1\",\n        \"get-caller-file\": \"^2.0.5\",\n        \"require-directory\": \"^2.1.1\",\n        \"string-width\": \"^4.2.3\",\n        \"y18n\": \"^5.0.5\",\n        \"yargs-parser\": \"^21.1.1\"\n      },\n      \"dependencies\": {\n        \"emoji-regex\": {\n          \"version\": \"8.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz\",\n          \"integrity\": \"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz\",\n          \"integrity\": \"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==\",\n          \"dev\": true\n        },\n        \"string-width\": {\n          \"version\": \"4.2.3\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz\",\n          \"integrity\": \"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==\",\n          \"dev\": true,\n          \"requires\": {\n            \"emoji-regex\": \"^8.0.0\",\n            \"is-fullwidth-code-point\": \"^3.0.0\",\n            \"strip-ansi\": \"^6.0.1\"\n          }\n        },\n        \"yargs-parser\": {\n          \"version\": \"21.1.1\",\n          \"resolved\": \"https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz\",\n          \"integrity\": \"sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==\",\n          \"dev\": true\n        }\n      }\n    },\n    \"yargs-parser\": {\n      \"version\": \"20.2.9\",\n      \"resolved\": \"https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz\",\n      \"integrity\": \"sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==\",\n      \"dev\": true\n    },\n    \"yn\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/yn/-/yn-3.1.1.tgz\",\n      \"integrity\": \"sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==\",\n      \"dev\": true\n    },\n    \"yocto-queue\": {\n      \"version\": \"0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz\",\n      \"integrity\": \"sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==\",\n      \"dev\": true\n    }\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## v2.11.1\n\n`2023-10-11`\n\n## Enhancement\n- 优化打字机光标效果\n- 清空聊天历史按钮\n- 更新文档\n\n## BugFix\n- 修复移动端上的问题\n- 修复不规范的引入导致的问题\n\n## v2.11.0\n\n`2023-04-26`\n\n> [chatgpt-web-plus](https://github.com/Chanzhaoyu/chatgpt-web-plus) 新界面、完整用户管理\n\n## Enhancement\n- 更新默认 `accessToken` 反代地址为 [[pengzhile](https://github.com/pengzhile)] 的 `https://ai.fakeopen.com/api/conversation` [[24min](https://github.com/Chanzhaoyu/chatgpt-web/pull/1567/files)]\n- 添加自定义 `temperature` 和 `top_p` [[quzard](https://github.com/Chanzhaoyu/chatgpt-web/pull/1260)]\n- 优化代码 [[shunyue1320](https://github.com/Chanzhaoyu/chatgpt-web/pull/1328)]\n- 优化复制代码反馈效果\n\n## BugFix\n- 修复余额查询和文案 [[luckywangxi](https://github.com/Chanzhaoyu/chatgpt-web/pull/1174)][[zuoning777](https://github.com/Chanzhaoyu/chatgpt-web/pull/1296)]\n- 修复默认语言错误 [[idawnwon](https://github.com/Chanzhaoyu/chatgpt-web/pull/1352)]\n- 修复 `onRegenerate` 下问题 [[leafsummer](https://github.com/Chanzhaoyu/chatgpt-web/pull/1188)]\n\n## Other\n- 引导用户触发提示词 [[RyanXinOne](https://github.com/Chanzhaoyu/chatgpt-web/pull/1183)]\n- 添加韩语翻译 [[Kamilake](https://github.com/Chanzhaoyu/chatgpt-web/pull/1372)]\n- 添加俄语翻译 [[aquaratixc](https://github.com/Chanzhaoyu/chatgpt-web/pull/1571)]\n- 优化翻译和文本检查 [[PeterDaveHello](https://github.com/Chanzhaoyu/chatgpt-web/pull/1460)]\n- 移除无用文件\n\n## v2.10.9\n\n`2023-04-03`\n\n> 更新默认 `accessToken` 反代地址为 [[pengzhile](https://github.com/pengzhile)] 的 `https://ai.fakeopen.com/api/conversation`\n\n## Enhancement\n- 添加 `socks5` 代理认证 [[yimiaoxiehou](https://github.com/Chanzhaoyu/chatgpt-web/pull/999)]\n- 添加 `socks` 代理用户名密码的配置 [[hank-cp](https://github.com/Chanzhaoyu/chatgpt-web/pull/890)]\n- 添加可选日志打印 [[zcong1993](https://github.com/Chanzhaoyu/chatgpt-web/pull/1041)]\n- 更新侧边栏按钮本地化[[simonwu53](https://github.com/Chanzhaoyu/chatgpt-web/pull/911)]\n- 优化代码块滚动条高度 [[Fog3211](https://github.com/Chanzhaoyu/chatgpt-web/pull/1153)]\n## BugFix\n- 修复 `PWA` 问题 [[bingo235](https://github.com/Chanzhaoyu/chatgpt-web/pull/807)]\n- 修复 `ESM` 错误 [[kidonng](https://github.com/Chanzhaoyu/chatgpt-web/pull/826)]\n- 修复反向代理开启时限流失效的问题 [[gitgitgogogo](https://github.com/Chanzhaoyu/chatgpt-web/pull/863)]\n- 修复 `docker` 构建时 `.env` 可能被忽略的问题 [[zaiMoe](https://github.com/Chanzhaoyu/chatgpt-web/pull/877)]\n- 修复导出异常错误 [[KingTwinkle](https://github.com/Chanzhaoyu/chatgpt-web/pull/938)]\n- 修复空值异常 [[vchenpeng](https://github.com/Chanzhaoyu/chatgpt-web/pull/1103)]\n- 移动端上的体验问题\n\n## Other\n- `Docker` 容器名字名义 [[LOVECHEN](https://github.com/Chanzhaoyu/chatgpt-web/pull/1035)]\n- `kubernetes` 部署配置 [[CaoYunzhou](https://github.com/Chanzhaoyu/chatgpt-web/pull/1001)]\n- 感谢 [[assassinliujie](https://github.com/Chanzhaoyu/chatgpt-web/pull/962)] 和 [[puppywang](https://github.com/Chanzhaoyu/chatgpt-web/pull/1017)] 的某些贡献\n- 更新 `kubernetes/deploy.yaml` [[idawnwon](https://github.com/Chanzhaoyu/chatgpt-web/pull/1085)]\n- 文档更新 [[#yi-ge](https://github.com/Chanzhaoyu/chatgpt-web/pull/883)]\n- 文档更新 [[weifeng12x](https://github.com/Chanzhaoyu/chatgpt-web/pull/880)]\n- 依赖更新\n\n## v2.10.8\n\n`2023-03-23`\n\n如遇问题，请删除 `node_modules` 重新安装依赖。\n\n## Feature\n- 显示回复消息原文的选项 [[yilozt](https://github.com/Chanzhaoyu/chatgpt-web/pull/672)]\n- 添加单 `IP` 每小时请求限制。环境变量： `MAX_REQUEST_PER_HOUR` [[zhuxindong ](https://github.com/Chanzhaoyu/chatgpt-web/pull/718)]\n- 前端添加角色设定，仅 `API` 方式可见 [[quzard](https://github.com/Chanzhaoyu/chatgpt-web/pull/768)]\n- `OPENAI_API_MODEL` 变量现在对 `ChatGPTUnofficialProxyAPI` 也生效，注意：`Token` 和 `API` 的模型命名不一致，不能直接填入 `gpt-3.5` 或者 `gpt-4` [[hncboy](https://github.com/Chanzhaoyu/chatgpt-web/pull/632)]\n- 添加繁体中文 `Prompts` [[PeterDaveHello](https://github.com/Chanzhaoyu/chatgpt-web/pull/796)]\n\n## Enhancement\n- 重置回答时滚动定位至该回答 [[shunyue1320](https://github.com/Chanzhaoyu/chatgpt-web/pull/781)]\n- 当 `API` 是 `gpt-4` 时增加可用的 `Max Tokens` [[simonwu53](https://github.com/Chanzhaoyu/chatgpt-web/pull/729)]\n- 判断和忽略回复字符 [[liut](https://github.com/Chanzhaoyu/chatgpt-web/pull/474)]\n- 切换会话时，自动聚焦输入框 [[JS-an](https://github.com/Chanzhaoyu/chatgpt-web/pull/735)]\n- 渲染的链接新窗口打开\n- 查询余额可选 `API_BASE_URL` 代理地址\n- `config` 接口添加验证防止被无限制调用\n- `PWA` 默认不开启，现在需手动修改 `.env` 文件 `VITE_GLOB_APP_PWA` 变量\n- 当网络连接时，刷新页面，`500` 错误页自动跳转到主页\n\n## BugFix\n- `scrollToBottom` 调回 `scrollToBottomIfAtBottom` [[shunyue1320](https://github.com/Chanzhaoyu/chatgpt-web/pull/771)]\n- 重置异常的 `loading` 会话\n\n## Common\n- 创建 `start.cmd` 在 `windows` 下也可以运行 [vulgatecnn](https://github.com/Chanzhaoyu/chatgpt-web/pull/656)]\n- 添加 `visual-studio-code` 中调试配置 [[ChandlerVer5](https://github.com/Chanzhaoyu/chatgpt-web/pull/296)]\n- 修复文档中 `docker` 端口为本地 [[kilvn](https://github.com/Chanzhaoyu/chatgpt-web/pull/802)]\n## Other\n- 依赖更新\n\n\n## v2.10.7\n\n`2023-03-17`\n\n## BugFix\n- 回退 `chatgpt` 版本，原因：导致 `OPENAI_API_BASE_URL` 代理失效\n- 修复缺省状态的 `usingContext` 默认值\n\n## v2.10.6\n\n`2023-03-17`\n\n## Feature\n- 显示 `API` 余额 [[pzcn](https://github.com/Chanzhaoyu/chatgpt-web/pull/582)]\n\n## Enhancement\n- 美化滚动条样式和 `UI` 保持一致 [[haydenull](https://github.com/Chanzhaoyu/chatgpt-web/pull/617)]\n- 优化移动端 `Prompt` 样式 [[CornerSkyless](https://github.com/Chanzhaoyu/chatgpt-web/pull/608)]\n- 上下文开关改为全局开关，现在记录在本地缓存中\n- 配置信息按接口类型显示\n\n## Perf\n- 优化函数方法 [[kirklin](https://github.com/Chanzhaoyu/chatgpt-web/pull/583)]\n- 字符错误 [[pdsuwwz](https://github.com/Chanzhaoyu/chatgpt-web/pull/585)]\n- 文档描述错误 [[lizhongyuan3](https://github.com/Chanzhaoyu/chatgpt-web/pull/636)]\n\n## BugFix\n- 修复 `Prompt` 导入、导出兼容性错误\n- 修复 `highlight.js` 控制台兼容性警告\n\n## Other\n- 依赖更新\n\n## v2.10.5\n\n`2023-03-13`\n\n更新依赖，`access_token` 默认代理为 [pengzhile](https://github.com/pengzhile) 的 `https://bypass.duti.tech/api/conversation`\n\n## Feature\n- `Prompt` 商店在线导入可以导入两种 `recommend.json`里提到的模板 [simonwu53](https://github.com/Chanzhaoyu/chatgpt-web/pull/521)\n- 支持 `HTTPS_PROXY` [whatwewant](https://github.com/Chanzhaoyu/chatgpt-web/pull/308)\n- `Prompt` 添加查询筛选\n\n## Enhancement\n- 调整输入框最大行数 [yi-ge](https://github.com/Chanzhaoyu/chatgpt-web/pull/502)\n- 优化 `docker` 打包 [whatwewant](https://github.com/Chanzhaoyu/chatgpt-web/pull/520)\n- `Prompt` 添加翻译和优化布局\n- 「繁体中文」补全和审阅 [PeterDaveHello](https://github.com/Chanzhaoyu/chatgpt-web/pull/542)\n- 语言选择调整为下路框形式\n- 权限输入框类型调整为密码形式\n\n## BugFix\n- `JSON` 导入检查 [Nothing1024](https://github.com/Chanzhaoyu/chatgpt-web/pull/523)\n- 修复 `AUTH_SECRET_KEY` 模式下跨域异常并添加对 `node.js 19` 版本的支持 [yi-ge](https://github.com/Chanzhaoyu/chatgpt-web/pull/499)\n- 确定清空上下文时不应该重置会话标题\n\n## Other\n- 调整文档\n- 更新依赖\n\n## v2.10.4\n\n`2023-03-11`\n\n## Feature\n- 感谢 [Nothing1024](https://github.com/Chanzhaoyu/chatgpt-web/pull/268) 添加 `Prompt` 模板和 `Prompt` 商店支持\n\n## Enhancement\n- 设置添加关闭按钮[#495]\n\n## Demo\n\n![Prompt](https://camo.githubusercontent.com/6a51af751eb29238cb7ef4f8fbd89f63db837562f97f33273095424e62dc9194/68747470733a2f2f73312e6c6f63696d672e636f6d2f323032332f30332f30342f333036326665633163613562632e676966)\n\n## v2.10.3\n\n`2023-03-10`\n\n> 声明：除 `ChatGPTUnofficialProxyAPI` 使用的非官方代理外，本项目代码包括上游引用包均开源在 `GitHub`，如果你觉得本项目有监控后门或有问题导致你的账号、API被封，那我很抱歉。我可能`BUG`写的多，但我不缺德。此次主要为前端界面调整，周末愉快。\n\n## Feature\n- 支持长回复 [[yi-ge](https://github.com/Chanzhaoyu/chatgpt-web/pull/450)][[详情](https://github.com/Chanzhaoyu/chatgpt-web/pull/450)]\n- 支持 `PWA` [[chenxch](https://github.com/Chanzhaoyu/chatgpt-web/pull/452)]\n\n## Enhancement\n- 调整移动端按钮和优化布局\n- 调整 `iOS` 上安全距离\n- 简化 `docker-compose` 部署 [[cloudGrin](https://github.com/Chanzhaoyu/chatgpt-web/pull/466)]\n\n## BugFix\n- 修复清空会话侧边栏标题不会重置的问题 [[RyanXinOne](https://github.com/Chanzhaoyu/chatgpt-web/pull/453)]\n- 修复设置文字过长时导致的设置按钮消失的问题\n\n## Other\n- 更新依赖\n\n## v2.10.2\n\n`2023-03-09`\n\n衔接 `2.10.1` 版本[详情](https://github.com/Chanzhaoyu/chatgpt-web/releases/tag/v2.10.1)\n\n## Enhancement\n- 移动端下输入框获得焦点时左侧按钮隐藏\n\n## BugFix\n- 修复 `2.10.1` 中添加 `OPENAI_API_MODEL` 变量的判断错误，会导致默认模型指定失效，抱歉\n- 回退 `2.10.1` 中前端变量影响 `Docker` 打包\n\n## v2.10.1\n\n`2023-03-09`\n\n注意：删除了 `.env` 文件改用 `.env.example` 代替，如果是手动部署的同学现在需要手动创建 `.env` 文件并从 `.env.example` 中复制需要的变量，并且 `.env` 文件现在会在 `Git` 提交中被忽略，原因如下：\n\n- 在项目中添加 `.env` 从一开始就是个错误的示范\n- 如果是 `Fork` 项目进行修改测试总是会被 `Git` 修改提示给打扰\n- 感谢 [yi-ge](https://github.com/Chanzhaoyu/chatgpt-web/pull/395) 的提醒和修改\n\n\n这两天开始，官方已经开始对第三方代理进行了拉闸， `accessToken` 即将或已经开始可能会不可使用。异常 `API` 使用也开始封号，封号缘由不明，如果出现使用 `API` 提示错误，请查看后端控制台信息，或留意邮箱。\n\n## Feature\n- 感谢 [CornerSkyless](https://github.com/Chanzhaoyu/chatgpt-web/pull/393) 添加是否发送上下文开关功能\n\n## Enhancement\n- 感谢 [nagaame](https://github.com/Chanzhaoyu/chatgpt-web/pull/415) 优化`docker`打包镜像文件过大的问题\n- 感谢 [xieccc](https://github.com/Chanzhaoyu/chatgpt-web/pull/404) 新增 `API` 模型配置变量 `OPENAI_API_MODEL`\n- 感谢 [acongee](https://github.com/Chanzhaoyu/chatgpt-web/pull/394) 优化输出时滚动条问题\n\n## BugFix\n- 感谢 [CornerSkyless](https://github.com/Chanzhaoyu/chatgpt-web/pull/392) 修复导出图片会丢失头像的问题\n- 修复深色模式导出图片的样式问题\n\n\n## v2.10.0\n\n`2023-03-07`\n\n- 老规矩，手动部署的同学需要删除 `node_modules` 安装包重新安装降低出错概率，其他部署不受影响，但是可能会有缓存问题。\n- 虽然说了更新放缓，但是 `issues` 不看， `PR` 不改我睡不着，我的邮箱从每天早上`8`点到凌晨`12`永远在滴滴滴，所以求求各位，超时的`issues`自己关闭下哈，我真的需要缓冲一下。\n- 演示图片请看最后\n\n## Feature\n- 添加权限功能，用法：`service/.env` 中的 `AUTH_SECRET_KEY` 变量添加密码\n- 感谢 [PeterDaveHello](https://github.com/Chanzhaoyu/chatgpt-web/pull/348) 添加「繁体中文」翻译\n- 感谢 [GermMC](https://github.com/Chanzhaoyu/chatgpt-web/pull/369) 添加聊天记录导入、导出、清空的功能\n- 感谢 [CornerSkyless](https://github.com/Chanzhaoyu/chatgpt-web/pull/374) 添加会话保存为本地图片的功能\n\n\n## Enhancement\n- 感谢 [CornerSkyless](https://github.com/Chanzhaoyu/chatgpt-web/pull/363) 添加 `ctrl+enter`  发送消息\n- 现在新消息只有在结束了之后才滚动到底部，而不是之前的强制性\n- 优化部分代码\n\n## BugFix\n-\t转义状态码前端显示，防止直接暴露 `key`（我可能需要更多的状态码补充）\n\n## Other\n- 更新依赖到最新\n\n## 演示\n> 不是界面最新效果，有美化改动\n\n权限\n\n![权限](https://user-images.githubusercontent.com/24789441/223438518-80d58d42-e344-4e39-b87c-251ff73925ed.png)\n\n聊天记录导出\n\n![聊天记录导出](https://user-images.githubusercontent.com/57023771/223372153-6d8e9ec1-d82c-42af-b4bd-232e50504a25.gif)\n\n保存图片到本地\n\n![保存图片到本地](https://user-images.githubusercontent.com/13901424/223423555-b69b95ef-8bcf-4951-a7c9-98aff2677e18.gif)\n\n## v2.9.3\n\n`2023-03-06`\n\n## Enhancement\n- 感谢 [ChandlerVer5](https://github.com/Chanzhaoyu/chatgpt-web/pull/305) 使用 `markdown-it` 替换 `marked`，解决代码块闪烁的问题\n- 感谢 [shansing](https://github.com/Chanzhaoyu/chatgpt-web/pull/277) 改善文档\n- 感谢 [nalf3in](https://github.com/Chanzhaoyu/chatgpt-web/pull/293) 添加英文翻译\n\n## BugFix\n- 感谢[sepcnt ](https://github.com/Chanzhaoyu/chatgpt-web/pull/279) 修复切换记录时编辑状态未关闭的问题\n- 修复复制代码的兼容性报错问题\n- 修复部分优化小问题\n\n## v2.9.2\n\n`2023-03-04`\n\n手动部署的同学，务必删除根目录和`service`中的`node_modules`重新安装依赖，降低出现问题的概率，自动部署的不需要做改动。\n\n### Feature\n- 感谢 [hyln9](https://github.com/Chanzhaoyu/chatgpt-web/pull/247) 添加对渲染 `LaTex` 数学公式的支持\n- 感谢 [ottocsb](https://github.com/Chanzhaoyu/chatgpt-web/pull/227) 添加支持 `webAPP` (苹果添加到主页书签访问)支持\n- 添加 `OPENAI_API_BASE_URL` 可选环境变量[#249]\n## Enhancement\n- 优化在高分屏上主题内容的最大宽度[#257]\n- 现在文字按单词截断[#215][#225]\n### BugFix\n- 修复动态生成时代码块不能被复制的问题[#251][#260]\n- 修复 `iOS` 移动端输入框不会被键盘顶起的问题[#256]\n- 修复控制台渲染警告\n## Other\n- 更新依赖至最新\n- 修改 `README` 内容\n\n## v2.9.1\n\n`2023-03-02`\n\n### Feature\n- 代码块添加当前代码语言显示和复制功能[#197][#196]\n- 完善多语言，现在可以切换中英文显示\n\n## Enhancement\n- 由[Zo3i](https://github.com/Chanzhaoyu/chatgpt-web/pull/187) 完善 `docker-compose` 部署文档\n\n### BugFix\n- 由 [ottocsb](https://github.com/Chanzhaoyu/chatgpt-web/pull/200) 修复头像修改不同步的问题\n## Other\n- 更新依赖至最新\n- 修改 `README` 内容\n## v2.9.0\n\n`2023-03-02`\n\n### Feature\n- 现在能复制带格式的消息文本\n- 新设计的设定页面，可以自定义姓名、描述、头像（链接方式）\n- 新增`403`和`404`页面以便扩展\n\n## Enhancement\n- 更新 `chatgpt` 使 `ChatGPTAPI` 支持 `gpt-3.5-turbo-0301`（默认）\n- 取消了前端超时限制设定\n\n## v2.8.3\n\n`2023-03-01`\n\n### Feature\n- 消息已输出内容不会因为中断而消失[#167]\n- 添加复制消息按钮[#133]\n\n### Other\n- `README` 添加声明内容\n\n## v2.8.2\n\n`2023-02-28`\n### Enhancement\n- 代码主题调整为 `One Dark - light|dark` 适配深色模式\n### BugFix\n- 修复普通文本代码渲染和深色模式下的问题[#139][#154]\n\n## v2.8.1\n\n`2023-02-27`\n\n### BugFix\n- 修复 `API` 版本不是 `Markdown` 时，普通 `HTML` 代码会被渲染的问题 [#146]\n\n## v2.8.0\n\n`2023-02-27`\n\n- 感谢 [puppywang](https://github.com/Chanzhaoyu/chatgpt-web/commit/628187f5c3348bda0d0518f90699a86525d19018) 修复了 `2.7.0` 版本中关于流输出数据的问题（使用 `nginx` 需要自行配置 `octet-stream` 相关内容）\n\n- 关于为什么使用 `octet-stream` 而不是 `sse`，是因为更好的兼容之前的模式。\n\n- 建议更新到此版本获得比较完整的体验\n\n### Enhancement\n- 优化了部份代码和类型提示\n- 输入框添加换行提示\n- 移动端输入框现在回车为换行，而不是直接提交\n- 移动端双击标题返回顶部，箭头返回底部\n\n### BugFix\n- 流输出数据下的问题[#122]\n- 修复了 `API Key` 下部份代码不换行的问题\n- 修复移动端深色模式部份样式问题[#123][#126]\n- 修复主题模式图标不一致的问题[#126]\n\n## v2.7.3\n\n`2023-02-25`\n\n### Feature\n- 适配系统深色模式 [#118](https://github.com/Chanzhaoyu/chatgpt-web/issues/103)\n### BugFix\n- 修复用户消息能被渲染为 `HTML` 问题 [#117](https://github.com/Chanzhaoyu/chatgpt-web/issues/117)\n\n## v2.7.2\n\n`2023-02-24`\n### Enhancement\n- 消息使用 [github-markdown-css](https://www.npmjs.com/package/github-markdown-css) 进行美化，现在支持全语法\n- 移除测试无用函数\n\n## v2.7.1\n\n`2023-02-23`\n\n因为消息流在 `accessToken` 中存在解析失败和消息不完整等一系列的问题，调整回正常消息形式\n\n### Feature\n- 现在可以中断请求过长没有答复的消息\n- 现在可以删除单条消息\n- 设置中显示当前版本信息\n\n### BugFix\n- 回退 `2.7.0` 的消息不稳定的问题\n\n## v2.7.0\n\n`2023-02-23`\n\n### Feature\n- 使用消息流返回信息，反应更迅速\n\n### Enhancement\n- 样式的一点小改动\n\n## v2.6.2\n\n`2023-02-22`\n### BugFix\n- 还原修改代理导致的异常问题\n\n## v2.6.1\n\n`2023-02-22`\n\n### Feature\n- 新增 `Railway` 部署模版\n\n### BugFix\n- 手动打包 `Proxy` 问题\n\n## v2.6.0\n\n`2023-02-21`\n### Feature\n- 新增对 `网页 accessToken` 调用 `ChatGPT`，更智能不过不太稳定 [#51](https://github.com/Chanzhaoyu/chatgpt-web/issues/51)\n- 前端页面设置按钮显示查看当前后端服务配置\n\n### Enhancement\n- 新增 `TIMEOUT_MS` 环境变量设定后端超时时常（单位：毫秒）[#62](https://github.com/Chanzhaoyu/chatgpt-web/issues/62)\n\n## v2.5.2\n\n`2023-02-21`\n### Feature\n- 增加对 `markdown` 格式的支持 [Demo](https://github.com/Chanzhaoyu/chatgpt-web/pull/77)\n### BugFix\n- 重载会话时滚动条保持\n\n## v2.5.1\n\n`2023-02-21`\n\n### Enhancement\n- 调整路由模式为 `hash`\n- 调整新增会话添加到\n- 调整移动端样式\n\n\n## v2.5.0\n\n`2023-02-20`\n\n### Feature\n- 会话 `loading` 现在显示为光标动画\n- 会话现在可以再次生成回复\n- 会话异常可以再次进行请求\n- 所有删除选项添加确认操作\n\n### Enhancement\n- 调整 `chat` 为路由页面而不是组件形式\n- 更新依赖至最新\n- 调整移动端体验\n\n### BugFix\n- 修复移动端左侧菜单显示不完整的问题\n\n## v2.4.1\n\n`2023-02-18`\n\n### Enhancement\n- 调整部份移动端上的样式\n- 输入框支持换行\n\n## v2.4.0\n\n`2023-02-17`\n\n### Feature\n- 响应式支持移动端\n### Enhancement\n- 修改部份描述错误\n\n## v2.3.3\n\n`2023-02-16`\n\n### Feature\n- 添加 `README` 部份说明和贡献列表\n- 添加 `docker` 镜像\n- 添加 `GitHub Action` 自动化构建\n\n### BugFix\n- 回退依赖更新导致的 [Eslint 报错](https://github.com/eslint/eslint/issues/16896)\n\n## v2.3.2\n\n`2023-02-16`\n\n### Enhancement\n- 更新依赖至最新\n- 优化部份内容\n\n## v2.3.1\n\n`2023-02-15`\n\n### BugFix\n- 修复多会话状态下一些意想不到的问题\n\n## v2.3.0\n\n`2023-02-15`\n### Feature\n- 代码类型信息高亮显示\n- 支持 `node ^16` 版本\n- 移动端响应式初步支持\n- `vite` 中 `proxy` 代理\n\n### Enhancement\n- 调整超时处理范围\n\n### BugFix\n- 修复取消请求错误提示会添加到信息中\n- 修复部份情况下提交请求不可用\n- 修复侧边栏宽度变化闪烁的问题\n\n## v2.2.0\n\n`2023-02-14`\n### Feature\n- 会话和上下文本地储存\n- 侧边栏本地储存\n\n## v2.1.0\n\n`2023-02-14`\n### Enhancement\n- 更新依赖至最新\n- 联想功能移动至前端提交，后端只做转发\n\n### BugFix\n- 修复部份项目检测有关 `Bug`\n- 修复清除上下文按钮失效\n\n## v2.0.0\n\n`2023-02-13`\n### Refactor\n重构并优化大部分内容\n\n## v1.0.5\n\n`2023-02-12`\n\n### Enhancement\n- 输入框焦点，连续提交\n\n### BugFix\n- 修复信息框样式问题\n- 修复中文输入法提交问题\n\n## v1.0.4\n\n`2023-02-11`\n\n### Feature\n- 支持上下文联想\n\n## v1.0.3\n\n`2023-02-11`\n\n### Enhancement\n- 拆分 `service` 文件以便扩展\n- 调整 `Eslint` 相关验证\n\n### BugFix\n- 修复部份控制台报错\n\n## v1.0.2\n\n`2023-02-10`\n\n### BugFix\n- 修复新增信息容器不会自动滚动到问题\n- 修复文本过长不换行到问题 [#1](https://github.com/Chanzhaoyu/chatgpt-web/issues/1)\n"
  },
  {
    "path": "CONTRIBUTING.en.md",
    "content": "# Contribution Guide\nThank you for your valuable time. Your contributions will make this project better! Before submitting a contribution, please take some time to read the getting started guide below.\n\n## Semantic Versioning\nThis project follows semantic versioning. We release patch versions for important bug fixes, minor versions for new features or non-important changes, and major versions for significant and incompatible changes.\n\nEach major change will be recorded in the `changelog`.\n\n## Submitting Pull Request\n1. Fork [this repository](https://github.com/Chanzhaoyu/chatgpt-web) and create a branch from `main`. For new feature implementations, submit a pull request to the `feature` branch. For other changes, submit to the `main` branch.\n2. Install the `pnpm` tool using `npm install pnpm -g`.\n3. Install the `Eslint` plugin for `VSCode`, or enable `eslint` functionality for other editors such as `WebStorm`.\n4. Execute `pnpm bootstrap` in the root directory.\n5. Execute `pnpm install` in the `/service/` directory.\n6. Make changes to the codebase. If applicable, ensure that appropriate testing has been done.\n7. Execute `pnpm lint:fix` in the root directory to perform a code formatting check.\n8. Execute `pnpm type-check` in the root directory to perform a type check.\n9. Submit a git commit, following the [Commit Guidelines](#commit-guidelines).\n10. Submit a `pull request`. If there is a corresponding `issue`, please link it using the [linking-a-pull-request-to-an-issue keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).\n\n## Commit Guidelines\n\nCommit messages should follow the [conventional-changelog standard](https://www.conventionalcommits.org/en/v1.0.0/):\n\n```bash\n<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer]\n```\n\n### Commit Types\n\nThe following is a list of commit types:\n\n- feat: New feature or functionality\n- fix: Bug fix\n- docs: Documentation update\n- style: Code style or component style update\n- refactor: Code refactoring, no new features or bug fixes introduced\n- perf: Performance optimization\n- test: Unit test\n- chore: Other commits that do not modify src or test files\n\n\n## License\n\n[MIT](./license)"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# 贡献指南\n感谢你的宝贵时间。你的贡献将使这个项目变得更好！在提交贡献之前，请务必花点时间阅读下面的入门指南。\n\n## 语义化版本\n该项目遵循语义化版本。我们对重要的漏洞修复发布修订号，对新特性或不重要的变更发布次版本号，对重大且不兼容的变更发布主版本号。\n\n每个重大更改都将记录在 `changelog` 中。\n\n## 提交 Pull Request\n1. Fork [此仓库](https://github.com/Chanzhaoyu/chatgpt-web)，从 `main` 创建分支。新功能实现请发 pull request 到 `feature` 分支。其他更改发到 `main` 分支。\n2. 使用 `npm install pnpm -g` 安装 `pnpm` 工具。\n3. `vscode` 安装了 `Eslint` 插件，其它编辑器如 `webStorm` 打开了 `eslint` 功能。\n4. 根目录下执行 `pnpm bootstrap`。\n5. `/service/` 目录下执行 `pnpm install`。\n6. 对代码库进行更改。如果适用的话，请确保进行了相应的测试。\n7. 请在根目录下执行 `pnpm lint:fix` 进行代码格式检查。\n8. 请在根目录下执行 `pnpm type-check` 进行类型检查。\n9. 提交 git commit, 请同时遵守 [Commit 规范](#commit-指南)\n10. 提交 `pull request`， 如果有对应的 `issue`，请进行[关联](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)。\n\n## Commit 指南\n\nCommit messages 请遵循[conventional-changelog 标准](https://www.conventionalcommits.org/en/v1.0.0/)：\n\n```bash\n<类型>[可选 范围]: <描述>\n\n[可选 正文]\n\n[可选 脚注]\n```\n\n### Commit 类型\n\n以下是 commit 类型列表:\n\n- feat: 新特性或功能\n- fix: 缺陷修复\n- docs: 文档更新\n- style: 代码风格或者组件样式更新\n- refactor: 代码重构，不引入新功能和缺陷修复\n- perf: 性能优化\n- test: 单元测试\n- chore: 其他不修改 src 或测试文件的提交\n\n\n## License\n\n[MIT](./license)\n"
  },
  {
    "path": "Dockerfile",
    "content": "# build front-end\nFROM node:lts-alpine AS frontend\n\nRUN npm install pnpm -g\n# 安装 Git\nRUN apk add --no-cache git\n\nWORKDIR /app\n\nCOPY ./package.json /app\n\nCOPY ./pnpm-lock.yaml /app\n\n#RUN git --version\n\nRUN pnpm install\n\nCOPY . /app\n\nRUN pnpm run build\n\n# build backend\nFROM node:lts-alpine as backend\n\nRUN npm install pnpm -g\n\nWORKDIR /app\n\nCOPY /service/package.json /app\n\nCOPY /service/pnpm-lock.yaml /app\n\nRUN pnpm install\n\nCOPY /service /app\n\nRUN pnpm build\n\n# service\nFROM node:lts-alpine\n\nRUN npm install pnpm -g\n\nWORKDIR /app\n\nCOPY /service/package.json /app\n\nCOPY /service/pnpm-lock.yaml /app\n\nRUN pnpm install --production && rm -rf /root/.npm /root/.pnpm-store /usr/local/share/.cache /tmp/*\n\nCOPY /service /app\n\nCOPY --from=frontend /app/dist /app/public\n\nCOPY --from=backend /app/build /app/build\n\nEXPOSE 3002\n\nCMD [\"pnpm\", \"run\", \"prod\"]\n"
  },
  {
    "path": "README.md",
    "content": "# ChatGPT Web Midjourney Proxy\n\n[English](./README_EN.md) | [Русский язык](./README_RU.md) | [Français](./README_FR.md) | [한국어](./README_KR.md) | [Tiếng Việt](./README_VN.md) | [Türkçe](./README_TR.md)\n\n## 声明\n- 此项目只发布于 GitHub，基于 MIT 协议，免费且作为开源学习使用。并且不会有任何形式的卖号、付费服务、讨论群、讨论组等行为。谨防受骗。\n- 本开源是在 [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web) 基础上做二次开发 ；使用 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 、 Suno-API、[Luma-API](https://github.com/LumaAI-API/Luma-API)  作为后端API而形成的；\n- 可以直接用 https://vercel.ddaiai.com 先体验\n\n![cover](./docs/mj2a1.jpg)\n## 支持功能 \n- [x] 支持 udio 文生音乐\n- [x] 支持 pika  文生视频，图生视频\n- [x] 支持 openai realtime [点击观看.youtube](https://www.youtube.com/watch?v=pKvVi3oBRQU)  [B站](https://www.bilibili.com/video/BV1Kt22YPE2c/) \n- [x] 支持 kling 可灵 文生视频，图生视频, 绘图\n- [x] 支持 ideogram 绘图\n- [x] 支持 runway 文生视频，图生视频\n- [x] 支持 luma 文生视频，图生视频\n- [x] 支持 viggle 舞蹈\n- [x] 支持 suno 单独模块，可歌词调整 曲风调整\n- [x] 支持 suno 以音频生成音频\n- [x] 支持 flux dall.e 文生图\n- [x] 原chatgpt web 所有功能\n- [x] chatgpt web 支持自定义api key、base_url\n- [x] midjourney 文生图、垫图+文生图  、图变 U1到U4 、 V1到V4、重绘等操作\n- [X] midjourney 支持局部重绘、支持1.5倍变焦 2倍变焦、2倍高清 4倍高清\n- [X] midjourney 支持左、右、上、下延伸变化\n- [X] midjourney 同时支持[midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 接口 和 [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus) 接口\n- [X] midjourney 图生文\n- [X] 图片使用localforage实现本地存储\n- [X] 支持midjourney、niji 不同机器人\n- [X] 支持[InsightFace 人脸替换](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] midjourney 混图、获取 seed \n- [X] chatgpt 前端支持自定义模型、上下文对话数、回复数\n- [X] chatgpt 支持图片上传图片 供gpt-4-vision-preview使用、gpts\n- [X] chatgpt 支持超链模型切换 https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] 支持ChatGPT试的超链模型切换 https://chat.openai.com/g/g-2fkFE8rbu 修改为 https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] chatgpt 支持 GPTs 多模态\n- [X] chatgpt 支持 tts whisper dall-e-3 画图\n- [X] 即时语音识别(浏览器自带语音识别 ASR) `v2.15.7`以上版本\n- [X] 支持超链更换设置，适合`one-api` `new-api`部署聊天(<b color=\"red\">为了安全，此方式请使用自己域名</b>) https://mj.your-name.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] 支持`one-api`、`new-api`部署聊天 (<b color=\"red\">为了安全，此方式请使用自己域名</b>) https://mj.your-name.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## 无服务器-个人桌面安装\n> - [x] 请到 https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases 下载最新版本安装(选择合适你操作系统的版本)\n> - [x] 选择一个合适的中转服务商( 最好都支持 `gpt`  `gpts` `midjourney` `claude`  `suno` `luma` `runway` `viggle` `flux` `ideogram` `kling` `pika`)\n> - [x] 中转服务商推荐 https://www.openai-hk.com 一个`key`和`api接口地址` 同时支持 [gpt](https://www.openai-hk.com/docs/getting-started.html) [gpts](https://www.openai-hk.com/docs/openai/gpts.html) [midjourney](https://www.openai-hk.com/docs/midjourney/guide.html) [claude](https://www.openai-hk.com/docs/lab/claude-3.html) [suno](https://www.openai-hk.com/docs/lab/suno-v3.html) [luma](https://www.openai-hk.com/docs/lab/luma-video.html) [runway](https://www.openai-hk.com/docs/lab/runway-video.html) [viggle](https://www.openai-hk.com/docs/lab/viggle-dance.html) [ideogram](https://www.openai-hk.com/docs/lab/ideogram.html) [flux](https://www.openai-hk.com/docs/lab/flux.html) [kling](https://www.openai-hk.com/docs/lab/kling.html) [pika](https://www.openai-hk.com/docs/lab/pika-video.html) [Riffusion](https://www.openai-hk.com/docs/lab/riffusion-music.html)\n![多模态](./docs/suno-ds.jpg)\n\n## Vercel 一键部署\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## env 环境变量\n\n| 环境变量 | 说明 | 默认值 |docker等部署| vercel 部署|\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | OpenAI API 接口地址 | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | OpenAI API 密钥 |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  默认模型 | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  mj proxy 接口地址  |[搭建参考](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  mj proxy | 空  | ✅ |  ✅|\n| SUNO_SERVER |  SUNO API 接口地址  | [搭建参考](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  SUNO API 的key | 空  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  访问授权密码 | 无  | ✅ |   x|\n| API_UPLOADER |  支持上传 | 关闭  | ✅ |  x|\n| HIDE_SERVER |  前端ui隐藏服务端|    | ✅ |  x|\n| CUSTOM_MODELS |  自定义可选模型 `CUSTOM_MODELS=-all,gpt-3.5` | 无  | ✅ |  ✅|\n| TJ_BAIDU_ID |  百度统计ID | 无  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  谷歌统计ID | 无  | ✅ |  ✅|\n| SYS_NOTIFY |  系统通知，支持HTML | 无  | ✅ |  ✅|\n| DISABLE_GPT4 |  禁用GPT-4 | 无  | ✅ |  ✅|\n| GPT_URL | 自定 GPT_URL=/gpts.json  | 无 也可自己的外链 | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | 上传图片大小限制 默认1M |  1 | ✅ |  ✅|\n| SYS_THEME | 默认主题 `light`或者`dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | 是否开启 `wsrv`图床  | 无(关闭)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | 防爆破验证：验证次数触发 NGINX 请设置 `proxy_set_header   X-Forwarded-For  $remote_addr`  | 无  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | 防爆破验证：停留时间 单位分钟  | 无  | ✅ |  x|\n| CLOSE_MD_PREVIEW | 是否不关闭输入预览 | 无  | ✅ |  ✅|\n| UPLOAD_TYPE | 指定上传方式 [`R2` R2上传] [`API` 跟随UI前端中转]、[`Container` 本地容器]、[`MyUrl` 自定义链接]  |  空 | ✅ |  x|\n| MENU_DISABLE  | 菜单禁用 可选:gpts,draws,gallery,music,video,dance,realtime |  空 | ✅ |  ✅|\n| VISION_MODEL  | 默认使用的识图 可选:`gpt-4o`,`gpt-4-turb`,`gpt-4-vision-preview`等 |  空 | ✅ |  ✅|\n| SYSTEM_MESSAGE  | 自定义默认角色消息 |  空 | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | 自定义可视图模型 用`,` 分开 |  空 | ✅ |  ✅|\n| LUMA_SERVER |  LUMA API 接口地址  | [搭建参考](https://github.com/LumaAI-API/Luma-API) | ✅ |  ✅|\n| LUMA_KEY |  LUMA API 的key | 空  | ✅ |  ✅|\n\n  \n\n## docker 部署\n \n> - [x] 需 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 或者[trueai](https://github.com/trueai-org/midjourney-proxy) 支持 \n> - [x] 需 Suno-API  支持\n> - [x] 需 [Luma-API](https://github.com/LumaAI-API/Luma-API)  支持\n\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e LUMA_SERVER=https://your-luma-server:8000  \\\n-e LUMA_KEY=your-luma-key  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\n访问 http://ip:6015 \n\n**文件上传**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\n如果是前端ui设置 OPENAI_API_KEY OPENAI_API_BASE_URL ; 图片上传也会随着走 OPENAI_API_BASE_URL走\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\n返回格式\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### midjourney-proxy API docker部署\n更多参考到 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 开源光光\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=discord服务ID  \\\n-e mj.discord.channel-id=discord服务组ID   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n\n## 更多展示\n\n\n### Realtime \n\n[点击观看Realtime视频](https://www.youtube.com/watch?v=pKvVi3oBRQU) \n\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/realtime-2.jpg\" style=\"width:200px\" > \n</div>\n \n\n### suno、udio 音乐AI制作\n![suno](./docs/suno2.jpg)\n\n### luma runway pika kling 视频AI制作\n![suno](./docs/luma-video.jpg)\n\n\n\n### 自定义服务端api key、base_url：\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Store \n![多模态](./docs/gpts.jpg)\n![多模态](./docs/gpts1.jpg)\n\n### 录音 whisper  和  tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### 局部重绘：\n[![局部重绘](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### 换脸\n![换脸](./docs/mj2a2.jpg)\n\n### 混图\n![混图](./docs/mj2a3.jpg)\n\n### 支持图片上传图片 供gpt-4-vision-preview使用\n![混图](./docs/mj4a1.png)\n手机端：\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n\n## 文件上传 支持cloudflare r2 存储\n\n- cloudflare r2 存储 10 GB/月 免费 https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- 配置文档参考 https://zhuanlan.zhihu.com/p/658058503\n- vercel 不支持 r2 存储\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## 文件服务器请求优先顺序\nR2> 前端UI设置文件服务> 后端文件服务 >跟随中转\n## 防爆破验证设置\n\n![防爆破](./docs/check_error.jpg)\n- [x] vercel 不支持；仅支持Docker化部署\n- [x] 如果前面挂载 `nginx` 请配置 `proxy_set_header   X-Forwarded-For  $remote_addr;`\n- [x] 参数如下: 错误验证3次，只能在10分钟后再验证\n```yml\n# Secret key 注意: 只能拿事英文+数字\nAUTH_SECRET_KEY=my888god\n#爆破：验证次数 注意: 数字 ；nginx 请设置  proxy_set_header   X-Forwarded-For  $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n#爆破：验证停留时间 单位分钟 注意: 是数字\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] 脚本如下\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=你的英文密码 -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n- \n## License\nMIT © [Dooy](./license)\n\n## 其他\n如果觉得这个项目对您有所帮助，请帮忙点个star 或者捐助我们\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## 捐助\n如果我的开源项目对你有帮助，请考虑通过以下任意一种方式赞助: \n<br> `付款备注上您的联系方式`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>微信捐助</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>支付宝捐助</div>\n    </div>\n</div>"
  },
  {
    "path": "README_EN.md",
    "content": "\n# ChatGPT Web Midjourney Proxy\n\n[中文](./README_ZH.md) | [Русский язык](./README_RU.md) | [Français](./README_FR.md) | [한국어](./README_KR.md) | [Tiếng Việt](./README_VN.md) | [Türkçe](./README_TR.md)\n\n## Disclaimer\n- This project is only released on GitHub under the MIT license, free and open-source for learning purposes. There will be no form of account selling, paid services, discussion groups, etc. Beware of scams.\n- This open-source project is developed based on [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web); it uses the midjourney API provided by [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) and [Suno-API]  as the backend.\n\n![cover](./docs/mj2a1.jpg)\n## Supported Features \n- [x] Support Kling for text-to-video, image-to-video, and drawing.\n- [x] Support Ideogram for drawing.\n- [x] Support Runway for text-to-video and image-to-video.\n- [x] Support Luma for text-to-video and image-to-video.\n- [x] Support Viggle for dance.\n- [x] Support Suno for audio-to-audio generation.\n- [x] Support for the standalone Suno module, with adjustable lyrics and music style\n- [x] All original ChatGPT web features\n- [x] ChatGPT web supports custom API keys and base_url\n- [x] Midjourney text-to-image\n- [x] Midjourney blend image + text-to-image  \n- [X] Midjourney image variations U1 to U4, V1 to V4, and redrawing\n- [X] Midjourney partial redrawing\n- [X] Midjourney 1.5x and 2x zoom\n- [X] Midjourney 2x and 4x HD\n- [X] Midjourney extensions to the left, right, top, and bottom\n- [X] Midjourney supports both [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) and [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus)\n- [X] Midjourney text from images\n- [X] Local image storage using localforage\n- [X] Support for different bots like midjourney and niji\n- [X] Support for [InsightFace face replacement](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] Midjourney image blending\n- [X] Midjourney get seed\n- [X] DALL-E-3 image generation\n- [X] ChatGPT front-end model selection\n- [X] ChatGPT front-end supports custom models, context number, and reply count\n- [X] ChatGPT supports image uploads for GPT-4-Vision-Preview\n- [X] ChatGPT supports file backend uploads (for models like GPT-4-All, GPT-4-Gizmo-xxx) by default off, can be enabled with environment variable API_UPLOADER=1\n- [X] ChatGPT supports reverse models like GPT-4-All, GPT-4-V, GPT-4-Gizmo-(gizmo_id)\n- [X] ChatGPT supports hyperlink model switching https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] ChatGPT supports ChatGPT-style hyperlink model switching https://chat.openai.com/g/g-2fkFE8rbu modified to https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] ChatGPT supports GPTs multimodal\n- [X] ChatGPT supports TTS whisper\n- [X] Instant voice recognition (browser's built-in ASR) `v2.15.7` and above\n- [X] Support hyperlink change settings, suitable for `one-api` and `new-api` deployments https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] Support `one-api` and `new-api` deployments https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## Serverless - Personal Desktop Installation\n> - [x] Please download the latest version from https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases (choose the version suitable for your operating system)\n> - [x] Choose an appropriate proxy service (preferably one that supports `gpt`, `gpts`, `midjourney`, `claude`, `suno`)\n> - [x] Recommended proxy service https://www.openai-hk.com a `key` and `api interface address` support `gpt`, `midjourney`, `claude`, `suno` simultaneously, mj-fast as low as 0.12 RMB/image\n![multimodal](./docs/suno-ds.jpg)\n\n## Vercel One-Click Deployment\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## env Environment Variables\n\n| Environment Variable | Description | Default Value | Docker Deployment | Vercel Deployment |\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | OpenAI API interface address | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | OpenAI API key |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  Default model | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  MJ proxy interface address  | [Reference for setup](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  MJ proxy secret | Empty  | ✅ |  ✅|\n| SUNO_SERVER |  SUNO API interface address  | [Reference for setup](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  SUNO API key | Empty  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  Access authorization password | None  | ✅ |   x|\n| API_UPLOADER |  Support upload | Disabled  | ✅ |  x|\n| HIDE_SERVER |  Hide server UI on the front end |    | ✅ |  x|\n| CUSTOM_MODELS |  Custom selectable models | None  | ✅ |  ✅|\n| TJ_BAIDU_ID |  Baidu Analytics ID | None  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  Google Analytics ID | None  | ✅ |  ✅|\n| SYS_NOTIFY |  System notifications, supports HTML | None  | ✅ |  ✅|\n| DISABLE_GPT4 |  Disable GPT-4 | None  | ✅ |  ✅|\n| GPT_URL | Custom GPT_URL=/gpts.json  | None or your external link | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | GPT4V upload image size |  1 | ✅ |  ✅|\n| SYS_THEME | Default theme `light` or `dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | Enable `wsrv` image bed  | None (disabled)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | Brute force prevention: Number of verification attempts NGINX please set `proxy_set_header X-Forwarded-For $remote_addr`  | None  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | Brute force prevention: Wait time in minutes  | None  | ✅ |  x|\n| CLOSE_MD_PREVIEW | Do not close input preview | None  | ✅ |  ✅|\n| UPLOAD_TYPE | Specify upload method [`R2` R2 upload] [`API` Follow UI front-end relay] [`Container` Local container] [`MyUrl` Custom link]  |  Empty | ✅ |  x|\n| MENU_DISABLE  | Disable menu options: gpts, draws, gallery, music |  Empty | ✅ |  ✅|\n| VISION_MODEL  | Default recognition model Options: `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview`, etc. |  Empty | ✅ |  ✅|\n| SYSTEM_MESSAGE  | Custom default role message |  Empty | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | Custom vision models separated by `,` |  Empty | ✅ |  ✅|\n\n## Docker Deployment\n \n> - [x] Requires [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) support\n> - [x] Requires [Suno-API]  support\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatg\n\npt-web-midjourney-proxy\n```\nAccess http://ip:6015 \n\n**File Upload**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\nIf the front-end UI sets OPENAI_API_KEY and OPENAI_API_BASE_URL, the image upload will also follow the OPENAI_API_BASE_URL.\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\nReturn format\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### Midjourney-proxy API Docker Deployment\nFor more references, go to [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) open-source project.\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=Discord Server ID  \\\n-e mj.discord.channel-id=Discord Server Group ID   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n## More Demonstrations\n\n### Custom Server API Key, Base_URL:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Store \n![multimodal](./docs/gpts.jpg)\n![multimodal](./docs/gpts1.jpg)\n\n### Suno Music Creation\n![suno](./docs/suno.jpg)\n\n### Recording Whisper and TTS\n![whisper--tts](./docs/tts-whisper.png)\n\n### Partial Redraw:\n[![Partial Redraw](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### Face Replacement\n![Face Replacement](./docs/mj2a2.jpg)\n\n### Image Blending\n![Image Blending](./docs/mj2a3.jpg)\n\n### Support for Image Upload for GPT-4-Vision-Preview\n![Image Blending](./docs/mj4a1.png)\nMobile:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n## File Upload Support for Cloudflare R2 Storage\n\n- Cloudflare R2 storage 10 GB/month free https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- Configuration reference https://zhuanlan.zhihu.com/p/658058503\n- Vercel does not support R2 storage\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## File Server Request Priority\nR2 > Front-end UI set file service > Backend file service > Follow proxy\n## Brute Force Prevention Settings\n\n![Brute Force Prevention](./docs/check_error.jpg)\n- [x] Vercel is not supported; only Docker deployment is supported\n- [x] If NGINX is mounted in front, configure `proxy_set_header X-Forwarded-For $remote_addr;`\n- [x] Parameters: 3 failed verification attempts, can only reattempt after 10 minutes\n```yml\n# Secret key Note: Only alphanumeric characters\nAUTH_SECRET_KEY=my888god\n# Brute force: verification attempts Note: Number; NGINX please set proxy_set_header X-Forwarded-For $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n# Brute force: wait time in minutes Note: Number\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] Script:\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=your-english-password -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n\n## License\nMIT © [Dooy](./license)\n\n## Others\nIf you find this project helpful, please consider giving it a star or donating to us.\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## Donations\nIf my open-source project is helpful to you, please consider sponsoring me through any of the following methods: \n<br> `Payment remarks with your contact information`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>WeChat Donation</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Alipay Donation</div>\n    </div>\n</div>"
  },
  {
    "path": "README_FR.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**Déclaration**\n- Ce projet n'est publié que sur GitHub, sous licence MIT, gratuit et destiné à un usage d'apprentissage open source. Il n'y aura aucune vente de comptes, service payant, groupe de discussion, etc. Soyez vigilant face aux arnaques.\n- Ce projet open source est basé sur [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web) et utilise l'API midjourney de [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) et [Suno-API](https://github.com/SunoAI-API/Suno-API) comme backend.\n\n\n![couverture](./docs/mj2a1.jpg)\n## Fonctionnalités prises en charge \n- [x] Prise en charge du module Suno, ajustement des paroles et du style musical\n- [x] Toutes les fonctionnalités de chatgpt web\n- [x] chatgpt web prend en charge la personnalisation de l'API key et de base_url\n- [x] Création d'images par texte avec midjourney\n- [x] Image de base + création d'images par texte avec midjourney\n- [X] Opérations de variation (U1 à U4, V1 à V4, redessiner) avec midjourney\n- [X] Redessin partiel avec midjourney\n- [X] Zoom 1,5x et 2x avec midjourney\n- [X] Haute définition 2x et 4x avec midjourney\n- [X] Extension à gauche, droite, haut et bas avec midjourney\n- [X] Prise en charge des interfaces [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) et [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus) avec midjourney\n- [X] Création de texte par image avec midjourney\n- [X] Stockage local des images avec localforage\n- [X] Prise en charge des robots midjourney et niji\n- [X] Prise en charge du remplacement de visage [InsightFace](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] Mélange d'images avec midjourney\n- [X] Obtention de seed avec midjourney\n- [X] Création d'images avec dall-e-3\n- [X] Sélection de modèle en frontend avec chatgpt\n- [X] Prise en charge de la personnalisation des modèles, du nombre de dialogues et de réponses en frontend avec chatgpt\n- [X] Prise en charge du téléchargement d'images pour gpt-4-vision-preview avec chatgpt\n- [X] Prise en charge du téléchargement de fichiers en backend pour les modèles gpt-4-all, gpt-4-gizmo-xxx (désactivé par défaut, activation par variable d'environnement API_UPLOADER=1)\n- [X] Prise en charge des modèles inversés gpt-4-all, gpt-4-v, gpt-4-gizmo-(gizmo_id) avec chatgpt\n- [X] Prise en charge du changement de modèle par lien hypertexte https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] Prise en charge du changement de modèle par lien hypertexte pour ChatGPT https://chat.openai.com/g/g-2fkFE8rbu modifié en https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] Prise en charge des modèles multi-modaux GPTs avec chatgpt\n- [X] Prise en charge de tts whisper avec chatgpt\n- [X] Reconnaissance vocale instantanée (ASR intégré au navigateur) à partir de la version `v2.15.7`\n- [X] Prise en charge de la modification des paramètres par lien hypertexte, adapté pour les déploiements `one-api` et `new-api` de chat https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] Prise en charge des déploiements de chat `one-api` et `new-api` https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## Installation sur ordinateur personnel sans serveur\n> - [x] Téléchargez la dernière version sur https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases (choisissez la version adaptée à votre système d'exploitation)\n> - [x] Choisissez un service de relais approprié (de préférence supportant `gpt`, `gpts`, `midjourney`, `claude`, `suno`)\n> - [x] Service de relais recommandé https://www.openai-hk.com, un `key` et une `adresse d'interface API` supportant simultanément `gpt`, `midjourney`, `claude`, `suno`, avec un coût minimum de 0,12 RMB par image pour mj-fast\n![multi-modale](./docs/suno-ds.jpg)\n\n## Déploiement en un clic sur Vercel\n\n[![Déployer avec Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## Variables d'environnement (env)\n\n| Variable d'environnement | Description | Valeur par défaut | Déploiement docker | Déploiement vercel |\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | Adresse de l'interface API OpenAI | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | Clé API OpenAI |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  Modèle par défaut | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  Adresse de l'interface mj proxy  |[Référence d'installation](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  Secret API mj proxy | vide  | ✅ |  ✅|\n| SUNO_SERVER |  Adresse de l'interface API SUNO  | [Référence d'installation](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  Clé API SUNO | vide  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  Mot de passe d'accès autorisé | Aucun  | ✅ |   x|\n| API_UPLOADER |  Support de téléchargement | Désactivé  | ✅ |  x|\n| HIDE_SERVER |  Masquer le serveur dans l'interface utilisateur |    | ✅ |  x|\n| CUSTOM_MODELS |  Modèles personnalisés disponibles | Aucun  | ✅ |  ✅|\n| TJ_BAIDU_ID |  ID de statistiques Baidu | Aucun  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  ID de statistiques Google | Aucun  | ✅ |  ✅|\n| SYS_NOTIFY |  Notification système, supporte HTML | Aucun  | ✅ |  ✅|\n| DISABLE_GPT4 |  Désactiver GPT-4 | Aucun  | ✅ |  ✅|\n| GPT_URL | URL personnalisée GPT_URL=/gpts.json  | Aucune ou lien externe personnalisé | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | Taille de l'image uploadée pour gpt4v |  1 | ✅ |  ✅|\n| SYS_THEME | Thème par défaut `light` ou `dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | Activer le stockage d'images `wsrv`  | Aucun (désactivé)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | Vérification anti-brute-force : Nombre de tentatives de vérification, NGINX doit définir `proxy_set_header X-Forwarded-For $remote_addr`  | Aucun  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | Vérification anti-brute-force : Temps d'attente en minutes  | Aucun  | ✅ |  x|\n| CLOSE_MD_PREVIEW | Désactiver l'aperçu en entrée | Aucun  | ✅ |  ✅|\n| UPLOAD_TYPE | Type de téléchargement spécifié [`R2` pour R2] [`API` via l'interface utilisateur] [`Container` pour le stockage local] [`MyUrl` pour un lien personnalisé]  |  vide | ✅ |  x|\n| MENU_DISABLE  | Désactiver des menus sélectionnés : gpts, draws, gallery, music\n\n |  vide | ✅ |  ✅|\n| VISION_MODEL  | Modèle de reconnaissance par défaut : `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview`, etc. |  vide | ✅ |  ✅|\n| SYSTEM_MESSAGE  | Message de rôle par défaut personnalisé |  vide | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | Modèles de vision personnalisés, séparés par des virgules |  vide | ✅ |  ✅|\n\n## Déploiement docker\n \n> - [x] Nécessite [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) \n> - [x] Nécessite [Suno-API](https://github.com/SunoAI-API/Suno-API) \n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\nAccédez à http://ip:6015 \n\n**Téléchargement de fichiers**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\nSi la configuration de l'interface utilisateur FRONT-END est OPENAI_API_KEY et OPENAI_API_BASE_URL; le téléchargement d'images suivra également OPENAI_API_BASE_URL.\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\nRéponse formatée\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### Déploiement de l'API midjourney-proxy avec docker\nRéférez-vous à [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) pour plus de détails\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=ID du serveur discord  \\\n-e mj.discord.channel-id=ID du groupe discord   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n\n## Plus d'exemples\n\n### API key et base_url personnalisés en serveur:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Store \n![multi-modale](./docs/gpts.jpg)\n![multi-modale](./docs/gpts1.jpg)\n\n### Création musicale avec suno\n![suno](./docs/suno.jpg)\n\n\n### Enregistrement whisper et tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### Redessin partiel:\n[![redessin partiel](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### Remplacement de visage\n![remplacement de visage](./docs/mj2a2.jpg)\n\n### Mélange d'images\n![mélange d'images](./docs/mj2a3.jpg)\n\n### Prise en charge du téléchargement d'images pour gpt-4-vision-preview\n![gpt-4-vision-preview](./docs/mj4a1.png)\nMobile:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n\n## Téléchargement de fichiers avec stockage cloudflare r2\n\n- Stockage gratuit jusqu'à 10 Go/mois avec cloudflare r2 https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- Documentation de configuration https://zhuanlan.zhihu.com/p/658058503\n- Vercel ne supporte pas le stockage r2\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## Ordre de priorité des demandes au serveur de fichiers\nR2 > Configuration de l'interface utilisateur > Serveur de fichiers backend > Relais\n## Paramètres de vérification anti-brute-force\n\n![anti-brute-force](./docs/check_error.jpg)\n- [x] Vercel ne supporte pas ; uniquement supporté pour les déploiements Docker\n- [x] Si nginx est utilisé en amont, configurez `proxy_set_header X-Forwarded-For $remote_addr;`\n- [x] Paramètres : 3 tentatives, vérification possible après 10 minutes\n```yml\n# Clé secrète : utilisez uniquement des lettres et des chiffres\nAUTH_SECRET_KEY=my888god\n# anti-brute-force : nombre de tentatives. Pour nginx, configurez proxy_set_header X-Forwarded-For $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n# anti-brute-force : temps d'attente en minutes\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] Script\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=mot-de-passe -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n\n## Licence\nMIT © [Dooy](./license)\n\n## Autre\nSi vous trouvez ce projet utile, veuillez nous soutenir en mettant une étoile ou en faisant un don.\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## Donation\nSi mon projet open source vous a été utile, veuillez envisager de faire un don via l'une des méthodes suivantes :\n<br> `Mentionnez vos coordonnées dans la note de paiement`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>Don via WeChat</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Don via Alipay</div>\n    </div>\n</div>"
  },
  {
    "path": "README_KR.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**선언**\n- 이 프로젝트는 GitHub에만 게시되며, MIT 라이센스를 기반으로 무료로 오픈 소스 학습용으로 사용됩니다. 어떤 형태의 계정 판매, 유료 서비스, 토론 그룹 등의 행위도 없으니 사기를 조심하십시오.\n- 이 오픈 소스는 [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web)를 기반으로 2차 개발된 것이며, [midjourney-proxy](https://github.com/novicezk/midjourney-proxy)가 제공하는 midjourney API와 [Suno-API](https://github.com/SunoAI-API/Suno-API)를 백엔드로 사용하여 형성되었습니다.\n\n![cover](./docs/mj2a1.jpg)\n## 지원 기능\n- [x] suno 단독 모듈 지원, 가사 조정, 곡 스타일 조정 가능\n- [x] 원래 chatgpt 웹의 모든 기능\n- [x] chatgpt 웹 지원 사용자 정의 API 키, base_url\n- [x] midjourney 텍스트로 이미지 생성\n- [x] midjourney 텍스트와 이미지로 이미지 생성\n- [X] midjourney 이미지 변환 U1에서 U4, V1에서 V4, 재그리기 등 작업\n- [X] midjourney 부분 재그리기 지원\n- [X] midjourney 1.5배 확대, 2배 확대 지원\n- [X] midjourney 2배 HD, 4배 HD 지원\n- [X] midjourney 좌, 우, 상, 하 확장 지원\n- [X] midjourney와 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 인터페이스 및 [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus) 인터페이스 동시 지원\n- [X] midjourney 이미지에서 텍스트 생성\n- [X] localforage를 사용한 이미지 로컬 저장\n- [X] midjourney 및 niji 다양한 로봇 지원\n- [X] [InsightFace 얼굴 교체](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot) 지원\n- [X] midjourney 이미지 합성\n- [X] midjourney 시드 가져오기\n- [X] dall-e-3 이미지 생성\n- [X] chatgpt 프론트엔드 모델 선택\n- [X] chatgpt 프론트엔드 사용자 정의 모델, 대화 수, 응답 수 지원\n- [X] chatgpt 이미지 업로드 지원 gpt-4-vision-preview 사용\n- [X] chatgpt 파일 백엔드 업로드 지원(gpt-4-all, gpt-4-gizmo-xxx 모델) 기본적으로 비활성화됨, 활성화하려면 환경 변수 API_UPLOADER=1 필요\n- [X] chatgpt 역모델 지원 gpt-4-all, gpt-4-v, gpt-4-gizmo-(gizmo_id)\n- [X] chatgpt 초링크 모델 전환 지원 https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] ChatGPT 실시간 초링크 모델 전환 지원 https://chat.openai.com/g/g-2fkFE8rbu를 https://vercel.ddaiai.com/#/g/g-2fkFE8rbu로 변경\n- [X] chatgpt GPTs 다중 모드 지원\n- [X] chatgpt tts whisper 지원\n- [X] 즉시 음성 인식(브라우저 기본 음성 인식 ASR) `v2.15.7` 이상 버전\n- [X] 초링크 설정 변경 지원, `one-api`, `new-api` 배포 채팅에 적합 https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] `one-api`, `new-api` 배포 채팅 지원 https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## 서버리스 - 개인 데스크탑 설치\n> - [x] https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases에서 최신 버전 다운로드(운영 체제에 적합한 버전 선택)\n> - [x] 적합한 중계 서비스 제공업체 선택(`gpt`, `gpts`, `midjourney`, `claude`, `suno`를 모두 지원하는 것이 좋음)\n> - [x] 중계 서비스 제공업체 추천 https://www.openai-hk.com 하나의 `key`와 `api 인터페이스 주소` 동시에 `gpt`, `midjourney`, `claude`, `suno` 지원, mj-fast 최소 0.12rmb/장\n![다중 모드](./docs/suno-ds.jpg)\n\n## Vercel 원클릭 배포\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## env 환경 변수\n\n| 환경 변수 | 설명 | 기본값 |docker 등 배포| vercel 배포|\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | OpenAI API 인터페이스 주소 | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | OpenAI API 키 |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  기본 모델 | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  mj 프록시 인터페이스 주소 |[구축 참고](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  mj 프록시 | 비어 있음  | ✅ |  ✅|\n| SUNO_SERVER |  SUNO API 인터페이스 주소 | [구축 참고](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  SUNO API 키 | 비어 있음  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  접근 권한 암호 | 없음  | ✅ |   x|\n| API_UPLOADER |  업로드 지원 | 비활성화됨  | ✅ |  x|\n| HIDE_SERVER |  프론트엔드 UI 서버 숨김 |    | ✅ |  x|\n| CUSTOM_MODELS |  사용자 정의 선택 가능한 모델 | 없음  | ✅ |  ✅|\n| TJ_BAIDU_ID |  Baidu 통계 ID | 없음  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  Google 통계 ID | 없음  | ✅ |  ✅|\n| SYS_NOTIFY |  시스템 알림, HTML 지원 | 없음  | ✅ |  ✅|\n| DISABLE_GPT4 |  GPT-4 비활성화 | 없음  | ✅ |  ✅|\n| GPT_URL | 사용자 정의 GPT_URL=/gpts.json  | 없음, 외부 링크도 가능 | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | gpt4v 업로드 이미지 크기 |  1 | ✅ |  ✅|\n| SYS_THEME | 기본 테마 `light` 또는 `dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | `wsrv` 이미지 서버 활성화 여부  | 비활성화  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | 폭파 방지 검증: 검증 횟수 NGINX 설정 `proxy_set_header X-Forwarded-For $remote_addr`  | 없음  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | 폭파 방지 검증: 대기 시간 단위 분  | 없음  | ✅ |  x|\n| CLOSE_MD_PREVIEW | 입력 미리보기 비활성화 | 없음  | ✅ |  ✅|\n| UPLOAD_TYPE | 업로드 방식 지정 [`R2` R2 업로드] [`API` UI 프론트엔드 중계] [`Container` 로컬 컨테이너] [`MyUrl` 사용자 정의 링크]  |  비어 있음 | ✅ |  x|\n| MENU_DISABLE  | 메뉴 비활성화 옵션: gpts, draws, gallery, music |  비어 있음 | ✅ |  ✅|\n| VISION_MODEL  | 기본 사용 이미지 인식 모델: `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview` 등 |  비어 있음 | ✅ |  ✅|\n| SYSTEM_MESSAGE\n\n  | 사용자 정의 기본 역할 메시지 |  비어 있음 | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | 사용자 정의 이미지 인식 모델, 쉼표로 구분 |  비어 있음 | ✅ |  ✅|\n\n## docker 배포\n\n> - [x] [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 지원 필요\n> - [x] [Suno-API](https://github.com/SunoAI-API/Suno-API) 지원 필요\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\n접속 http://ip:6015 \n\n**파일 업로드**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\n프론트엔드 UI에서 OPENAI_API_KEY OPENAI_API_BASE_URL 설정 시; 이미지 업로드도 OPENAI_API_BASE_URL로 진행\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\n반환 형식\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### midjourney-proxy API docker 배포\n자세한 내용은 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 오픈 소스를 참조\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=discord 서비스 ID  \\\n-e mj.discord.channel-id=discord 서비스 그룹 ID   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n## 더 많은 예시\n\n### 사용자 정의 서버 API 키, base_url:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS GTP Store \n![다중 모드](./docs/gpts.jpg)\n![다중 모드](./docs/gpts1.jpg)\n\n### suno 음악 제작\n![suno](./docs/suno.jpg)\n\n### 녹음 whisper와 tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### 부분 재그리기:\n[![부분 재그리기](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### 얼굴 교체\n![얼굴 교체](./docs/mj2a2.jpg)\n\n### 이미지 합성\n![이미지 합성](./docs/mj2a3.jpg)\n\n### gpt-4-vision-preview 사용을 위한 이미지 업로드 지원\n![이미지 합성](./docs/mj4a1.png)\n모바일:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n## 파일 업로드 Cloudflare R2 저장소 지원\n\n- Cloudflare R2 저장소 10 GB/월 무료 https://www.cloudflare.com/ko-kr/developer-platform/r2/\n- 구성 문서 참고 https://zhuanlan.zhihu.com/p/658058503\n- Vercel은 R2 저장소를 지원하지 않음\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## 파일 서버 요청 우선순위\nR2 > 프론트엔드 UI 설정 파일 서버 > 백엔드 파일 서버 > 중계\n## 폭파 방지 검증 설정\n\n![폭파 방지](./docs/check_error.jpg)\n- [x] Vercel은 지원하지 않음; Docker 배포만 지원\n- [x] 앞에 `nginx`를 장착한 경우 `proxy_set_header X-Forwarded-For $remote_addr;` 설정 필요\n- [x] 매개변수는 다음과 같음: 3회 검증 오류 시 10분 후에만 다시 검증 가능\n```yml\n# 암호 주의: 영어 + 숫자만 사용\nAUTH_SECRET_KEY=my888god\n#폭파: 검증 횟수 주의: 숫자; nginx 설정 proxy_set_header X-Forwarded-For $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n#폭파: 검증 대기 시간 단위 분 주의: 숫자\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] 스크립트는 다음과 같음\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=your_english_password -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n\n## 라이센스\nMIT © [Dooy](./license)\n\n## 기타\n이 프로젝트가 유용하다고 생각되면 star를 주거나 후원을 부탁드립니다\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## 후원\n제 오픈 소스 프로젝트가 도움이 되었다면, 아래 방법 중 하나로 후원을 고려해 주세요: \n<br> `결제 메모에 연락처를 남겨 주세요`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>WeChat 후원</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Alipay 후원</div>\n    </div>\n</div>"
  },
  {
    "path": "README_RU.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**Заявление**\n- Этот проект опубликован только на GitHub, основан на лицензии MIT, бесплатен и предназначен для использования в качестве учебного ресурса с открытым исходным кодом. Не предусмотрены никакие формы продажи аккаунтов, платных услуг, обсуждательных групп и т.д. Остерегайтесь мошенничества.\n- Этот проект создан на основе [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web); используется midjourney API, предоставляемый [midjourney-proxy](https://github.com/novicezk/midjourney-proxy), и [Suno-API](https://github.com/SunoAI-API/Suno-API) в качестве backend.\n\n![cover](./docs/mj2a1.jpg)\n## Поддерживаемые функции\n- [x] Поддержка отдельного модуля suno, регулировка текста песни, изменение стиля музыки\n- [x] Все функции оригинального chatgpt web\n- [x] Chatgpt web поддерживает настраиваемый api key и base_url\n- [x] Midjourney генерация изображений по тексту\n- [x] Midjourney создание изображений по тексту и изображению\n- [X] Midjourney U1-U4, V1-V4, перерисовка и другие действия\n- [X] Midjourney поддержка частичной перерисовки\n- [X] Midjourney поддержка увеличения в 1.5 раза, в 2 раза\n- [X] Midjourney поддержка 2x HD, 4x HD\n- [X] Midjourney поддержка изменения влево, вправо, вверх, вниз\n- [X] Midjourney поддержка [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) и [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus)\n- [X] Midjourney генерация текста по изображению\n- [X] Локальное хранение изображений с использованием localforage\n- [X] Поддержка различных ботов midjourney, niji\n- [X] Поддержка [InsightFace замена лица](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] Midjourney смешивание изображений\n- [X] Midjourney получение seed\n- [X] DALL-E-3 генерация изображений\n- [X] Выбор модели на frontend chatgpt\n- [X] Поддержка пользовательских моделей, количества контекстных диалогов, количества ответов на frontend chatgpt\n- [X] Поддержка загрузки изображений для gpt-4-vision-preview\n- [X] Поддержка загрузки файлов на backend (для моделей gpt-4-all, gpt-4-gizmo-xxx). По умолчанию отключено, для включения требуется переменная окружения API_UPLOADER=1\n- [X] Поддержка обратных моделей gpt-4-all, gpt-4-v, gpt-4-gizmo-(gizmo_id)\n- [X] Поддержка переключения гиперссылок на модели https://vercel.ddaiai.com/#/m/gpt-4-all, https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] Поддержка переключения гиперссылок на модели ChatGPT https://chat.openai.com/g/g-2fkFE8rbu на https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] Поддержка ChatGPT с несколькими модальностями GPTs\n- [X] Поддержка tts whisper\n- [X] Мгновенное распознавание речи (ASR браузера) `v2.15.7` и выше\n- [X] Поддержка изменения настроек гиперссылок, подходящих для деплоя `one-api`, `new-api` чата https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] Поддержка деплоя `one-api`, `new-api` чата https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## Установка на рабочем столе без сервера\n> - [x] Перейдите по ссылке https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases и скачайте последнюю версию (выберите версию, подходящую для вашей операционной системы)\n> - [x] Выберите подходящего провайдера прокси-сервера (лучше всего, чтобы он поддерживал `gpt`, `gpts`, `midjourney`, `claude`, `suno`)\n> - [x] Рекомендуемый провайдер прокси-сервера https://www.openai-hk.com, один `key` и `api интерфейс`, поддерживающий одновременно `gpt`, `midjourney`, `claude`, `suno`, mj-fast от 0.12rmb/изображение\n![многомодальность](./docs/suno-ds.jpg)\n\n## Однократное развертывание Vercel\n\n[![Развернуть с Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## Переменные окружения\n\n| Переменная окружения | Описание | Значение по умолчанию | docker и другие развертывания | развертывание vercel |\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | Адрес OpenAI API | https://api.openai.com | ✅ |  ✅ |\n| OPENAI_API_KEY | Ключ OpenAI API | sk-xxxxx | ✅ |  ✅ |\n| OPENAI_API_MODEL | Модель по умолчанию | gpt-3.5-turbo | ✅ |  ✅ |\n| MJ_SERVER | Адрес midjourney proxy API | [Инструкция по установке](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅ |\n| MJ_API_SECRET | Секретный ключ midjourney proxy | пусто | ✅ |  ✅ |\n| SUNO_SERVER | Адрес SUNO API | [Инструкция по установке](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅ |\n| SUNO_KEY | Ключ SUNO API | пусто | ✅ |  ✅ |\n| AUTH_SECRET_KEY | Пароль для доступа | нет | ✅ |   x |\n| API_UPLOADER | Поддержка загрузки | отключено | ✅ |  x |\n| HIDE_SERVER | Скрыть сервер в интерфейсе | нет | ✅ |  x |\n| CUSTOM_MODELS | Настраиваемые модели | нет | ✅ |  ✅ |\n| TJ_BAIDU_ID | ID статистики Baidu | нет | ✅ |  ✅ |\n| TJ_GOOGLE_ID | ID статистики Google | нет | ✅ |  ✅ |\n| SYS_NOTIFY | Системные уведомления, поддержка HTML | нет | ✅ |  ✅ |\n| DISABLE_GPT4 | Отключить GPT-4 | нет | ✅ |  ✅ |\n| GPT_URL | URL для кастомных моделей GPT | нет | ✅ |  ✅ |\n| UPLOAD_IMG_SIZE | Максимальный размер загружаемого изображения для gpt4v | 1 | ✅ |  ✅ |\n| SYS_THEME | Тема по умолчанию `light` или `dark` | dark | ✅ |  ✅ |\n| MJ_IMG_WSRV | Включить wsrv для изображений | нет | ✅ |  ✅ |\n| AUTH_SECRET_ERROR_COUNT | Количество попыток для защиты от перебора паролей | нет | ✅ |  x |\n| AUTH_SECRET_ERROR_TIME | Время блокировки при защите от перебора паролей (в минутах) | нет | ✅ |  x |\n| CLOSE_MD_PREVIEW | Отключить предпросмотр Markdown | нет | ✅ |  ✅ |\n| UPLOAD_TYPE | Метод загрузки: [`R2` R2 загрузка], [`API` через frontend UI], [`Container` локальное], [`MyUrl` кастомный URL] | пусто | ✅ |  x |\n| MENU_DISABLE  | Отключение меню: gpts,draws,gallery,music | пусто | ✅ |  ✅ |\n| VISION_MODEL  | Модель для распознавания изображений: `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview` | пусто | ✅ | \n\n ✅ |\n| SYSTEM_MESSAGE  | Кастомное сообщение по умолчанию | пусто | ✅ |  ✅ |\n| CUSTOM_VISION_MODELS  | Кастомные модели для распознавания изображений, разделенные запятыми | пусто | ✅ |  ✅ |\n\n## Развертывание с помощью Docker\n\n> - [x] Требуется поддержка [midjourney-proxy](https://github.com/novicezk/midjourney-proxy)\n> - [x] Требуется поддержка [Suno-API](https://github.com/SunoAI-API/Suno-API)\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\nДоступ по адресу http://ip:6015\n\n**Загрузка файлов**:\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\nЕсли в интерфейсе установлены OPENAI_API_KEY и OPENAI_API_BASE_URL; загрузка изображений будет следовать за OPENAI_API_BASE_URL\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\nВозвращаемый формат\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### Развертывание midjourney-proxy API через Docker\nДополнительные инструкции смотрите на [midjourney-proxy](https://github.com/novicezk/midjourney-proxy)\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=ID сервера discord  \\\n-e mj.discord.channel-id=ID канала discord   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n## Дополнительные примеры\n\n### Кастомный api key и base_url для сервера:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Store \n![многомодальность](./docs/gpts.jpg)\n![многомодальность](./docs/gpts1.jpg)\n\n### Создание музыки с помощью suno\n![suno](./docs/suno.jpg)\n\n### Запись и tts whisper\n![whisper--tts](./docs/tts-whisper.png)\n\n### Частичная перерисовка:\n[![Частичная перерисовка](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### Замена лица\n![Замена лица](./docs/mj2a2.jpg)\n\n### Смешивание изображений\n![Смешивание изображений](./docs/mj2a3.jpg)\n\n### Загрузка изображений для gpt-4-vision-preview\n![Загрузка изображений](./docs/mj4a1.png)\nНа мобильных устройствах:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n## Загрузка файлов с поддержкой cloudflare r2\n\n- cloudflare r2 до 10 ГБ в месяц бесплатно https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- Инструкции по настройке https://zhuanlan.zhihu.com/p/658058503\n- Vercel не поддерживает r2\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## Приоритет запросов на файловый сервер\nR2> Настройки файлового сервера в UI> Сервис backend > прокси\n## Защита от перебора паролей\n\n![Защита от перебора паролей](./docs/check_error.jpg)\n- [x] Vercel не поддерживает; поддержка только для развертывания Docker\n- [x] Если используется nginx, настройте `proxy_set_header   X-Forwarded-For  $remote_addr;`\n- [x] Пример настроек: 3 попытки, блокировка на 10 минут\n```yml\n# Секретный ключ: только латиница и цифры\nAUTH_SECRET_KEY=my888god\n# Защита от перебора: количество попыток\nAUTH_SECRET_ERROR_COUNT=3\n# Защита от перебора: время блокировки в минутах\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] Пример скрипта\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=ваш_секретный_ключ -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n\n## Лицензия\nMIT © [Dooy](./license)\n\n## Прочее\nЕсли вы считаете, что этот проект был вам полезен, пожалуйста, поставьте звезду или сделайте пожертвование\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## Пожертвования\nЕсли мои проекты с открытым исходным кодом помогли вам, пожалуйста, рассмотрите возможность сделать пожертвование:\n<br> `Укажите ваши контактные данные в примечании к платежу`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>Пожертвование через WeChat</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Пожертвование через Alipay</div>\n    </div>\n</div>"
  },
  {
    "path": "README_TR.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**Beyan**\n- Bu proje sadece GitHub'da yayımlanmaktadır, MIT lisansı altında ücretsiz ve açık kaynak öğrenimi amacıyla kullanılmaktadır. Hiçbir şekilde hesap satışı, ücretli hizmet, tartışma grubu veya tartışma odası gibi faaliyetler bulunmamaktadır. Dolandırıcılıklara karşı dikkatli olun.\n- Bu açık kaynak proje, [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web) temel alınarak geliştirilmiştir; [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) tarafından sağlanan midjourney api ve [Suno-API](https://github.com/SunoAI-API/Suno-API) arka uç olarak kullanılmıştır;\n\n![cover](./docs/mj2a1.jpg)\n## Desteklenen Özellikler\n- [x] suno tek başına modül desteği, şarkı sözleri ve müzik tarzı ayarlama\n- [x] Orijinal chatgpt web tüm özellikleri\n- [x] chatgpt web özel api key, base_url desteği\n- [x] midjourney metinden görüntü oluşturma\n- [x] midjourney görüntü üzerine metin ekleme\n- [X] midjourney görüntü değişiklikleri U1'den U4'e, V1'den V4'e ve yeniden çizim gibi işlemler\n- [X] midjourney yerel yeniden çizim desteği\n- [X] midjourney 1.5x ve 2x yakınlaştırma desteği\n- [X] midjourney 2x ve 4x yüksek çözünürlük desteği\n- [X] midjourney sola, sağa, yukarıya, aşağıya uzantı değişiklikleri\n- [X] midjourney aynı anda [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) ve [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus) arayüzlerini destekler\n- [X] midjourney görüntüden metin oluşturma\n- [X] Görüntülerin yerel depolama için localforage kullanımı\n- [X] midjourney ve niji farklı botları destekler\n- [X] [InsightFace yüz değiştirme](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot) desteği\n- [X] midjourney görüntü karıştırma\n- [X] midjourney seed alma\n- [X] dall-e-3 çizim\n- [X] chatgpt ön uç model seçimi\n- [X] chatgpt ön uç özel model, sohbet sayısı, yanıt sayısı desteği\n- [X] chatgpt görüntü yükleme ve gpt-4-vision-preview kullanımı\n- [X] chatgpt dosya yükleme desteği (gpt-4-all, gpt-4-gizmo-xxx modelleri için)! Varsayılan olarak kapalıdır, açmak için API_UPLOADER=1 ortam değişkenine ihtiyaç vardır\n- [X] chatgpt tersine modeller gpt-4-all, gpt-4-v, gpt-4-gizmo-(gizmo_id) desteği\n- [X] chatgpt super link model değiştirme https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu desteği\n- [X] ChatGPT super link model değiştirme desteği https://chat.openai.com/g/g-2fkFE8rbu https://vercel.ddaiai.com/#/g/g-2fkFE8rbu olarak değiştirilebilir\n- [X] chatgpt GPTs multi-modal desteği\n- [X] chatgpt tts whisper desteği\n- [X] Anında ses tanıma (tarayıcıda yerleşik ses tanıma ASR) `v2.15.7` üzeri sürümler\n- [X] one-api ve new-api dağıtım sohbeti için super link değiştirme https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] one-api ve new-api dağıtım sohbeti https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## Sunucusuz-Kişisel Masaüstü Kurulumu\n> - [x] En son sürümü indirmek için https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases adresine gidin (işletim sisteminize uygun sürümü seçin)\n> - [x] Uygun bir ara sunucu hizmeti seçin (tercihen `gpt`, `gpts`, `midjourney`, `claude`, `suno` destekleyen)\n> - [x] Ara sunucu hizmet sağlayıcıları önerisi https://www.openai-hk.com bir `key` ve `api arayüz adresi` aynı anda `gpt`, `midjourney`, `claude`, `suno` destekler, mj-fast en düşük 0.12rmb/adet\n![multi-modal](./docs/suno-ds.jpg)\n\n## Vercel Tek Tıklama ile Dağıtım\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## env Ortam Değişkenleri\n\n| Ortam Değişkeni | Açıklama | Varsayılan Değer |docker gibi dağıtımlar| vercel dağıtımı|\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | OpenAI API arayüz adresi | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | OpenAI API anahtarı |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  Varsayılan model | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  mj proxy arayüz adresi  |[Kurulum Referansı](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  mj proxy | Boş  | ✅ |  ✅|\n| SUNO_SERVER |  SUNO API arayüz adresi  | [Kurulum Referansı](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  SUNO API anahtarı | Boş  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  Erişim yetkilendirme şifresi | Yok  | ✅ |   x|\n| API_UPLOADER |  Yükleme desteği | Kapalı  | ✅ |  x|\n| HIDE_SERVER |  Ön uç arayüzü sunucu gizle |    | ✅ |  x|\n| CUSTOM_MODELS |  Özel seçilebilir modeller | Yok  | ✅ |  ✅|\n| TJ_BAIDU_ID |  Baidu İstatistik ID | Yok  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  Google İstatistik ID | Yok  | ✅ |  ✅|\n| SYS_NOTIFY |  Sistem bildirimi, HTML destekler | Yok  | ✅ |  ✅|\n| DISABLE_GPT4 |  GPT-4 devre dışı bırakma | Yok  | ✅ |  ✅|\n| GPT_URL | Özelleştir GPT_URL=/gpts.json  | Yok, ayrıca kendi harici linkinizi de kullanabilirsiniz | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | gpt4v görüntü yükleme boyutu |  1 | ✅ |  ✅|\n| SYS_THEME | Varsayılan tema `light` veya `dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | `wsrv` resim sunucu açılışı | Yok (kapalı)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | Bruteforce koruması: doğrulama sayısı NGINX lütfen `proxy_set_header   X-Forwarded-For  $remote_addr` ayarlayın | Yok  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | Bruteforce koruması: bekleme süresi dakika cinsinden | Yok  | ✅ |  x|\n| CLOSE_MD_PREVIEW | Giriş önizlemesini kapat | Yok  | ✅ |  ✅|\n| UPLOAD_TYPE | Yükleme türü [`R2` R2 yükleme] [`API` UI ön uçla ara sunucu] [`Container` yerel konteyner] [`\n\nMyUrl` özel link]  |  Boş | ✅ |  x|\n| MENU_DISABLE  | Menü devre dışı bırakılacak seçenekler: gpts,draws,gallery,music |  Boş | ✅ |  ✅|\n| VISION_MODEL  | Varsayılan görüntü modeli seçenekleri: `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview` vb. |  Boş | ✅ |  ✅|\n| SYSTEM_MESSAGE  | Varsayılan özel rol mesajı |  Boş | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | Özel görüntü modelleri, virgülle ayrılmış |  Boş | ✅ |  ✅|\n\n## docker Dağıtımı\n\n> - [x] [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) desteği gereklidir\n> - [x] [Suno-API](https://github.com/SunoAI-API/Suno-API) desteği gereklidir\n\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=your-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\nErişim http://ip:6015 \n\n**Dosya Yükleme**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\nÖn uç arayüzde OPENAI_API_KEY ve OPENAI_API_BASE_URL ayarlandığında; resim yükleme de OPENAI_API_BASE_URL üzerinden yürütülecektir\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\nDönüş Formatı\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### midjourney-proxy API docker dağıtımı\nDaha fazla bilgi için [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) açık kaynak referansını ziyaret edin\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=discord hizmeti ID  \\\n-e mj.discord.channel-id=discord hizmet grubu ID   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n## Daha Fazla Gösterim\n\n### Özel sunucu api key, base_url:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Mağaza\n![multi-modal](./docs/gpts.jpg)\n![multi-modal](./docs/gpts1.jpg)\n\n### suno Müzik Yapımı\n![suno](./docs/suno.jpg)\n\n### Ses Kaydı whisper ve tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### Yerel yeniden çizim:\n[![Yerel yeniden çizim](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### Yüz Değiştirme\n![Yüz Değiştirme](./docs/mj2a2.jpg)\n\n### Görüntü Karıştırma\n![Görüntü Karıştırma](./docs/mj2a3.jpg)\n\n### Görüntü yükleme ve gpt-4-vision-preview kullanımı\n![Görüntü](./docs/mj4a1.png)\nMobil:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n\n## Dosya Yükleme Cloudflare R2 Depolama Desteği\n\n- Cloudflare R2 depolama 10 GB/ay ücretsiz https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- Konfigürasyon dokümanı için https://zhuanlan.zhihu.com/p/658058503 adresine bakın\n- vercel R2 depolamayı desteklemez\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## Dosya Sunucusu Talep Öncelik Sırası\nR2> Ön uç arayüzde belirlenen dosya hizmeti> Arka uç dosya hizmeti > ara sunucu\n## Bruteforce Koruma Ayarları\n\n![Bruteforce](./docs/check_error.jpg)\n- [x] vercel desteklemez; sadece Docker dağıtımı destekler\n- [x] Eğer ön tarafta `nginx` kullanılıyorsa lütfen `proxy_set_header   X-Forwarded-For  $remote_addr;` ayarlayın\n- [x] Parametreler: 3 kez yanlış doğrulama yapılırsa, 10 dakika boyunca tekrar doğrulama yapılamaz\n```yml\n# Secret key Not: Sadece İngilizce harf ve rakam kullanın\nAUTH_SECRET_KEY=my888god\n# Bruteforce: doğrulama sayısı Not: Rakam olmalıdır; nginx lütfen `proxy_set_header   X-Forwarded-For  $remote_addr` ayarlayın\nAUTH_SECRET_ERROR_COUNT=3\n# Bruteforce: bekleme süresi dakika cinsinden Not: Rakam olmalıdır\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] Betik\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=ingilizce_sifreniz -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n## Lisans\nMIT © [Dooy](./license)\n\n## Diğerleri\nEğer bu proje size yardımcı olduysa, lütfen bir yıldız verin veya bizi bağışlayın\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## Bağış\nEğer açık kaynak projelerim size yardımcı olduysa, lütfen aşağıdaki yöntemlerden biriyle bağış yapmayı düşünün:\n<br> `Ödeme notunda iletişim bilgilerinizi belirtin`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>WeChat Bağışı</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Alipay Bağışı</div>\n    </div>\n</div>"
  },
  {
    "path": "README_VN.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**Tuyên bố**\n- Dự án này chỉ phát hành trên GitHub, dựa trên giấy phép MIT, miễn phí và sử dụng cho mục đích học tập mã nguồn mở. Không có bất kỳ hình thức bán tài khoản, dịch vụ trả phí, nhóm thảo luận, nhóm thảo luận nào khác. Hãy cảnh giác với lừa đảo.\n- Mã nguồn mở này được phát triển lại dựa trên [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web) và sử dụng midjourney api do [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) cung cấp và [Suno-API](https://github.com/SunoAI-API/Suno-API) làm backend.\n\n![cover](./docs/mj2a1.jpg)\n## Chức năng hỗ trợ\n- [x] Hỗ trợ module riêng biệt Suno, có thể điều chỉnh lời bài hát và phong cách âm nhạc\n- [x] Tất cả các chức năng của chatgpt web gốc\n- [x] chatgpt web hỗ trợ API key tùy chỉnh, base_url\n- [x] Midjourney sinh hình từ văn bản\n- [x] Midjourney vẽ từ hình + văn bản\n- [X] Midjourney biến hình từ U1 đến U4, V1 đến V4, và các thao tác vẽ lại khác\n- [X] Midjourney hỗ trợ vẽ lại từng phần\n- [X] Midjourney hỗ trợ zoom 1.5x, 2x\n- [X] Midjourney hỗ trợ HD 2x, HD 4x\n- [X] Midjourney hỗ trợ mở rộng trái, phải, trên, dưới\n- [X] Midjourney hỗ trợ cả hai giao diện [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) và [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus)\n- [X] Midjourney sinh văn từ hình ảnh\n- [X] Sử dụng localforage để lưu trữ hình ảnh cục bộ\n- [X] Hỗ trợ các robot khác nhau của Midjourney và Niji\n- [X] Hỗ trợ [InsightFace thay thế khuôn mặt](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] Midjourney trộn hình ảnh\n- [X] Midjourney lấy seed\n- [X] Dall-e-3 vẽ hình ảnh\n- [X] Chatgpt chọn mô hình ở giao diện trước\n- [X] Chatgpt hỗ trợ mô hình tùy chỉnh, số lượng đối thoại theo ngữ cảnh, số lượng trả lời\n- [X] Chatgpt hỗ trợ tải ảnh để sử dụng GPT-4-Vision-Preview\n- [X] Chatgpt hỗ trợ tải lên file backend (dành cho các mô hình GPT-4-All, GPT-4-Gizmo-XXX)! Mặc định là tắt, mở cần biến môi trường API_UPLOADER=1\n- [X] Chatgpt hỗ trợ mô hình đảo ngược GPT-4-All, GPT-4-V, GPT-4-Gizmo-(gizmo_id)\n- [X] Chatgpt hỗ trợ chuyển đổi mô hình liên kết https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] Hỗ trợ chuyển đổi mô hình liên kết thử nghiệm của ChatGPT https://chat.openai.com/g/g-2fkFE8rbu sửa thành https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] Chatgpt hỗ trợ GPTs đa modal\n- [X] Chatgpt hỗ trợ tts whisper\n- [X] Nhận diện giọng nói ngay lập tức (Nhận diện giọng nói sẵn có của trình duyệt ASR) `v2.15.7` trở lên\n- [X] Hỗ trợ thay đổi thiết lập liên kết, phù hợp với `one-api`, `new-api` triển khai chat https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] Hỗ trợ triển khai chat `one-api`, `new-api` https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## Cài đặt trên máy cá nhân - không máy chủ\n> - [x] Vui lòng tải phiên bản mới nhất từ https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases (chọn phiên bản phù hợp với hệ điều hành của bạn)\n> - [x] Chọn một nhà cung cấp dịch vụ trung chuyển phù hợp (Tốt nhất là hỗ trợ `gpt`, `gpts`, `midjourney`, `claude`, `suno`)\n> - [x] Nhà cung cấp dịch vụ trung chuyển đề xuất https://www.openai-hk.com với một `key` và `địa chỉ API` hỗ trợ cùng lúc `gpt`, `midjourney`, `claude`, `suno`, mj-fast thấp nhất chỉ 0.12rmb/hình ảnh\n![đa modal](./docs/suno-ds.jpg)\n\n## Vercel triển khai một lần nhấn\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## Biến môi trường env\n\n| Biến môi trường | Mô tả | Giá trị mặc định | triển khai docker| triển khai vercel|\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | Địa chỉ API OpenAI | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | Khóa API OpenAI |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  Mô hình mặc định | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  Địa chỉ giao diện proxy mj  |[tham khảo cài đặt](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  mj proxy | Trống  | ✅ |  ✅|\n| SUNO_SERVER |  Địa chỉ API SUNO  | [tham khảo cài đặt](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  Khóa API SUNO | Trống  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  Mật khẩu truy cập | Không có  | ✅ |   x|\n| API_UPLOADER |  Hỗ trợ tải lên | Tắt  | ✅ |  x|\n| HIDE_SERVER |  Ẩn server trong giao diện trước |    | ✅ |  x|\n| CUSTOM_MODELS |  Mô hình tùy chỉnh | Không có  | ✅ |  ✅|\n| TJ_BAIDU_ID |  ID thống kê Baidu | Không có  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  ID thống kê Google | Không có  | ✅ |  ✅|\n| SYS_NOTIFY |  Thông báo hệ thống, hỗ trợ HTML | Không có  | ✅ |  ✅|\n| DISABLE_GPT4 |  Vô hiệu hóa GPT-4 | Không có  | ✅ |  ✅|\n| GPT_URL | URL GPT tùy chỉnh =/gpts.json  | Không có hoặc liên kết ngoài của bạn | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | Kích thước tải lên ảnh gpt4v |  1 | ✅ |  ✅|\n| SYS_THEME | Chủ đề mặc định `light` hoặc `dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | Có bật `wsrv` làm máy chủ hình ảnh không  | Không (tắt)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | Số lần xác minh lỗi để tránh brute force NGINX xin vui lòng thiết lập `proxy_set_header X-Forwarded-For $remote_addr`  | Không có  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | Thời gian dừng lại khi xác minh lỗi đơn vị phút  | Không có  | ✅ |  x|\n| CLOSE_MD_PREVIEW | Có tắt xem trước đầu vào không | Không có  | ✅ |  ✅|\n| UPLOAD_TYPE | Chỉ định cách tải lên [`R2` tải lên R2] [`API` trung chuyển UI] [`Container` container cục bộ] [`MyUrl` liên kết tùy chỉnh]  |  Trống\n\n | ✅ |  x|\n| MENU_DISABLE  | Menu vô hiệu hóa tùy chọn: gpts, draws, gallery, music |  Trống | ✅ |  ✅|\n| VISION_MODEL  | Mô hình nhận diện mặc định tùy chọn: `gpt-4o`, `gpt-4-turb`, `gpt-4-vision-preview` |  Trống | ✅ |  ✅|\n| SYSTEM_MESSAGE  | Tin nhắn nhân vật mặc định tùy chỉnh |  Trống | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | Mô hình nhận diện tùy chỉnh cách nhau bởi dấu phẩy |  Trống | ✅ |  ✅|\n\n  \n\n## Triển khai docker\n\n> - [x] Cần [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) hỗ trợ\n> - [x] Cần [Suno-API](https://github.com/SunoAI-API/Suno-API) hỗ trợ\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\nTruy cập http://ip:6015 \n\n**Tải lên tệp:**\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\nNếu thiết lập UI trước OPENAI_API_KEY OPENAI_API_BASE_URL; tải lên hình ảnh sẽ theo OPENAI_API_BASE_URL\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\nKết quả trả về\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### API midjourney-proxy triển khai docker\nTham khảo thêm tại [midjourney-proxy](https://github.com/novicezk/midjourney-proxy)\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=ID dịch vụ discord  \\\n-e mj.discord.channel-id=ID nhóm dịch vụ discord  \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n## Hình ảnh thêm\n\n### API key và base_url tùy chỉnh ở giao diện trước:\n![base_url](./docs/gptbase.jpg)\n\n### GPTS GTP Store\n![đa modal](./docs/gpts.jpg)\n![đa modal](./docs/gpts1.jpg)\n\n### Sản xuất âm nhạc Suno\n![suno](./docs/suno.jpg)\n\n### Ghi âm whisper và tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### Vẽ lại từng phần:\n[![Vẽ lại từng phần](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### Thay đổi khuôn mặt\n![Thay đổi khuôn mặt](./docs/mj2a2.jpg)\n\n### Trộn hình ảnh\n![Trộn hình ảnh](./docs/mj2a3.jpg)\n\n### Hỗ trợ tải lên hình ảnh cho gpt-4-vision-preview\n![Trộn hình ảnh](./docs/mj4a1.png)\nTrên điện thoại:\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n\n## Tải lên tệp hỗ trợ lưu trữ cloudflare r2\n\n- Lưu trữ cloudflare r2 10 GB/tháng miễn phí https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- Tài liệu cấu hình tham khảo https://zhuanlan.zhihu.com/p/658058503\n- Vercel không hỗ trợ lưu trữ r2\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## Ưu tiên yêu cầu máy chủ tệp\nR2> Thiết lập dịch vụ tệp UI phía trước > Dịch vụ tệp backend > theo trung chuyển\n## Thiết lập xác minh tránh brute force\n\n![Xác minh tránh brute force](./docs/check_error.jpg)\n- [x] Vercel không hỗ trợ; chỉ hỗ trợ triển khai docker\n- [x] Nếu đằng trước gắn `nginx` vui lòng cấu hình `proxy_set_header X-Forwarded-For $remote_addr;`\n- [x] Các tham số như sau: lỗi xác minh 3 lần, chỉ có thể xác minh lại sau 10 phút\n```yml\n# Secret key chú ý: Chỉ có chữ cái tiếng Anh + số\nAUTH_SECRET_KEY=my888god\n# Brute force: số lần xác minh lỗi chú ý: số ；nginx vui lòng thiết lập proxy_set_header X-Forwarded-For $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n# Brute force: thời gian dừng lại đơn vị phút chú ý: là số\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] Kịch bản như sau\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=mật khẩu tiếng Anh của bạn -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n- \n## License\nMIT © [Dooy](./license)\n\n## Khác\nNếu bạn thấy dự án này hữu ích, hãy giúp tôi bằng cách đánh giá sao hoặc ủng hộ chúng tôi\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## Ủng hộ\nNếu mã nguồn mở của tôi hữu ích với bạn, vui lòng xem xét ủng hộ qua bất kỳ phương thức nào sau đây:\n<br> `Ghi chú liên hệ của bạn trên thanh toán`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>Ủng hộ WeChat</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>Ủng hộ Alipay</div>\n    </div>\n</div>"
  },
  {
    "path": "README_ZH.md",
    "content": "# ChatGPT Web Midjourney Proxy\n💡**声明**\n- 此项目只发布于 GitHub，基于 MIT 协议，免费且作为开源学习使用。并且不会有任何形式的卖号、付费服务、讨论群、讨论组等行为。谨防受骗。\n- 本开源是在 [ChenZhaoYu](https://github.com/Chanzhaoyu/chatgpt-web) 基础上做二次开发 ；使用 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 提供的midjourney api和 [Suno-API](https://github.com/SunoAI-API/Suno-API)  作为后端而形成的；\n\n\n![cover](./docs/mj2a1.jpg)\n## 支持功能 \n- [x] 支持 suno 单独模块，可歌词调整 曲风调整\n- [x] 原chatgpt web 所有功能\n- [x] chatgpt web 支持自定义api key、base_url\n- [x] midjourney 文生图\n- [x] midjourney 垫图+文生图  \n- [X] midjourney 图变 U1到U4 、 V1到V4、重绘等操作\n- [X] midjourney 支持局部重绘\n- [X] midjourney 支持1.5倍变焦 2倍变焦\n- [X] midjourney 支持2倍高清 4倍高清\n- [X] midjourney 支持左、右、上、下延伸变化\n- [X] midjourney 同时支持[midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 接口 和 [midjourney-proxy-plus](https://github.com/litter-coder/midjourney-proxy-plus) 接口\n- [X] midjourney 图生文\n- [X] 图片使用localforage实现本地存储\n- [X] 支持midjourney、niji 不同机器人\n- [X] 支持[InsightFace 人脸替换](https://discord.com/api/oauth2/authorize?client_id=1090660574196674713&permissions=274877945856&scope=bot)\n- [X] midjourney 混图\n- [X] midjourney 获取 seed\n- [X] dall-e-3 画图\n- [X] chatgpt 前端选择模型\n- [X] chatgpt 前端支持自定义模型、上下文对话数、回复数\n- [X] chatgpt 支持图片上传图片 供gpt-4-vision-preview使用\n- [X] chatgpt 支持文件后端上传（供给gpt-4-all gpt-4-gizmo-xxx 模型）！ 默认是关闭的 打开需要环境变量 API_UPLOADER=1\n- [X] chatgpt 支持逆向模型 gpt-4-all gpt-4-v gpt-4-gizmo-(gizmo_id)\n- [X] chatgpt 支持超链模型切换 https://vercel.ddaiai.com/#/m/gpt-4-all https://vercel.ddaiai.com/#/m/gpt-4-gizmo-g-2fkFE8rbu\n- [X] 支持ChatGPT试的超链模型切换 https://chat.openai.com/g/g-2fkFE8rbu 修改为 https://vercel.ddaiai.com/#/g/g-2fkFE8rbu\n- [X] chatgpt 支持 GPTs 多模态\n- [X] chatgpt 支持 tts whisper\n- [X] 即时语音识别(浏览器自带语音识别 ASR) `v2.15.7`以上版本\n- [X] 支持超链更换设置，适合`one-api` `new-api`部署聊天 https://vercel.ddaiai.com/#/s/t?OPENAI_API_BASE_URL=https://abc.com&OPENAI_API_KEY=sk-xxxxx&MJ_SERVER=https://abc.com&MJ_API_SECRET=sk-xxx&UPLOADER_URL=\n- [X] 支持`one-api`、`new-api`部署聊天 https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://www.abc.com%22} `(v.2.14.3)`\n\n## 无服务器-个人桌面安装\n> - [x] 请到 https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases 下载最新版本安装(选择合适你操作系统的版本)\n> - [x] 选择一个合适的中转服务商( 最好都支持 `gpt`, `gpts`, `midjourney`, `claude`, `suno` )\n> - [x] 中转服务商推荐 https://www.openai-hk.com 一个`key`和`api接口地址` 同时支持 `gpt` `midjourney` `claude` `suno`，mj-fast最低能到0.12rmb/张\n![多模态](./docs/suno-ds.jpg)\n\n## Vercel 一键部署\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/Dooy/chatgpt-web-midjourney-proxy&env=OPENAI_API_BASE_URL&env=OPENAI_API_KEY&env=MJ_SERVER&env=MJ_API_SECRET&project-name=chatgpt-web-midjourney-proxy&repository-name=chatgpt-web-midjourney-proxy)\n\n## env 环境变量\n\n| 环境变量 | 说明 | 默认值 |docker等部署| vercel 部署|\n| --- | --- | --- | --- | --- |\n| OPENAI_API_BASE_URL | OpenAI API 接口地址 | https://api.openai.com | ✅ |  ✅|\n| OPENAI_API_KEY | OpenAI API 密钥 |  sk-xxxxx | ✅ |  ✅|\n| OPENAI_API_MODEL |  默认模型 | gpt-3.5-turbo  | ✅ |  ✅|\n| MJ_SERVER |  mj proxy 接口地址  |[搭建参考](https://github.com/novicezk/midjourney-proxy) | ✅ |  ✅|\n| MJ_API_SECRET |  mj proxy | 空  | ✅ |  ✅|\n| SUNO_SERVER |  SUNO API 接口地址  | [搭建参考](https://github.com/SunoAI-API/Suno-API) | ✅ |  ✅|\n| SUNO_KEY |  SUNO API 的key | 空  | ✅ |  ✅|\n| AUTH_SECRET_KEY |  访问授权密码 | 无  | ✅ |   x|\n| API_UPLOADER |  支持上传 | 关闭  | ✅ |  x|\n| HIDE_SERVER |  前端ui隐藏服务端|    | ✅ |  x|\n| CUSTOM_MODELS |  自定义可选模型 | 无  | ✅ |  ✅|\n| TJ_BAIDU_ID |  百度统计ID | 无  | ✅ |  ✅|\n| TJ_GOOGLE_ID |  谷歌统计ID | 无  | ✅ |  ✅|\n| SYS_NOTIFY |  系统通知，支持HTML | 无  | ✅ |  ✅|\n| DISABLE_GPT4 |  禁用GPT-4 | 无  | ✅ |  ✅|\n| GPT_URL | 自定 GPT_URL=/gpts.json  | 无 也可自己的外链 | ✅ |  ✅|\n| UPLOAD_IMG_SIZE | gpt4v 上传图片大小 |  1 | ✅ |  ✅|\n| SYS_THEME | 默认主题 `light`或者`dark`  | dark | ✅ |  ✅|\n| MJ_IMG_WSRV | 是否开启 `wsrv`图床  | 无(关闭)  | ✅ |  ✅|\n| AUTH_SECRET_ERROR_COUNT | 防爆破验证：验证次数触发 NGINX 请设置 `proxy_set_header   X-Forwarded-For  $remote_addr`  | 无  | ✅ |  x|\n| AUTH_SECRET_ERROR_TIME | 防爆破验证：停留时间 单位分钟  | 无  | ✅ |  x|\n| CLOSE_MD_PREVIEW | 是否不关闭输入预览 | 无  | ✅ |  ✅|\n| UPLOAD_TYPE | 指定上传方式 [`R2` R2上传] [`API` 跟随UI前端中转]、[`Container` 本地容器]、[`MyUrl` 自定义链接]  |  空 | ✅ |  x|\n| MENU_DISABLE  | 菜单禁用 可选:gpts,draws,gallery,music |  空 | ✅ |  ✅|\n| VISION_MODEL  | 默认使用的识图 可选:`gpt-4o`,`gpt-4-turb`,`gpt-4-vision-preview`等 |  空 | ✅ |  ✅|\n| SYSTEM_MESSAGE  | 自定义默认角色消息 |  空 | ✅ |  ✅|\n| CUSTOM_VISION_MODELS  | 自定义可视图模型 用`,` 分开 |  空 | ✅ |  ✅|\n\n  \n\n## docker 部署\n \n> - [x] 需 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy)   支持\n> - [x] 需 [Suno-API](https://github.com/SunoAI-API/Suno-API)  支持\n\n\n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://your-mj-server:6013  \\\n-e MJ_API_SECRET=your-mj-api-secret  \\\n-e SUNO_SERVER=https://your-suno-server:8000  \\\n-e SUNO_KEY=you-suno-key  ydlhero/chatgpt-web-midjourney-proxy\n```\n访问 http://ip:6015 \n\n**文件上传**: \n```bash\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e MJ_API_SECRET=abc123456  ydlhero/chatgpt-web-midjourney-proxy\n```\n如果是前端ui设置 OPENAI_API_KEY OPENAI_API_BASE_URL ; 图片上传也会随着走 OPENAI_API_BASE_URL走\n```shell\ncurl -X POST -H \"Content-Type: multipart/form-data\" -F \"file=@/path/to/file\" http://OPENAI_API_BASE_URL/v1/upload\n```\n返回格式\n```json\n{\n\"url\":\"https://xxxxxxx.jpg\"\n}\n```\n\n### midjourney-proxy API docker部署\n更多参考到 [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) 开源光光\n```bash\ndocker run -d --name mj6013  -p 6013:8080  \\\n-e mj.discord.guild-id=discord服务ID  \\\n-e mj.discord.channel-id=discord服务组ID   \\\n-e mj.queue.timeout-minutes=6 \\\n-e mj.api-secret=abc123456 \\\n-e mj.discord.user-token=**********  \\\n--restart=always novicezk/midjourney-proxy:2.5.5\n```\n\n\n## 更多展示\n\n### 自定义服务端api key、base_url：\n![base_url](./docs/gptbase.jpg)\n\n### GPTS  GTP Store \n![多模态](./docs/gpts.jpg)\n![多模态](./docs/gpts1.jpg)\n\n### suno 音乐制作\n![suno](./docs/suno.jpg)\n\n\n### 录音 whisper  和  tts\n![whisper--tts](./docs/tts-whisper.png)\n\n### 局部重绘：\n[![局部重绘](./docs/mj2.jpg)](./docs/mj2.jpg)\n\n### 换脸\n![换脸](./docs/mj2a2.jpg)\n\n### 混图\n![混图](./docs/mj2a3.jpg)\n\n### 支持图片上传图片 供gpt-4-vision-preview使用\n![混图](./docs/mj4a1.png)\n手机端：\n<div style=\"display: flex; flex-wrap: wrap\">\n <img src=\"./docs/mjs1.jpg\" style=\"width:200px\" >\n <img src=\"./docs/mjs2.jpg\"  style=\"width:200px\">\n <img src=\"./docs/mjs3.jpg\"  style=\"width:200px\">\n</div>\n\n\n## 文件上传 支持cloudflare r2 存储\n\n- cloudflare r2 存储 10 GB/月 免费 https://www.cloudflare.com/zh-cn/developer-platform/r2/\n- 配置文档参考 https://zhuanlan.zhihu.com/p/658058503\n- vercel 不支持 r2 存储\n```yml\nR2_DOMAIN=\nR2_BUCKET_NAME=\nR2_ACCOUNT_ID=\nR2_KEY_ID=\nR2_KEY_SECRET=\n```\n## 文件服务器请求优先顺序\nR2> 前端UI设置文件服务> 后端文件服务 >跟随中转\n## 防爆破验证设置\n\n![防爆破](./docs/check_error.jpg)\n- [x] vercel 不支持；仅支持Docker化部署\n- [x] 如果前面挂载 `nginx` 请配置 `proxy_set_header   X-Forwarded-For  $remote_addr;`\n- [x] 参数如下: 错误验证3次，只能在10分钟后再验证\n```yml\n# Secret key 注意: 只能拿事英文+数字\nAUTH_SECRET_KEY=my888god\n#爆破：验证次数 注意: 数字 ；nginx 请设置  proxy_set_header   X-Forwarded-For  $remote_addr;\nAUTH_SECRET_ERROR_COUNT=3\n#爆破：验证停留时间 单位分钟 注意: 是数字\nAUTH_SECRET_ERROR_TIME=10\n```\n- [x] 脚本如下\n```shell\ndocker run --name chatgpt-web-midjourney-proxy  -d -p 6015:3002 \\\n-e OPENAI_API_KEY=sk-xxxxx \\\n-e OPENAI_API_BASE_URL=https://api.openai.com  \\\n-e MJ_SERVER=https://172.17.0.1:6013  \\\n-e MJ_API_SECRET=abc123456 \\\n-e API_UPLOADER=1  -v /data/uploads:/app/uploads \\\n-e AUTH_SECRET_KEY=你的英文密码 -e AUTH_SECRET_ERROR_COUNT=3 \\\n-e AUTH_SECRET_ERROR_TIME=10 ydlhero/chatgpt-web-midjourney-proxy\n```\n- \n## License\nMIT © [Dooy](./license)\n\n## 其他\n如果觉得这个项目对您有所帮助，请帮忙点个star 或者捐助我们\n\n[![Star History Chart](https://api.star-history.com/svg?repos=Dooy/chatgpt-web-midjourney-proxy&type=Date)](https://star-history.com/#Dooy/chatgpt-web-midjourney-proxy&Date)\n\n## 捐助\n如果我的开源项目对你有帮助，请考虑通过以下任意一种方式赞助: \n<br> `付款备注上您的联系方式`\n<div style=\"display: flex; flex-wrap: wrap\">\n    <div style=\"width:200px\">\n        <img src=\"./docs/wxpay.jpg\"  style=\"width:200px\">\n        <div>微信捐助</div>\n    </div>\n    <div style=\"width:200px\">\n        <img src=\"./docs/alipay.jpg\"  style=\"width:200px\"> \n        <div>支付宝捐助</div>\n    </div>\n</div>"
  },
  {
    "path": "SPONSOR.md",
    "content": "# Sponsor My Open Source Works\n\n如果我的开源项目对你有帮助，请考虑通过以下任意一种方式赞助:\n\n## 微信赞助\n![微信](./docs/wxpay.jpg)\n## 支付宝赞助\n![支付宝](./docs/alipay.jpg)"
  },
  {
    "path": "api/proxy.js",
    "content": "const {\n    createProxyMiddleware\n} = require('http-proxy-middleware')\n\nmodule.exports = (req, res) => {\n    let target = ''\n    let headers= {}\n    // 代理目标地址\n    if (req.url.startsWith('/mjapi')) { //这里使用/api可能会与vercel serverless 的 api 路径冲突，根据接口进行调整\n        target = process.env.MJ_SERVER??'https://api.openai.com';\n        headers= {\n            'Mj-Api-Secret': process.env.MJ_API_SECRET // 添加自定义请求头\n        }\n    }else if(req.url.startsWith('/openapi')){\n        target = process.env.OPENAI_API_BASE_URL??'https://api.openai.com';\n        headers= {\n            'Authorization': 'Bearer ' +process.env.OPENAI_API_KEY // 添加自定义请求头\n        }\n    }\n    // 创建代理对象并转发请求\n    createProxyMiddleware({\n        target,\n        changeOrigin: true,\n        headers,\n        pathRewrite: {\n            // 通过路径重写，去除请求路径中的 `/api`\n            '^/mjapi/': '/'\n            ,'^/openapi/': '/'\n        }\n    })(req, res)\n}\n"
  },
  {
    "path": "api/session.js",
    "content": "module.exports = (req, res) => {\n  console.log('session.js', req.body);\n  try {\n    let data = req.body.data; \n    let obj ={\n        \"status\": \"Success\",\n        \"message\": \"\",\n        \"data\": {\n            \"isHideServer\": false,\n            \"isUpload\": false,\n            \"auth\":   process.env.AUTH_SECRET_KEY?true:false ,\n            \"model\": \"ChatGPTAPI\",\n            \"amodel\": process.env.OPENAI_API_MODEL?? \"gpt-3.5-turbo\"\n            ,isApiGallery:    process.env.MJ_API_GALLERY ? true : false \n            ,cmodels : process.env.CUSTOM_MODELS??'' \n            ,baiduId : process.env.TJ_BAIDU_ID?? \"\" \n            ,googleId: process.env.TJ_GOOGLE_ID?? \"\"\n            , notify : process.env.SYS_NOTIFY?? \"\" \n            ,disableGpt4 : process.env.DISABLE_GPT4?? \"\" \n            ,isWsrv:  process.env.MJ_IMG_WSRV?? \"\" \n            ,uploadImgSize: process.env.UPLOAD_IMG_SIZE?? \"5\" \n            ,gptUrl : process.env.GPT_URL?? \"\"\n            ,theme : process.env.SYS_THEME?? \"dark\"\n            ,isCloseMdPreview : process.env.CLOSE_MD_PREVIEW?true:false\n            ,menuDisable: process.env.MENU_DISABLE??\"\"\n            ,visionModel: process.env.VISION_MODEL??\"\"\n            ,systemMessage: process.env.SYSTEM_MESSAGE??\"\"\n            ,customVisionModel: process.env.CUSTOM_VISION_MODELS??\"\"\n\n        }\n    }\n    res.writeHead(200).end(\n        JSON.stringify( obj )\n    );\n  } catch (e) {\n    console.error('session.js', e, req.body);\n  }\n}"
  },
  {
    "path": "api/verify.js",
    "content": "module.exports = (req, res) => {\n\tlet obj = {\n\t\t\"status\": \"Fail\",\n\t\t\"message\": \"密钥无效 | Secret key is invalid\",\n\t\t\"data\": null\n\t};\n\tconst auth_secret_keys = process.env.AUTH_SECRET_KEY? process.env.AUTH_SECRET_KEY.trim().split(',').filter(item => item !== ''):[];\n\tif (req.body && req.body.token && auth_secret_keys.include(req.body.token)) obj = {\n\t\tstatus: 'Success',\n\t\tmessage: 'Verify successfully',\n\t\tdata: null\n\t}\n\tres.setHeader('Content-type', 'application/json');\n\tres.writeHead(200).end(\n\t\tJSON.stringify(obj)\n\t);\n}\n"
  },
  {
    "path": "api/webdav-proxy.js",
    "content": "const https = require('https');\nconst http = require('http');\nconst { URL } = require('url');\n\nmodule.exports = async (req, res) => {\n  // 设置 CORS 头\n  res.setHeader('Access-Control-Allow-Origin', '*');\n  res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');\n  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n  // 处理 OPTIONS 请求\n  if (req.method === 'OPTIONS') {\n    return res.status(200).end();\n  }\n\n  // 只允许 POST 请求\n  if (req.method !== 'POST') {\n    return res.writeHead(405).end(JSON.stringify({ error: 'Method not allowed' }));\n  }\n\n  try {\n    const { url, method, username, password, data } = req.body;\n\n    if (!url || !method || !username || !password) {\n      return res.writeHead(400).end(JSON.stringify({ error: '缺少必要参数' }));\n    }\n\n    // 创建 Basic Auth\n    const auth = Buffer.from(`${username}:${password}`).toString('base64');\n    const parsedUrl = new URL(url);\n    \n    const options = {\n      hostname: parsedUrl.hostname,\n      port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),\n      path: parsedUrl.pathname + parsedUrl.search,\n      method: method,\n      headers: {\n        'Authorization': `Basic ${auth}`,\n      },\n      timeout: 30000\n    };\n\n    if (method === 'PUT') {\n      options.headers['Content-Type'] = 'application/json';\n      if (data) {\n        const bodyData = typeof data === 'string' ? data : JSON.stringify(data);\n        options.headers['Content-Length'] = Buffer.byteLength(bodyData);\n      }\n    }\n\n    if (method === 'PROPFIND') {\n      options.headers['Depth'] = '0';\n    }\n\n    const protocol = parsedUrl.protocol === 'https:' ? https : http;\n\n    const proxyReq = protocol.request(options, (proxyRes) => {\n      let responseData = '';\n      \n      proxyRes.on('data', (chunk) => {\n        responseData += chunk;\n      });\n\n      proxyRes.on('end', () => {\n        const statusCode = proxyRes.statusCode;\n        const isSuccess = (statusCode >= 200 && statusCode < 300) || statusCode === 207;\n        \n        let errorMsg = null;\n        if (!isSuccess) {\n          errorMsg = `HTTP ${statusCode} - ${url}`;\n          if (responseData) {\n            errorMsg += ` | Response: ${responseData.substring(0, 200)}`;\n          }\n        }\n        \n        res.writeHead(200).end(JSON.stringify({\n          success: isSuccess,\n          status: statusCode,\n          data: responseData,\n          requestUrl: url,\n          error: errorMsg\n        }));\n      });\n    });\n\n    proxyReq.on('error', (error) => {\n      console.error('WebDAV proxy error:', error.message);\n      res.writeHead(500).end(JSON.stringify({\n        success: false,\n        error: error.message\n      }));\n    });\n\n    proxyReq.on('timeout', () => {\n      proxyReq.destroy();\n      res.writeHead(500).end(JSON.stringify({\n        success: false,\n        error: '请求超时'\n      }));\n    });\n\n    if (method === 'PUT' && data) {\n      const bodyData = typeof data === 'string' ? data : JSON.stringify(data);\n      proxyReq.write(bodyData);\n    }\n\n    proxyReq.end();\n  } catch (error) {\n    console.error('WebDAV proxy error:', error.message);\n    res.writeHead(500).end(JSON.stringify({\n      success: false,\n      error: error.message\n    }));\n  }\n};\n"
  },
  {
    "path": "changlog.md",
    "content": "# 功能升级日志\n\n#  计划 \n# 2.25.11\n- feat: 添加 WebDAV 聊天记录同步功能 #665\n\n# 2.25.10\n- 😄 新增画图：nano-banana-2 gpt-image-1.5 gemini-3.1-flash-image-preivew\n- 😄 新增对话：`gpt-5.1`、`gemini-3-pro-preview`,`grok-4.1`\n- 2026第一个版本\n\n# 2.25.9\n- 🐞 修复：mj显示双图\n- 🐞 修复：gpt-5-all gpts 读取不了pdf的问题\n- 🐞 修复：nona-banana 请求返回正确，但是页面不显示，原因是确实一个判断逻辑。下面代码即可解决bug #667\n- 🐞 修复：MP4格式自动调用whisper-1模型可以去除吗？ #666\n\n# 2.25.8\n- 😄 新增视频：veo3.1 veo3.1-pro openai/sora-2 openai/sora-2-pro\n- 😄 修改：sora-2参数\n\n# 2.25.7\n- 😄 新增视频：sora-2-pro\n- 😄 修改：修改 sora-2参数\n# 2.25.6\n- 😄 新增视频：sora-2\n# 2.25.5\n- 😄 新增：suno-v5\n\n# 2.25.4\n- 😄 新增：nano-banana支持 比例\n- 😄 新增：google veo类视频、fal-ai视频类\n- 😄 新增：支持直达视频模型 https://vercel.ddaiai.com/#/video/index?tab=all&model=veo3\n# 2.25.3\n- 😄 新增：dalle格式的 谷歌 nano-banana\n\n# 2.25.2\n- 🐞 修复：gpt-image-1 无法同时传多个图片 #634\n- 🐞 修复：【bug】绘画 gpt-image-1 采用服务端配置生成图片报错 #646\n- 🐞 修复： gpt5报错 #650\n- 😄 新增：支持 mj 视频组合 `--video` `--bs 2`  生成视频  \n\n# 2.25.1\n- 😄 新增：支持 suno 模型 `v4.5+` , 将 mv 修改为`chirp-bluejay`\n# 2.24.10\n- 😄 新增：支持 `reasoning_content`\n\n# 2.24.9\n- 😄 新增：mj `图生视频` `图片编辑`\n\n# 2.24.8\n- 😄 新增：`flux-kontext-pro` `flux-kontext-max` 模型\n\n# 2.24.7\n- 😄 新增：riffusion 音乐模块\n- 😄 改进：mj 按钮如果没有预先设置 则直接显示\n\n# 2.24.6\n- 😄 新增：mj v6.1 v7的放大   关于MJ V6.1 和 V7 没有放大按钮 #635\n- 😄 新增：kling-v2-master 模型\n# 2.24.5\n- 😄 新增：pix 运镜\n\n# 2.24.4\n- 🐞 修复：oref 空 导致 trim错误\n\n# 2.24.3\n- 🐞 改进：mj 默认为 v7\n- 🐞 改进：mj 支持 oref 全面参考 \n\n# 2.24.2\n- 😄 新增： suno `v4.5`  model 为 `chirp-auk`\n# 2.24.1\n- 😄 新增：gpt-image-1 dall.e-2 支持 v1/image/edit 支持多图\n- 🐞 改进：默认上传改为5M\n\n# 2.23.10\n\n- 😄 新增：gpt-image-1 这个是dall-e格式\n- 😄 新增：pixverse 的 `v4`版本\n\n# 2.23.9\n- 😄 新增：rumwayml 支持 gen4_turbo\n\n# 2.23.8\n- 🐞 改进：识图默认放开都支持 只有gpt-3.5 已知不支持\n- 🐞 改进：服务端模型 支持搜索\n\n# 2.23.7\n- 😄 新增：模型 mj 7.0\n\n# 2.23.6\n- 🐞 修复：2.23.4依旧出现ds-R1不展示思考过程的问题 #611\n- 😄 新增：模型 从服务端的 /v1/models 拉起\n\n\n# 2.23.5\n- 😄 新增：`grok-3`,`grok-3-reasoner`,`grok-3-deepsearch` 模型\n- 😄 新增：`gpt-4.5-preview-2025-02-27`,`gpt-4.5-preview` 模型\n\n# 2.23.4\n- 🐞 修复：`deepseek-v3` `deepseek-r1` 识图处理，需要中转支持\n- 🐞 修复：`deepseek-r1` think 思考过程显示优化\n\n\n\n# 2.23.3\n- 😄 新增：`deepseek-v3` `deepseek-r1` 模型\n\n# 2.23.2\n- 😄 支持：Pixverse 模版特效\n- 😄 支持：kling 支持 model 选型 `v1` `v1.5` `v1.6`\n\n# 2.23.1\n- 🐞 修复：Pixverse 时长支持8s 而非10s\n- 😄 支持：Pixverse style风格\n- 🐞 修复：suno 后端转发目录使用 `/suno`\n\n# 2.22.10\n- 😄 支持：视频模型 Pixverse\n- 😄 支持：Pixverse 图片、前后帧、扩展\n\n# 2.22.9\n- 😄 新增：realtime 可设置模型 `gpt-4o-mini-realtime-preview-2024-12-17` `gpt-4o-realtime-preview-2024-12-17` `gpt-4o-realtime-preview-2024-10-01`\n# 2.22.8\n- 😄 新增：o1  o1-2024-12-17\n\n# 2.22.7\n- 😄 修改：suno upload 二次创作方式\n\n# 2.22.6\n- 😄 支持：viggle V3-Beta\n- 😄 支持：pika 2.0\n- 😄 新增：pika 3个效果\n\n# 2.22.5\n- 🐞 修改：suno默认版本为V4\n\n\n# 2.22.4\n- 🐞 修复：mj shorten\n- 🐞 修复：mj 图转文\n\n# 2.22.3\n- 😄 新增音乐：suno-v4\n- 😄 新增gpt模型：gpt-4o-2024-11-20\n# 2.22.2\n- 😄 新增：支持ruanway 官方api\n- 🐞 修复：模型识图表示\n\n# 2.22.1\n- 😄 新增：超链定位tab 定位到可灵 https://vercel.ddaiai.com//#/video/index?tab=kling\n- 😄 新增：手机可使用 音乐\n\n# 2.21.10\n- 😄 新增：claude-3-5-sonnet-all 模型\n- 😄 新增：pika 3个视频效果\n- 😄 新增：支持 udio\n\n\n# 2.21.9\n- 😄 新增：mj 默认版本为6.1，填写的有保存下次打开 可以重新载入\n- 🐞 修复：默认语言(第一次载入的时候)会根据浏览器语言对应，目前支持 中文简体、英语、中文繁体、法语、俄语、韩语、土耳其语、越南语 如果没在这个列表内则为英语\n\n# 2.21.8\n- 😄 新增：flux.1.1-pro 画图模型\n- 😄 新增：runway3 支持 参考视频\n\n# 2.21.7\n- 😄 新增：claude-3-5-sonnet-20241022 \n\n# 2.21.6\n- 😄 新增：pika 文生视频 图生视频\n- 🐞 修复：luma 支持长宽比例\n\n# 2.21.5\n- 🐞 修复：luam、runway视频删除、viggle删除、kling删除、suno删除？ #510\n\n# 2.21.4\n- 😄 新增：runway图片增加首尾帧选择\n\n# 2.21.3\n- 🐞 修复：回复数最多只有4096太少导致有时无法正常输出 #516\n- 😄 优化：支持实时语音对话服务中的设置\n\n# 2.21.2\n- 😄 新增：支持实时语音对话服务 realtime `gpt-4o-realtime-preview`\n\n# 2.21.1\n- 😄 优化：dall格式图片本地存储（flex,idemgram 不会图片链接过期而找不到 ）\n- 😄 优化：kling图片本地存储\n\n# 2.20.10\n- 😄 新增：模型 `o1-preview` `o1-mini`\n\n# 2.20.9\n- 🐞 修复：kling 图片提交\n- 😄 新增：可灵 kling 的镜头运用\n\n# 2.20.8\n- 😄 新增：可灵 kling 视频 绘图模块\n\n# 2.20.7\n- 😄 新增：runway 可以 extend\n- 🐞 修复：ideogram 清空\n\n# 2.20.6\n- 😄 新增： 画图 ideogram 相关模块\n\n# 2.20.5\n- 😄 新增： flux 相关模型的dall.e格式\n- 🐞 修复：claude-3-5，maxtoken问题 #495\n\n# 2.20.4\n- 🐞 修复：更新了背景图版本后。聊天窗口内容上下滚动有时候会失效，要重新刷新页面才能滚动 #490\n- 🐞 修复：docker部署能不用在编排的时候填写key\n\n# 2.20.3\n- 🤖 合并： 新增自定义背景图片 #488 @Yanyutin753\n- 💄 合并： 优化文件上传样式 #487 @Yanyutin753\n- 💄 合并： AUTH_SECRET_KEY 新增多密钥支持，使用,隔开 #484 @Yanyutin753 \n- 😄 新增： runway Gen3a Turbo\n- 😄 新增： UI服务端 同步 `runway` `viggle` 设置\n\n# 2.20.2\n- 😄 新增：gemini-1.5-pro-exp-0801\n- 😄 新增：chatgpt-4o-latest\n\n# 2.20.1\n- 😄 新增：gpt-4o-2024-08-06\n\n# 2.19.10\n- 😄 新增：视频 runway gen3 支持图片\n- 😄 新增：mj 6.1选项\n- 😄 新增：runway-gen3-fast 选项\n- 🐞 修复：LUMA_SERVER 出现标签选项\n\n# 2.19.9\n- 🐞 修复：luma 说明\n- 🐞 修复：Midjourney生图后，保留prompt在输入框中 #468\n\n# 2.19.8\n- 🐞 修复：runway 过期.重新获取\n\n# 2.19.7\n- 😄 新增：视频 runway 模块\n- 🐞 修复：gpt-4o-mini 图片问题\n- 🐞 修复：luma 说明\n \n\n# 2.19.6\n- 😄 新增：gpt-4o-mini模型\n- 🐞 修复：viggle 下载有问题\n\n# 2.19.5\n- 🐞 修复：后续会有luma尾帧么 #452\n- 😄 新增：viggle pro 跟 relax 能相互切换\n\n# 2.19.4\n- 🐞 修复：luma pro 与 relax版本切换 获取任务有问题\n\n\n# 2.19.3\n- 🐞 修复：viggle 个人上传视频无效\n\n# 2.19.2\n- 😄 新增：跳舞视频viggle模块\n\n# 2.19.1\n- 🐞 修复：Luma下载按钮无法下载？ #443\n- 🐞 修复：luma pro 与 relax版本切换 获取任务有问题\n- 🐞 修复：suno 歌词 fail 提示，luma 状态 failed 提示\n\n# 2.18.10\n- 🐞 修复：视频按钮提示词，有个小错别字。 #424\n- 🐞 修复：claude-3-5-sonnet-20240620无法上传图片 #425 #427 #430\n- 🐞 修复：LUMA不支持竖屏9:16 这个对于短视频 不友好 官方是支持的 #431\n- 🐞 修复：其实cluade其他模型也是支持识图 #433\n- 😄 新增：LUMA视频 支持 `延展` 每 `延展` `+5s`\n- 😄 修复：LUMA不支持竖屏9:16 这个对于短视频 不友好 官方是支持的 #431\n\n# 2.18.9\n- 🐞 修复：luma download_url bug\n- 🐞 修复：claude-3-5-sonnet-20240620传图片直接给我调用gpt-4-vision-preview #423\n\n# 2.18.8\n- 🐞 修复：无法通过?settings={\"key\":\"{key}\",\"url\":\"{server}\"}设置Suno和Luma #412\n- 😄 升级：suno请求带 `/suno` 前缀\n- 🐞 修复：请求新增逆向模型 `gpt-4o-all` #400\n- 😄 新增： `claude-3-5-sonnet-20240620` 模型\n- 🐞 修复：Bug: 手机版Safari下地址栏遮挡界面 #371\n\n# 2.18.7\n- 😄 新增：支持luma视频\n\n# 2.18.6\n- 😄 升级：suno支持延伸\n- 😄 升级：suno支持 以音频生成音频（需要用到延伸）\n\n# 2.18.5\n- 😄 升级：将suno可版本选择 v3 v3.5\n- 🐞 修复：suno 生成失败 error 状态\n\n# 2.18.4\n- 😄 升级：将suno 升级为3.5版本\n\n# 2.18.3\n- 🐞 重大修复：修复卡死.第二处\n\n# 2.18.2\n- 🐞 重大修复：修复卡死\n\n# 2.18.1\n- 🐞 修复：GPTS页面不支持一个页面一个模型 #378\n- 😄 新增：GPTs页 可以新增gpts\n\n# 2.17.10 \n- 😄 新增：新增自定义可视化模型 #338 参数 `CUSTOM_VISION_MODELS`\n- 🐞 修复：Bug: 设置SYSTEM_MESSAGE后模型依然对KnowledgeCutOffDate有误解 #370\n- 🐞 修复：Bug: 手机版Safari下地址栏遮挡界面 #371\n\n# 2.17.9 \n- 🐞 修复：自定义模型的tokens配置 #362 #333\n- 🐞 修复：手机版界面下 MENU_DISABLE 没有生效 #363\n- 🐞 修复：绘图的时候自动新建一个对话 #365\n\n# 2.17.8\n- 🐞 修复：MJ在等待队列状态下的处理逻辑\n- 😄 优化：读图由原来的 `gpt-4-vision-preview`  改为 自定义\n\n# 2.17.7\n- 🐞 修复：目前对于公式显示似乎有严重问题 #345 (再次修复)\n- 🐞 修复：是否支持已有模型列表的自定义？ #297\n\n# 2.17.6\n- 🐞 修复：目前对于公式显示似乎有严重问题 #345\n- 🐞 修复：MJ漏掉V6的2个按钮 高清2倍.subtle 高清2倍.creative\n- 😄 新增：关于gpts的模型名称传入问题 (支持`g-*`) #334\n- 😄 优化：Markdown优化图片显示\n\n# 2.17.5\n- 🐞 修复：`gpt-4o`,`gpt-4o-2024-05-13` 截止日期\n\n# 2.17.4\n- 🐞 修复：mj放大按钮 有v5变v6\n- 😄 新增：`gpt-4o`,`gpt-4o-2024-05-13` 模型\n\n# 2.17.3\n- 🐞 修复：左侧菜单栏不显示 #327\n# 2.17.2\n- 😄 优化：设置服务端设置 填写key 一键同步mj，suno\n- 😄 优化：左侧菜单栏可以配置 通过环境变量调整 `MENU_DISABLE=\"gpts,music,gallery\"` #308\n- 😄 新增：gemini-pro-1.5 模型 #326\n- 😄 优化：`gemini-pro-vision` `gemini-pro-1.5`   `gpt-4-turbo`,`gpt-4-turbo-2024-04-09`  模型 可读base64图 #326\n\n# 2.17.1\n- 😄 优化：模型选择可搜索\n- 😄 优化：suno错误提示 #305\n- 🐞 修复：mj-api-secret 为空时出错 #295\n- 🐞 修复：fix CLOSE_MD_PREVIEW #316\n\n# 2.16.10\n- 😄 新增：suno音乐 单独模块\n\n# 2.16.9\n- 😄 修复：桌面端程序版本问题\n\n# 2.16.8\n- 😄 新增：桌面端程序\n\n\n# 2.16.7\n- 😄 新增：新模型 `gpt-4-turbo-2024-04-09`\n\n \n# 2.16.6\n- 🐞 修复：手机端不支持 `sref` `cref`\n- 😄 新增：`sref` `cref` 上传至discord做为图床 \n- 😄 新增：新模型 `suno-v3`\n\n# 2.16.5\n- 🐞 修复：nPaint image editor sources availability #248\n- 🐞 修复：Bugs in supporing customer models #235\n\n# 2.16.4\n- 😄 新增：turnstile 安全认证\n- 🐞 修复：模型切换导致模型错乱\n- 🐞 修复：访问上传文件需认证\n\n# 2.16.3\n- 😄 新增：MJ `cref` `sref` `cw` 参数 \n- 🐞 修复：MJ功能问题反馈 #228 \n- 🐞 修复：关于余额用量精确度的问题建议 #223\n- 🐞 修复：mj 清参数 按钮\n- 🐞 修复：更新对话模型 未能更新窗口列表\n\n# 2.16.2\n- 😄 新增：MJ `--cref 图片url` 生成角色一致的图像\n- 🐞 优化：新开会话模型 每个会话一个自己的模型 #211 #193 \n\n# 2.16.1\n- 🐞 修复：头像链接加载很慢 #212\n- 🐞 修复：关于模型`claude-3`  `max_tokens` 增加为 4k #214\n\n# 2.15.10\n- 🐞 修复：Midjourney Proxy v2.5.5 API后端不接受 index为0的重绘提交 #209 #210 感谢 @hugoshao PR\n- 🐞 修复：Drawing 多语言本地化问题  #201 感谢 @hugoshao PR\n- 😄 新增：`claude-3-sonnet-20240229` `claude-3-opus-20240229` 而 `claude-3-opus-20240229` 可支持传图 #207\n\n# 2.15.9\n- 🐞 修复：聊天记录能导出，但是导入没成功 #197\n- 😄 PR：编辑对话内容 感谢 PR人 @bigQY\n\n# 2.15.8\n- 🐞 修复：dark模型下的code显示有问题\n- 😄 新增：环境变量 `UPLOAD_TYPE` 指定上传方式 ['R2' R2上传] ['API' 跟随UI前端中转]、['Container' 本地容器]、['MyUrl' 自定义链接]   #178\n- 😄 调整：MJ默认调整为 `v6`\n\n# 2.15.7\n- 🐞 修复：mj提交错误提示 规范化\n- 😄 新增：实时语音识别\n\n# 2.15.6\n- 🐞 修复：微信绘图弹窗兼容问题 #177 \n- 😄 新增：环境变量控制 `CLOSE_MD_PREVIEW=1`，是否开启输入MD预览 #124\n- 😄 新增：防爆破验证 相关变量 `AUTH_SECRET_ERROR_COUNT=3` `AUTH_SECRET_ERROR_TIME=10`\n\n# 2.15.5\n- 🐞 修复：授权提示 `请重新输入授权访问密码`\n- 😄 新增：提交版本信息\n- 😄 新增：@触发使用过的GPTs #140\n\n# 2.15.4\n- 🐞 修复：mj 上传文件 服务端授权认证( vercel 暂不支持) #157\n# 2.15.3\n- 🐞 修复：服务端授权认证( vercel 暂不支持) #138\n\n# 2.15.2\n- 😄 新增： 输入预览 增加md功能 #124\n- 🐞 修复： 更新模型logo未变化 #137\n- 😄 新增： 模型 `gpt-3.5-turbo-0125`\n- 😄 新增： MJ 模型 `niji V6`\n\n# 2.15.1\n- 🐞 修复： tts转化在微信内播放有问题 #126 @yoke1990\n- 🐞 修复： 自定义GPTs 在vercel 不可使用 #115\n- 🐞 修复： 针对每一个对话分别设置模型无效 #128 感谢\n- 🔨 优化： MJ 绘画选项组合优化，减少提示词给mj提示错误 #127 感谢 @yoke1990\n- 🔨 优化： 清空同时清空标题 #117  \n- 😄 新增： 环境变量主题 `SYS_THEME` 主题 `light`或者`dark` 默认 `dark` ( 新版本需要 清缓存 ) #123\n\n\n# 2.14.10\n- 😄 新增： TTS 人物设置\n- 😄 新增： 环境变量 `UPLOAD_IMG_SIZE` #27\n- 🔨 优化： GPTs 踩、赞 \n- 🔨 优化： 自定义GPTs\n\n# 2.14.9\n- 😄 新增： 模型 `gpt-4-0125-preview`\n\n# 2.14.8\n- 🐞 修复：垫图图片不能2次使用\n- 😄 新增：标头 列表页\n\n# 2.14.7\n- 😄 新增： 补回`temperature` 和 `top_p` `presence_penalty` `frequency_penalty`设置  #86\n- 😄 优化： 切换模型中  所有设置能随着对话框保存\n- 🐞 修复： 默认画图打开 #99\n\n# 2.14.6\n- 😄 新增： 语言版本`法语` `土耳其语` 感谢 @M4K4R PR\n- 🐞 修复： 手机端token被遮挡  #98\n- 🐞 修复： 环境变量 打开wsrv图片图床 `MJ_IMG_WSRV=1`\n- 🐞 修复： midjourney图片 wsrv图床 bug\n\n# 2.14.5\n- 😄 新增： midjourney wsrv访问图片\n# 2.14.4\n- 🐞 修复：手机端的页面绘画不出图 #59\n- 🐞 修复：midjourney 强制刷新不起作用\n# 2.14.3\n- 😄 新增： 角色自定到会话 #75 #40\n- 😄 新增： 支持one-api部署聊天 https://vercel.ddaiai.com/#/?settings={%22key%22:%22sk-abc%22,%22url%22:%22https://api.openai.com%22}\n\n# 2.14.2\n- 🐞 修复： gpt-4-1106-preview 模型 128000 #66\n- 😄 新增： 录音whisper转文本对话ChatGPT\n- 😄 新增： 对话内容tts转语音\n- 😄 新增： 文件上传支持 `cloudflare r2 存储` 感谢 @xuzhenjun130 PR\n\n# 2.14.1\n- 🐞 修复： gpt-4-1106-preview 模型 128k #66\n- 🐞 修复： 余额显示方式 #61\n- 😄 新增： `DISABLE_GPT4=1` 控制不让用 GPT-4 #65\n- 😄 新增： `OpenAi Api Key 错误` 对话框中出现引导设置\n\n# 2.13.10\n- 🔨 优化： 输入实时计算剩余tokens #63\n- 🐞 修复： 重新获取bug\n\n# 2.13.9\n- 😄 新增： 超链设置\n\n# 2.13.8\n- 🐞 修复： #55 将画图提示词加到2000字\n- 🔨 优化： 上传.加入进度条\n- 😄 新增： midjourney `清设置`按钮\n- 😄 新增： midjourney `自定义变焦`功能\n\n\n# 2.13.7\n- 🐞 修复： #55 名称错误\n- 😄 新增： midjourney shorten 操作\n- 🐞 修复： 手机端无GPTs入口\n\n# 2.13.6\n- 🔨 优化： UI服务端保存\n- 😄 新增： 国际化语言包\n\n## 2.13.5\n- 🐞 修复： 历史记录未带附件链接\n- 😄 新增： 系统通知 #47\n\n## 2.13.4\n- 🐞 修复： midjourney 参数不起作用\n\n## 2.13.3\n- 😄 更新： 更新本月使用量、余额的请求方式\n\n## 2.13.2 \n- 🐞 修复： midjourney 刷新错误\n- ✅ 新增： tts whisper 界面支持\n- 😄 新增： midjourney 新增 V6\n\n\n## 2.13.1 \n- 🐞 修复： gpts 加载排序\n- 😄 新增： google、百度统计\n- 😄 新增： 文件支持拖拽上传、粘贴截图上传 #39\n\n\n## 2.12.11 \n- 🐞 紧急修复： gpt-4-vision-preview 格式错误\n\n## 2.12.10 \n- 🐞 修复：希望实现左侧绘画功能区固定，不随对话界面上下滚动 #29\n- 🐞 修复：当服务端有错误，ui错误显示为空bug \n- 🔨 优化：新增 `CUSTOM_MODELS` 环境变量 可自定义可选模型 #32\n \n\n\n## 2.12.9 \n- 🐞 修复：按住回车不放，会一直触发提交刷新页面 #24\n- 🔨 优化：我的画廊 支持来之服务端的数据（适合自建服务器）\n- 🔨 优化：midjourney 新增 `原始链接` 按钮\n\n## 2.12.8\n- 😄 新增：我的画廊\n- 🐞 修复：重试按钮、停止按钮功能 #15\n\n\n## 2.12.7\n- 😄 新增：vercel 增加 AUTH_SECRET_KEY 可以访问输入验证 #15\n- 🐞 修复：OPENAI_API_MODEL 默认模型 同时支持 vercel #16\n- 🐞 修复：在手机端左侧没法下滑 #18\n\n\n## 2.12.6\n- 🐞 修复：`经常出现“新建聊天框”遮挡对话框的情况 ` #13\n- 🐞 修复：当GPTS在绘画窗口，切换不起效果\n- 🐞 修复：分页载入GPTs计数出现的问题\n\n## 2.12.5\n- 🔨 优化：丰富 GPTS 内容，可以搜索\n- 😄 新增：前端UI 设置 上传文件入口 #11\n- 🐞 修复：`经常出现“新建聊天框”遮挡对话框的情况 ` #13\n\n\n## 2.12.4\n- 😄 新增 dall-e-2模型\n- 🐞 修复：上传错误提示为空\n- 🐞 修复：`环境变量中配置的OPENAI_API_BASE_URL和OPENAI_API_KEY依旧没有效果，前端对话一直处于“思考中...”` #4\n\n## 2.12.3\n- 😄 新增 支持超链模型切换 http://ip:6013/#/m/gpt-4-all http://ip:6013/#/m/gpt-4-gizmo-1234\n- 😄 新增 支持 GPTs 多模态\n\n## 2.12.2\n- 😄 新增：支持文件后端上传（供给gpt-4-all gpt-4-gizmo-xxx 模型）！ 默认是关闭的 打开需要环境变量 API_UPLOADER=1\n- 😄 新增：支持逆向模型 gpt-4-all gpt-4-v gpt-4-gizmo-(gizmo_id)\n\n## 2.12.1\n- 😄 新增：图片上传图片 供gpt-4-vision-preview使用\n- 🐞 修复:：midjourney 辅助提示“模型版本” 去掉早期过时版本\n\n## 2.11.10\n- 🐞 修复：dall-e-3的大小规格\n- 😄 新增：gpt模型选择\n- 😄 新增：gpt自定义模型、上下文数、回复数\n- 🔩 更改：流请求方式由原来的axios改为fetch 打字效果更加顺滑\n\n## 2.11.9 \n- 😄 新增：dall-e-3 画图 \n## 2.11.8\n- 🐞 修复：midjourney 辅助提示“性格” 出现的bug\n- 😄 新增：最新版本检查\n- 😄 新增：midjourney 获取seed\n\n## 2.11.7\n- 😀 新增：midjourney 换脸\n- 😀 新增：midjourney 混图"
  },
  {
    "path": "docker-compose/docker-compose.yml",
    "content": "version: '3'\n\nservices:\n  gptweb:\n    container_name: chatgpt-web-midjourney-proxy\n    image: ydlhero/chatgpt-web-midjourney-proxy # 总是使用latest,更新时重新pull该tag镜像即可\n    ports:\n      - 6050:3002\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      # 必选\n      OPENAI_API_KEY: sk-xxxx\n      # API接口地址，可选，设置 OPENAI_API_KEY 时可用\n      OPENAI_API_BASE_URL:\n      # API模型，可选，设置 OPENAI_API_KEY 时可用\n      OPENAI_API_MODEL:\n      # 访问权限密钥，可选\n      AUTH_SECRET_KEY:\n      # midjourney 服务器地址，可选 可用下面的 http://midjourney-proxy:8080\n      MJ_SERVER:\n      # midjourney API密钥，可选\n      MJ_API_SECRET:\n      #API_UPLOADER 是否可以上传 1 可以其他都不可以，可选\n      API_UPLOADER:\n      #HIDE_SERVER 隐藏服务端 1，可选\n      HIDE_SERVER:\n      #自定义模型  CUSTOM_MODELS=-gpt-3.5-turbo-0301,gpt-4.5 不显示 gpt-3.5-turbo-0301 新增加 gpt-4.5，可选\n      CUSTOM_MODELS:\n      #TJ_BAIDU_ID 百度统计ID，可选\n      TJ_BAIDU_ID:\n      #TJ_GOOGLE_ID 谷歌统计ID，可选\n      TJ_GOOGLE_ID:\n      #SYS_NOTIFY 系统通知 支持HTML ，可选\n      SYS_NOTIFY:\n      #FILE_SERVER 文件服务器，可选 可以用下面的 http://fileserver:3012\n      FILE_SERVER: \n      #DISABLE_GPT4=1 前端限制GPT4调用，可选\n      DISABLE_GPT4:\n      # cloudflare r2 存储 10 GB/月 免费 https://www.cloudflare.com/zh-cn/developer-platform/r2/\n      R2_DOMAIN:\n      R2_BUCKET_NAME:\n      R2_ACCOUNT_ID:\n      R2_KEY_ID:\n      R2_KEY_SECRET:\n      ## UPLOAD_IMG_SIZE gpt-4-version 图片上传大小 单位是兆 注意别带单位 最好别超过10 \n      UPLOAD_IMG_SIZE: 1\n      # GPT_URL=/gpts.json  自定义GPTs模型\n      GPT_URL:\n      # SYS_THEME 主题 theme   light 或者 dark \n      SYS_THEME: dark\n      #关闭MD预览  CLOSE_MD_PREVIEW=1\n      CLOSE_MD_PREVIEW:\n      #爆破：验证次数 注意: vercel 不支持 nginx 请设置  proxy_set_header   X-Forwarded-For  $remote_addr;\n      AUTH_SECRET_ERROR_COUNT: 3\n      #爆破：验证停留时间 单位分钟 注意: vercel 不支持\n      AUTH_SECRET_ERROR_TIME: 10\n\n"
  },
  {
    "path": "docker-compose/gpt-mj/deploy.sh",
    "content": "#!/bin/bash\nset -e\ndocker compose pull\ndocker compose up -d --remove-orphans\n "
  },
  {
    "path": "docker-compose/gpt-mj/docker-compose.yml",
    "content": "version: '3'\nservices:\n  gptweb:\n    image: ydlhero/chatgpt-web-midjourney-proxy\n    ports:\n      - 6055:3002\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      # 必选\n      OPENAI_API_KEY: sk-xxxx\n      # API接口地址，可选，设置 OPENAI_API_KEY 时可用\n      OPENAI_API_BASE_URL:\n      # midjourney 服务器地址，可选 \n      MJ_SERVER: http://midjourney-proxy:8080\n      # midjourney API密钥，可选\n      MJ_API_SECRET: mjpassword\n\n  # midjourney服务 可选\n  midjourney-proxy:\n    image: novicezk/midjourney-proxy:2.5.5\n    restart: always\n    # ports:\n    #   - 6013:8080 #映射端口\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      mj.discord.guild-id: xxxx\n      mj.discord.channel-id: xxx\n      mj.discord.user-token: tooken-xxx\n      mj.api-secret: mjpassword\n\n\n\n"
  },
  {
    "path": "docker-compose/gpt-mj/readme.md",
    "content": "### 仅部署chatgpt和mj\n\n```shell\n    git clone https://github.com/Dooy/chatgpt-web-midjourney-proxy.git\n    cd chatgpt-web-midjourney-proxy/docker-compose/gpt-mj\n    #修改 docker-compose.yml 文件配置文件 \n\n    ./deploy.sh \n  ``` \n\n"
  },
  {
    "path": "docker-compose/gpts-mj-file/docker-compose.yml",
    "content": "version: '3'\n\nservices:\n  gptweb:\n    container_name: chatgpt-web-midjourney-proxy\n    image: ydlhero/chatgpt-web-midjourney-proxy # 总是使用latest,更新时重新pull该tag镜像即可\n    ports:\n      - 6050:3002\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      # 必选\n      OPENAI_API_KEY: sk-xxxx\n      # API接口地址，可选，设置 OPENAI_API_KEY 时可用\n      OPENAI_API_BASE_URL:\n      # 访问权限密钥，可选 注意修改\n      AUTH_SECRET_KEY: mygod\n      # midjourney 服务器地址，可选 可用下面的 http://midjourney-proxy:8080\n      MJ_SERVER: http://midjourney-proxy:8080\n      # midjourney API密钥，可选\n      MJ_API_SECRET: mygod\n      #API_UPLOADER 是否可以上传 1 可以其他都不可以，可选\n      API_UPLOADER: 1\n      #FILE_SERVER 文件服务器，可选 可以用下面的 http://fileserver:3012\n      FILE_SERVER: http://fileserver:3012\n      #爆破：验证次数 注意: vercel 不支持 nginx 请设置  proxy_set_header   X-Forwarded-For  $remote_addr;\n      AUTH_SECRET_ERROR_COUNT: 3\n      #爆破：验证停留时间 单位分钟 注意: vercel 不支持\n      AUTH_SECRET_ERROR_TIME: 10\n\n  # midjourney服务 可选\n  midjourney-proxy:\n    image: novicezk/midjourney-proxy:2.5.5\n    restart: always\n    # ports:\n    #   - 6013:8080 #映射端口\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      mj.discord.guild-id: xxx # xxx 如何获取\n      mj.discord.channel-id: xxx\n      mj.discord.user-token: xxx\n      mj.api-secret: mygod # MJ_API_SECRET\n  \n  #文件服务 可选\n  fileserver:\n    image: ydlhero/file-server:latest\n    restart: always\n    environment:\n      TZ: Asia/Shanghai # 指定时区\n      #对外显示的域名\n      SERVER_NAME: http://myip:3102\n    ports:\n      - \"3102:3102\"\n    volumes:\n      - /data/uploads:/app/uploads\n\n"
  },
  {
    "path": "docker-compose/gpts-mj-file/nginx/nginx.conf",
    "content": "server {\n\tlisten 80;\n\tserver_name  localhost;\n\tcharset utf-8;\n\terror_page   500 502 503 504  /50x.html;\n\t\n\t# 防止爬虫抓取\n\tif ($http_user_agent ~* \"360Spider|JikeSpider|Spider|spider|bot|Bot|2345Explorer|curl|wget|webZIP|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|NSPlayer|bingbot\")\n\t{\n\t\treturn 403;\n\t}\n\t\n\tlocation / {\n\t\t\troot /usr/share/nginx/html;\n   \t\ttry_files $uri /index.html;\n\t}\n\n\tlocation /api {\n\t\t\tproxy_set_header   X-Real-IP $remote_addr; #转发用户IP\n\t\t\tproxy_pass http://app:3002;\n\t}\n\n\tproxy_set_header Host $host;\n\tproxy_set_header X-Real-IP $remote_addr;\n\tproxy_set_header REMOTE-HOST $remote_addr;\n\tproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n}\n"
  },
  {
    "path": "docker-compose/gpts-mj-file/readme.md",
    "content": "### docker-compose 部署教程 \n\n```shell\n    git clone https://github.com/Dooy/chatgpt-web-midjourney-proxy.git\n    cd chatgpt-web-midjourney-proxy/docker-compose/gpts-mj-file\n    #修改 docker-compose.yml 文件配置问文件\n    \n    #如果执行有问题 请执行 start_h.sh\n    start.sh \n  ``` "
  },
  {
    "path": "docker-compose/gpts-mj-file/start.sh",
    "content": "#!/bin/bash\nset -e\n# docker compose pull\n# docker compose up -d --remove-orphans\ndocker-compose pull\ndocker-compose up -d --remove-orphans"
  },
  {
    "path": "docker-compose/gpts-mj-file/start_h.sh",
    "content": "#!/bin/bash\nset -e\ndocker compose pull\ndocker compose up -d --remove-orphans\n "
  },
  {
    "path": "docker-compose/readme.md",
    "content": "### docker-compose 部署教程\n- 将打包好的前端文件放到 `nginx/html` 目录下\n- ```shell\n  # 启动\n  docker-compose up -d\n  ```\n- ```shell\n  # 查看运行状态\n  docker ps\n  ```\n- ```shell\n  # 结束运行\n  docker-compose down\n  ```\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"zh-cmn-Hans\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\">\n\t<meta content=\"yes\" name=\"apple-mobile-web-app-capable\"/>\n\t<link rel=\"apple-touch-icon\" href=\"/favicon.ico\">\n\t<meta name=\"viewport\"\n\t\tcontent=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover\" />\n\t<title>ChatGPT Web Midjourney Proxy</title>\n\t<meta http-equiv=\"Expires\" content=\"0\">\n\t<meta http-equiv=\"Pragma\" content=\"no-cache\">\n\t<meta http-equiv=\"Cache-control\" content=\"no-cache\">\n\t<meta http-equiv=\"Cache\" content=\"no-cache\">\n\t\n</head>\n\n<body class=\"dark:bg-black\">\n\t<div id=\"app\">\n\t\t<style>\n\t\t\t.loading-wrap {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\talign-items: center;\n\t\t\t\theight: 100vh;\n\t\t\t}\n\n\t\t\t.balls {\n\t\t\t\twidth: 4em;\n\t\t\t\tdisplay: flex;\n\t\t\t\tflex-flow: row nowrap;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: space-between;\n\t\t\t}\n\n\t\t\t.balls div {\n\t\t\t\twidth: 0.8em;\n\t\t\t\theight: 0.8em;\n\t\t\t\tborder-radius: 50%;\n\t\t\t\tbackground-color: #4b9e5f;\n\t\t\t}\n\n\t\t\t.balls div:nth-of-type(1) {\n\t\t\t\ttransform: translateX(-100%);\n\t\t\t\tanimation: left-swing 0.5s ease-in alternate infinite;\n\t\t\t}\n\n\t\t\t.balls div:nth-of-type(3) {\n\t\t\t\ttransform: translateX(-95%);\n\t\t\t\tanimation: right-swing 0.5s ease-out alternate infinite;\n\t\t\t}\n\n\t\t\t@keyframes left-swing {\n\n\t\t\t\t50%,\n\t\t\t\t100% {\n\t\t\t\t\ttransform: translateX(95%);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t@keyframes right-swing {\n\t\t\t\t50% {\n\t\t\t\t\ttransform: translateX(-95%);\n\t\t\t\t}\n\n\t\t\t\t100% {\n\t\t\t\t\ttransform: translateX(100%);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\tbackground: #121212;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t\t<div class=\"loading-wrap\">\n\t\t\t<div class=\"balls\">\n\t\t\t\t<div></div>\n\t\t\t\t<div></div>\n\t\t\t\t<div></div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<script type=\"module\" src=\"/src/main.ts\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "kubernetes/README.md",
    "content": "## 增加一个Kubernetes的部署方式\n```\nkubectl apply -f deploy.yaml\n```\n\n### 如果需要Ingress域名接入\n```\nkubectl apply -f ingress.yaml\n```\n"
  },
  {
    "path": "kubernetes/deploy.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: chatgpt-web\n  labels:\n    app: chatgpt-web\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: chatgpt-web\n  strategy:\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: chatgpt-web\n    spec:\n      containers:\n        - image: chenzhaoyu94/chatgpt-web\n          name: chatgpt-web\n          imagePullPolicy: Always\n          ports:\n            - containerPort: 3002\n          env:\n            - name: OPENAI_API_KEY\n              value: sk-xxx\n            - name: OPENAI_API_BASE_URL\n              value: 'https://api.openai.com'\n            - name: OPENAI_API_MODEL\n              value: gpt-3.5-turbo\n            - name: API_REVERSE_PROXY\n              value: https://ai.fakeopen.com/api/conversation\n            - name: AUTH_SECRET_KEY\n              value: '123456'\n            - name: TIMEOUT_MS\n              value: '60000'\n            - name: SOCKS_PROXY_HOST\n              value: ''\n            - name: SOCKS_PROXY_PORT\n              value: ''\n            - name: HTTPS_PROXY\n              value: ''\n          resources:\n            limits:\n              cpu: 500m\n              memory: 500Mi\n            requests:\n              cpu: 300m\n              memory: 300Mi\n---\napiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app: chatgpt-web\n  name: chatgpt-web\nspec:\n  ports:\n    - name: chatgpt-web\n      port: 3002\n      protocol: TCP\n      targetPort: 3002\n  selector:\n    app: chatgpt-web\n  type: ClusterIP\n"
  },
  {
    "path": "kubernetes/ingress.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  annotations:\n    kubernetes.io/ingress.class: nginx\n    nginx.ingress.kubernetes.io/proxy-connect-timeout: '5'\n  name: chatgpt-web\nspec:\n  rules:\n    - host: chatgpt.example.com\n      http:\n        paths:\n          - backend:\n              service:\n                name: chatgpt-web\n                port:\n                  number: 3002\n            path: /\n            pathType: ImplementationSpecific\n  tls:\n    - secretName: chatgpt-web-tls\n"
  },
  {
    "path": "license",
    "content": "MIT License\n\nCopyright (c) 2023 Dooy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"chatgpt-web-midjourney-proxy\",\n  \"version\": \"2.26.1\",\n  \"private\": false,\n  \"description\": \"ChatGPT Web Midjourney Proxy\",\n  \"author\": \"Dooy <ydlhero@gmail.com>\",\n  \"keywords\": [\n    \"chatgpt-web\",\n    \"chatgpt\",\n    \"chatbot\",\n    \"Midjourney\",\n    \"Midjourney UI\",\n    \"Midjourney Proxy\",\n    \"gpts\",\n    \"gpts ui\",\n    \"vue\"\n  ],\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"run-p build-only\",\n    \"buildold\": \"run-p type-check build-only\",\n    \"preview\": \"vite preview\",\n    \"build-only\": \"vite build\",\n    \"type-check\": \"vue-tsc --noEmit\",\n    \"lint\": \"eslint .\",\n    \"lint:fix\": \"eslint . --fix\",\n    \"bootstrap\": \"pnpm install && pnpm run common:prepare\",\n    \"common:cleanup\": \"rimraf node_modules && rimraf pnpm-lock.yaml\",\n    \"common:prepare\": \"husky install\"\n  },\n  \"dependencies\": {\n    \"@ffmpeg/ffmpeg\": \"^0.12.10\",\n    \"@ffmpeg/util\": \"^0.12.1\",\n    \"@traptitech/markdown-it-katex\": \"^3.6.0\",\n    \"@vueuse/core\": \"^9.13.0\",\n    \"eventsource-parser\": \"^1.1.1\",\n    \"form-data\": \"^4.0.0\",\n    \"gpt-tokenizer\": \"^2.1.2\",\n    \"highlight.js\": \"^11.7.0\",\n    \"html2canvas\": \"^1.4.1\",\n    \"js-audio-recorder\": \"^1.0.7\",\n    \"katex\": \"^0.16.4\",\n    \"localforage\": \"^1.10.0\",\n    \"markdown-it\": \"^13.0.1\",\n    \"naive-ui\": \"^2.34.3\",\n    \"pinia\": \"^2.0.33\",\n    \"vue\": \"^3.2.47\",\n    \"vue-i18n\": \"^9.2.2\",\n    \"vue-router\": \"^4.1.6\",\n    \"vue-turnstile\": \"^1.0.8\",\n    \"vue-waterfall-plugin-next\": \"^2.3.1\"\n  },\n  \"devDependencies\": {\n    \"@antfu/eslint-config\": \"^0.35.3\",\n    \"@commitlint/cli\": \"^17.4.4\",\n    \"@commitlint/config-conventional\": \"^17.4.4\",\n    \"@iconify/vue\": \"^4.1.0\",\n    \"@openai/realtime-api-beta\": \"github:dooy/openai-realtime-api-beta\",\n    \"@openai/realtime-wavtools\": \"github:dooy/openai-realtime-wavtools\",\n    \"@tauri-apps/cli\": \"^1.5.11\",\n    \"@types/crypto-js\": \"^4.1.1\",\n    \"@types/katex\": \"^0.16.0\",\n    \"@types/markdown-it\": \"^12.2.3\",\n    \"@types/markdown-it-link-attributes\": \"^3.0.1\",\n    \"@types/node\": \"^18.14.6\",\n    \"@vitejs/plugin-vue\": \"^4.0.0\",\n    \"autoprefixer\": \"^10.4.13\",\n    \"axios\": \"^1.3.4\",\n    \"crypto-js\": \"^4.1.1\",\n    \"eslint\": \"^8.35.0\",\n    \"http-proxy-middleware\": \"^2.0.6\",\n    \"husky\": \"^8.0.3\",\n    \"less\": \"^4.1.3\",\n    \"lint-staged\": \"^13.1.2\",\n    \"markdown-it-link-attributes\": \"^4.0.1\",\n    \"npm-run-all\": \"^4.1.5\",\n    \"postcss\": \"^8.4.21\",\n    \"rimraf\": \"^4.2.0\",\n    \"tailwindcss\": \"^3.3.6\",\n    \"typescript\": \"~4.9.5\",\n    \"vite\": \"^4.2.0\",\n    \"vite-plugin-pwa\": \"^0.14.4\",\n    \"vite-plugin-static-copy\": \"^0.17.0\",\n    \"vue-tsc\": \"^1.2.0\"\n  },\n  \"lint-staged\": {\n    \"*.{ts,tsx,vue}\": [\n      \"pnpm lint:fix\"\n    ]\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "public/gpts.json",
    "content": "{\n    \"tag\": [\n        \"图像\",\n        \"论文\",\n        \"文件\",\n        \"识别\",\n        \"PDF\",\n        \"新闻\",\n        \"医生\",\n        \"老师\",\n        \"Logo\"\n    ],\n    \"gpts\": [\n        {\n            \"gid\": \"gpt-4-all\",\n            \"name\": \"gpt-4-all\",\n            \"logo\": \"https://cos.aitutu.cc/gpts/gpt4all.jpg\",\n            \"info\": \"集合官方GPT-4、联网，多模态（gpt-4v），绘图功能（dall-e3），限制不支持function等\",\n            \"use_cnt\": \"8624\",\n            \"bad\": \"0\"\n        },\n        {\n            \"gid\": \"gpt-4-gizmo-g-2fkFE8rbu\",\n            \"name\": \"DALL·E\",\n            \"logo\": \"https://files.oaiusercontent.com/file-SxYQO0Fq1ZkPagkFtg67DRVb?se=2123-10-12T23%3A57%3A32Z&sp=r&sv=2021-08-06&sr=b&rscc=max-age%3D31536000%2C%20immutable&rscd=attachment%3B%20filename%3Dagent_3.webp&sig=pLlQh8oUktqQzhM09SDDxn5aakqFuM2FAPptuA0mbqc%3D\",\n            \"info\": \"让我将你的想象变成图像 – 基于 ChatGPT\",\n            \"use_cnt\": \"3087\",\n            \"bad\": \"1\"\n        }\n    ]\n}"
  },
  {
    "path": "service/.eslintrc.json",
    "content": "{\n  \"root\": true,\n  \"ignorePatterns\": [\"build\"],\n  \"extends\": [\"@antfu\"]\n}\n"
  },
  {
    "path": "service/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\n.DS_Store\ndist\ndist-ssr\ncoverage\n*.local\n\n/cypress/videos/\n/cypress/screenshots/\n\n# Editor directories and files\n.vscode/*\n!.vscode/settings.json\n!.vscode/extensions.json\n.idea\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\nbuild\n"
  },
  {
    "path": "service/.npmrc",
    "content": "enable-pre-post-scripts=true\n"
  },
  {
    "path": "service/.vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\"dbaeumer.vscode-eslint\"]\n}\n"
  },
  {
    "path": "service/.vscode/settings.json",
    "content": "{\n  \"prettier.enable\": false,\n  \"editor.formatOnSave\": false,\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": true\n  },\n  \"eslint.validate\": [\n    \"javascript\",\n    \"typescript\",\n    \"json\",\n    \"jsonc\",\n    \"json5\",\n    \"yaml\"\n  ],\n  \"cSpell.words\": [\n    \"antfu\",\n    \"chatgpt\",\n    \"esno\",\n    \"GPTAPI\",\n    \"OPENAI\"\n  ]\n}\n"
  },
  {
    "path": "service/package.json",
    "content": "{\n  \"name\": \"chatgpt-web-service\",\n  \"version\": \"2.15.6\",\n  \"private\": false,\n  \"description\": \"ChatGPT Web Midjourney Proxy\",\n  \"author\": \"ChenZhaoYu <ydlhero@gmail.com>\",\n  \"keywords\": [\n    \"chatgpt-web\",\n    \"chatgpt\",\n    \"chatbot\",\n    \"express\"\n  ],\n  \"engines\": {\n    \"node\": \"^16 || ^18 || ^19\"\n  },\n  \"scripts\": {\n    \"start\": \"esno ./src/index.ts\",\n    \"dev\": \"esno watch ./src/index.ts\",\n    \"prod\": \"node ./build/index.mjs\",\n    \"build\": \"pnpm clean && tsup\",\n    \"clean\": \"rimraf build\",\n    \"lint\": \"eslint .\",\n    \"lint:fix\": \"eslint . --fix\",\n    \"common:cleanup\": \"rimraf node_modules && rimraf pnpm-lock.yaml\"\n  },\n  \"dependencies\": {\n    \"aws-sdk\": \"^2.1535.0\",\n    \"axios\": \"^1.3.4\",\n    \"body-parser\": \"^1.20.2\",\n    \"chatgpt\": \"^5.1.2\",\n    \"dotenv\": \"^16.0.3\",\n    \"esno\": \"^0.16.3\",\n    \"express\": \"^4.18.2\",\n    \"express-http-proxy\": \"^2.0.0\",\n    \"express-rate-limit\": \"^6.7.0\",\n    \"form-data\": \"^4.0.0\",\n    \"http-proxy-middleware\": \"^2.0.6\",\n    \"https-proxy-agent\": \"^5.0.1\",\n    \"isomorphic-fetch\": \"^3.0.0\",\n    \"md5\": \"^2.3.0\",\n    \"multer\": \"1.4.5-lts.1\",\n    \"node-fetch\": \"^3.3.0\",\n    \"socks-proxy-agent\": \"^7.0.0\",\n    \"uuid\": \"^9.0.1\"\n  },\n  \"devDependencies\": {\n    \"@antfu/eslint-config\": \"^0.35.3\",\n    \"@types/express\": \"^4.17.17\",\n    \"@types/node\": \"^18.14.6\",\n    \"eslint\": \"^8.35.0\",\n    \"rimraf\": \"^4.3.0\",\n    \"tsup\": \"^6.6.3\",\n    \"typescript\": \"^4.9.5\"\n  }\n}\n"
  },
  {
    "path": "service/src/chatgpt/index.ts",
    "content": "import * as dotenv from 'dotenv'\nimport 'isomorphic-fetch'\nimport type { ChatGPTAPIOptions, ChatMessage, SendMessageOptions } from 'chatgpt'\nimport { ChatGPTAPI, ChatGPTUnofficialProxyAPI } from 'chatgpt'\nimport { SocksProxyAgent } from 'socks-proxy-agent'\nimport httpsProxyAgent from 'https-proxy-agent'\nimport fetch from 'node-fetch'\nimport { sendResponse } from '../utils'\nimport { isNotEmptyString } from '../utils/is'\nimport type { ApiModel, ChatContext, ChatGPTUnofficialProxyAPIOptions, ModelConfig } from '../types'\nimport type { RequestOptions, SetProxyOptions, UsageResponse } from './types'\n\nconst { HttpsProxyAgent } = httpsProxyAgent\n\ndotenv.config()\n\nconst ErrorCodeMessage: Record<string, string> = {\n  401: '[OpenAI] 提供错误的API密钥 | Incorrect API key provided',\n  403: '[OpenAI] 服务器拒绝访问，请稍后再试 | Server refused to access, please try again later',\n  502: '[OpenAI] 错误的网关 |  Bad Gateway',\n  503: '[OpenAI] 服务器繁忙，请稍后再试 | Server is busy, please try again later',\n  504: '[OpenAI] 网关超时 | Gateway Time-out',\n  500: '[OpenAI] 服务器繁忙，请稍后再试 | Internal Server Error',\n}\n\nconst timeoutMs: number = !isNaN(+process.env.TIMEOUT_MS) ? +process.env.TIMEOUT_MS : 100 * 1000\nconst disableDebug: boolean = process.env.OPENAI_API_DISABLE_DEBUG === 'true'\n\nlet apiModel: ApiModel\nconst model = isNotEmptyString(process.env.OPENAI_API_MODEL) ? process.env.OPENAI_API_MODEL : 'gpt-3.5-turbo'\n\nif (!isNotEmptyString(process.env.OPENAI_API_KEY) && !isNotEmptyString(process.env.OPENAI_ACCESS_TOKEN)){\n  process.env.OPENAI_API_BASE_URL=\"https://api.openai.com\"\n  process.env.OPENAI_API_KEY=\"sk-xxx\"\n}\n  //throw new Error('Missing OPENAI_API_KEY or OPENAI_ACCESS_TOKEN environment variable')\n\nlet api: ChatGPTAPI | ChatGPTUnofficialProxyAPI\n\n(async () => {\n  // More Info: https://github.com/transitive-bullshit/chatgpt-api\n\n  if (isNotEmptyString(process.env.OPENAI_API_KEY)) {\n    const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL\n\n    const options: ChatGPTAPIOptions = {\n      apiKey: process.env.OPENAI_API_KEY,\n      completionParams: { model },\n      debug: !disableDebug,\n    }\n\n    // increase max token limit if use gpt-4\n    if (model.toLowerCase().includes('gpt-4')) {\n      // if use 32k model\n      if (model.toLowerCase().includes('32k')) {\n        options.maxModelTokens = 32768\n        options.maxResponseTokens = 8192\n      }\n      else {\n        options.maxModelTokens = 8192\n        options.maxResponseTokens = 2048\n      }\n    }\n    else if (model.toLowerCase().includes('gpt-3.5')) {\n      if (model.toLowerCase().includes('16k')) {\n        options.maxModelTokens = 16384\n        options.maxResponseTokens = 4096\n      }\n    }\n\n    if (isNotEmptyString(OPENAI_API_BASE_URL))\n      options.apiBaseUrl = `${OPENAI_API_BASE_URL}/v1`\n\n    setupProxy(options)\n\n    api = new ChatGPTAPI({ ...options })\n    apiModel = 'ChatGPTAPI'\n  }\n  else {\n    const options: ChatGPTUnofficialProxyAPIOptions = {\n      accessToken: process.env.OPENAI_ACCESS_TOKEN,\n      apiReverseProxyUrl: isNotEmptyString(process.env.API_REVERSE_PROXY) ? process.env.API_REVERSE_PROXY : 'https://ai.fakeopen.com/api/conversation',\n      model,\n      debug: !disableDebug,\n    }\n\n    setupProxy(options)\n\n    api = new ChatGPTUnofficialProxyAPI({ ...options })\n    apiModel = 'ChatGPTUnofficialProxyAPI'\n  }\n})()\n\nasync function chatReplyProcess(options: RequestOptions) {\n  const { message, lastContext, process, systemMessage, temperature, top_p } = options\n  try {\n    let options: SendMessageOptions = { timeoutMs }\n\n    if (apiModel === 'ChatGPTAPI') {\n      if (isNotEmptyString(systemMessage))\n        options.systemMessage = systemMessage\n      options.completionParams = { model, temperature, top_p }\n    }\n\n    if (lastContext != null) {\n      if (apiModel === 'ChatGPTAPI')\n        options.parentMessageId = lastContext.parentMessageId\n      else\n        options = { ...lastContext }\n    }\n\n    const response = await api.sendMessage(message, {\n      ...options,\n      onProgress: (partialResponse) => {\n        process?.(partialResponse)\n      },\n    })\n\n    return sendResponse({ type: 'Success', data: response })\n  }\n  catch (error: any) {\n    const code = error.statusCode\n    global.console.log(error)\n    if (Reflect.has(ErrorCodeMessage, code))\n      return sendResponse({ type: 'Fail', message: ErrorCodeMessage[code] })\n    return sendResponse({ type: 'Fail', message: error.message ?? 'Please check the back-end console' })\n  }\n}\n\nasync function fetchUsage() {\n  const OPENAI_API_KEY = process.env.OPENAI_API_KEY\n  const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL\n\n  if (!isNotEmptyString(OPENAI_API_KEY))\n    return Promise.resolve('-')\n\n  const API_BASE_URL = isNotEmptyString(OPENAI_API_BASE_URL)\n    ? OPENAI_API_BASE_URL\n    : 'https://api.openai.com'\n\n  const [startDate, endDate] = formatDate()\n\n  // 每月使用量\n  const urlUsage = `${API_BASE_URL}/v1/dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}`\n\n  const headers = {\n    'Authorization': `Bearer ${OPENAI_API_KEY}`,\n    'Content-Type': 'application/json',\n  }\n\n  const options = {} as SetProxyOptions\n\n  setupProxy(options)\n\n  try {\n    // 获取已使用量\n    const useResponse = await options.fetch(urlUsage, { headers })\n    if (!useResponse.ok)\n      throw new Error('获取使用量失败')\n    const usageData = await useResponse.json() as UsageResponse\n    const usage = Math.round(usageData.total_usage) / 100\n    return Promise.resolve(usage ? `$${usage}` : '-')\n  }\n  catch (error) {\n    global.console.log(error)\n    return Promise.resolve('-')\n  }\n}\n\nfunction formatDate(): string[] {\n  const today = new Date()\n  const year = today.getFullYear()\n  const month = today.getMonth() + 1\n  const lastDay = new Date(year, month, 0)\n  const formattedFirstDay = `${year}-${month.toString().padStart(2, '0')}-01`\n  const formattedLastDay = `${year}-${month.toString().padStart(2, '0')}-${lastDay.getDate().toString().padStart(2, '0')}`\n  return [formattedFirstDay, formattedLastDay]\n}\n\nasync function chatConfig() {\n  const usage = await fetchUsage()\n  const reverseProxy = process.env.API_REVERSE_PROXY ?? '-'\n  const httpsProxy = (process.env.HTTPS_PROXY || process.env.ALL_PROXY) ?? '-'\n  const socksProxy = (process.env.SOCKS_PROXY_HOST && process.env.SOCKS_PROXY_PORT)\n    ? (`${process.env.SOCKS_PROXY_HOST}:${process.env.SOCKS_PROXY_PORT}`)\n    : '-'\n  return sendResponse<ModelConfig>({\n    type: 'Success',\n    data: { apiModel, reverseProxy, timeoutMs, socksProxy, httpsProxy, usage },\n  })\n}\n\nfunction setupProxy(options: SetProxyOptions) {\n  if (isNotEmptyString(process.env.SOCKS_PROXY_HOST) && isNotEmptyString(process.env.SOCKS_PROXY_PORT)) {\n    const agent = new SocksProxyAgent({\n      hostname: process.env.SOCKS_PROXY_HOST,\n      port: process.env.SOCKS_PROXY_PORT,\n      userId: isNotEmptyString(process.env.SOCKS_PROXY_USERNAME) ? process.env.SOCKS_PROXY_USERNAME : undefined,\n      password: isNotEmptyString(process.env.SOCKS_PROXY_PASSWORD) ? process.env.SOCKS_PROXY_PASSWORD : undefined,\n    })\n    options.fetch = (url, options) => {\n      return fetch(url, { agent, ...options })\n    }\n  }\n  else if (isNotEmptyString(process.env.HTTPS_PROXY) || isNotEmptyString(process.env.ALL_PROXY)) {\n    const httpsProxy = process.env.HTTPS_PROXY || process.env.ALL_PROXY\n    if (httpsProxy) {\n      const agent = new HttpsProxyAgent(httpsProxy)\n      options.fetch = (url, options) => {\n        return fetch(url, { agent, ...options })\n      }\n    }\n  }\n  else {\n    options.fetch = (url, options) => {\n      return fetch(url, { ...options })\n    }\n  }\n}\n\nfunction currentModel(): ApiModel {\n  return apiModel\n}\n\nexport type { ChatContext, ChatMessage }\n\nexport { chatReplyProcess, chatConfig, currentModel }\n"
  },
  {
    "path": "service/src/chatgpt/types.ts",
    "content": "import type { ChatMessage } from 'chatgpt'\nimport type fetch from 'node-fetch'\n\nexport interface RequestOptions {\n  message: string\n  lastContext?: { conversationId?: string; parentMessageId?: string }\n  process?: (chat: ChatMessage) => void\n  systemMessage?: string\n  temperature?: number\n  top_p?: number\n}\n\nexport interface SetProxyOptions {\n  fetch?: typeof fetch\n}\n\nexport interface UsageResponse {\n  total_usage: number\n}\n"
  },
  {
    "path": "service/src/index.ts",
    "content": "import express from 'express'\nimport type { RequestProps } from './types'\nimport type { ChatMessage } from './chatgpt'\nimport { chatConfig, chatReplyProcess, currentModel } from './chatgpt'\nimport { auth, authV2, mlog, regCookie, turnstileCheck, verify } from './middleware/auth'\nimport { limiter } from './middleware/limiter'\nimport { isNotEmptyString,formattedDate } from './utils/is'\nimport multer from \"multer\"\nimport path from \"path\"\nimport fs from \"fs\"\nimport pkg from '../package.json'\n// const { createProxyMiddleware } = require('http-proxy-middleware');\n//import {createProxyMiddleware} from \"http-proxy-middleware\"\nimport  proxy from \"express-http-proxy\"\nimport bodyParser  from 'body-parser';\nimport FormData  from 'form-data'\nimport axios from 'axios';\nimport AWS  from 'aws-sdk';\nimport { v4 as uuidv4} from 'uuid';\nimport { viggleProxyFileDo,viggleProxy, lumaProxy, runwayProxy, ideoProxy, ideoProxyFileDo, klingProxy, pikaProxy, udioProxy, runwaymlProxy, pixverseProxy, sunoProxy, GptImageEdit } from './myfun'\n\n\nconst app = express()\nconst router = express.Router()\n\napp.use(express.static('public' ,{\n  // 设置响应头，允许带有查询参数的请求访问静态文件\n  setHeaders: (res, path, stat) => {\n    res.set('Cache-Control', 'public, max-age=1');\n  }\n} ))\n//app.use(express.json())\napp.use(bodyParser.json({ limit: '10mb' })); //大文件传输\n\n\n\napp.all('*', (_, res, next) => {\n  res.header('Access-Control-Allow-Origin', '*')\n  res.header('Access-Control-Allow-Headers', 'authorization, Content-Type')\n  res.header('Access-Control-Allow-Methods', '*')\n  next()\n})\n\nrouter.post('/chat-process',authV2 , async (req, res) => { //[authV2, limiter]\n  res.setHeader('Content-type', 'application/octet-stream')\n\n  try {\n    const { prompt, options = {}, systemMessage, temperature, top_p } = req.body as RequestProps\n    let firstChunk = true\n    await chatReplyProcess({\n      message: prompt,\n      lastContext: options,\n      process: (chat: ChatMessage) => {\n        res.write(firstChunk ? JSON.stringify(chat) : `\\n${JSON.stringify(chat)}`)\n        firstChunk = false\n      },\n      systemMessage,\n      temperature,\n      top_p,\n    })\n  }\n  catch (error) {\n    res.write(JSON.stringify(error))\n  }\n  finally {\n    res.end()\n  }\n})\n\nrouter.post('/config', auth, async (req, res) => {\n  try {\n    const response = await chatConfig()\n    res.send(response)\n  }\n  catch (error) {\n    res.send(error)\n  }\n})\n\nrouter.post('/session', async (req, res) => {\n  try {\n    const AUTH_SECRET_KEY = process.env.AUTH_SECRET_KEY\n    const hasAuth = isNotEmptyString(AUTH_SECRET_KEY)\n    const isUpload= isNotEmptyString(  process.env.API_UPLOADER )\n    const isHideServer= isNotEmptyString(  process.env.HIDE_SERVER );\n    const amodel=   process.env.OPENAI_API_MODEL?? \"gpt-3.5-turbo\" ;\n    const isApiGallery=  isNotEmptyString(  process.env.MJ_API_GALLERY );\n    const cmodels =   process.env.CUSTOM_MODELS??'' ;\n    const baiduId=process.env.TJ_BAIDU_ID?? \"\" ;\n    const googleId=process.env.TJ_GOOGLE_ID?? \"\" ;\n    const notify = process.env.SYS_NOTIFY?? \"\" ;\n    const disableGpt4 = process.env.DISABLE_GPT4?? \"\" ;\n    const isUploadR2 = isNotEmptyString(process.env.R2_DOMAIN);\n    const isWsrv =  process.env.MJ_IMG_WSRV?? \"\" \n    const uploadImgSize =  process.env.UPLOAD_IMG_SIZE?? \"5\" \n    const gptUrl = process.env.GPT_URL?? \"\"; \n    const theme = process.env.SYS_THEME?? \"dark\"; \n    const isCloseMdPreview = process.env.CLOSE_MD_PREVIEW?true:false\n    const uploadType= process.env.UPLOAD_TYPE\n    const turnstile= process.env.TURNSTILE_SITE\n    const menuDisable= process.env.MENU_DISABLE??\"\"\n    const visionModel= process.env.VISION_MODEL??\"\"\n    const systemMessage= process.env.SYSTEM_MESSAGE??\"\"\n    const customVisionModel= process.env.CUSTOM_VISION_MODELS??\"\"\n    const backgroundImage = process.env.BACKGROUND_IMAGE ?? \"\"\n    let  isHk= (process.env.OPENAI_API_BASE_URL??\"\").toLocaleLowerCase().indexOf('-hk')>0\n    if(!isHk)  isHk= (process.env.LUMA_SERVER??\"\").toLocaleLowerCase().indexOf('-hk')>0\n    if(!isHk)  isHk= (process.env.VIGGLE_SERVER??\"\").toLocaleLowerCase().indexOf('-hk')>0\n    \n\n    const data= { disableGpt4,isWsrv,uploadImgSize,theme,isCloseMdPreview,uploadType,\n      notify , baiduId, googleId,isHideServer,isUpload, auth: hasAuth\n      , model: currentModel(),amodel,isApiGallery,cmodels,isUploadR2,gptUrl\n      ,turnstile,menuDisable,visionModel,systemMessage,customVisionModel,backgroundImage,isHk\n    }\n    res.send({  status: 'Success', message: '', data})\n  }\n  catch (error) {\n    res.send({ status: 'Fail', message: error.message, data: null })\n  }\n})\n\nrouter.post('/verify', verify)\nrouter.get('/reg', regCookie )\n\n const API_BASE_URL = isNotEmptyString(process.env.OPENAI_API_BASE_URL)\n    ? process.env.OPENAI_API_BASE_URL\n    : 'https://api.openai.com'\n\napp.use('/mjapi',authV2 , proxy(process.env.MJ_SERVER?process.env.MJ_SERVER:'https://api.openai.com', {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return req.originalUrl.replace('/mjapi', '') // 将URL中的 `/mjapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    if(  process.env.MJ_API_SECRET ) proxyReqOpts.headers['mj-api-secret'] = process.env.MJ_API_SECRET;\n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  //limit: '10mb'\n\n}));\n\n\n\n// 设置存储引擎和文件保存路径\nconst storage = multer.diskStorage({\n  destination: function (req, file, cb) {\n    let uploadFolderPath=`./uploads/${formattedDate()}/`;//`\n\n    //console.log('dir', __dirname   ) ;\n\n    if(!fs.existsSync('./uploads/')) {\n      fs.mkdirSync('./uploads/');\n    }\n    if(!fs.existsSync(uploadFolderPath)) {\n      fs.mkdirSync(uploadFolderPath);\n    }\n    cb(null, `uploads/${formattedDate()}/`);\n  },\n  filename: function (req, file, cb) {\n    let filename=  Date.now() + path.extname(file.originalname);\n    console.log( 'file',  filename );\n    cb(null, filename);\n  }\n});\nconst upload = multer({ storage: storage });\n\nconst storage2 = multer.memoryStorage();\nconst upload2 = multer({ storage: storage2 });\n\n// 处理文件上传的路由\nconst isUpload= isNotEmptyString(  process.env.API_UPLOADER )\nif(isUpload){\n  if( process.env.FILE_SERVER){\n    app.use('/openapi/v1/upload',\n    upload2.single('file'),\n      async (req, res, next) => {\n        //console.log( \"boday\",req.body ,  req.body.model );\n        if(req.file.buffer) {\n          const fileBuffer = req.file.buffer;\n          const formData = new FormData();\n          formData.append('file',  fileBuffer,  { filename:  req.file.originalname }  );\n          //formData.append('model',  req.body.model );\n        try{\n          let url = process.env.FILE_SERVER ;\n          let responseBody = await axios.post( url , formData, {\n                  headers: {\n                  //Authorization: 'Bearer '+ process.env.OPENAI_API_KEY ,\n                  'Content-Type': 'multipart/form-data'\n                }\n            })   ;\n\n          res.json(responseBody.data );\n          }catch(e){\n            res.status( 400 ).json( {error: e } );\n          }\n        }else{\n          res.status(400).json({'error':'uploader fail'});\n        }\n      }\n    );\n  }\n  else{\n    app.use('/openapi/v1/upload', authV2, upload.single('file'), (req, res) => {\n    //res.send('文件上传成功！');\n    res.setHeader('Content-type', 'application/json' );\n    if(req.file.filename) res.json({ url:`/uploads/${formattedDate()}/${ req.file.filename  }`,created:Date.now() })\n    else res.json({ error:`uploader fail`,created:Date.now() })\n  });\n  }\n}else {\n  app.use('/openapi/v1/upload',  (req, res) => {\n    //res.send('文件上传成功！');\n     res.json({ error:`server is no open uploader `,created:Date.now() })\n  });\n}\napp.use('/uploads' , express.static('uploads'));\n\n// R2Client function\nconst R2Client = () => {\n  const accountId = process.env.R2_ACCOUNT_ID;\n  const accessKeyId = process.env.R2_KEY_ID;\n  const accessKeySecret = process.env.R2_KEY_SECRET;\n  const endpoint = new AWS.Endpoint(`https://${accountId}.r2.cloudflarestorage.com`);\n  const s3 = new AWS.S3({\n    endpoint: endpoint,\n    region: 'auto',\n    credentials: new AWS.Credentials(accessKeyId, accessKeySecret),\n\t\tsignatureVersion: 'v4',\n  });\n  return s3;\n};\n\n// cloudflare R2 upload\napp.post('/openapi/pre_signed', (req, res) => {\n  const bucketName = process.env.R2_BUCKET_NAME;\n  const domain = process.env.R2_DOMAIN;\n  const s3 = R2Client();\n  const fileName = uuidv4();\n  const saveFile = `${new Date().toISOString().split('T')[0]}/${fileName}${req.body.file_name}`;\n\n  const params = {\n    Bucket: bucketName,\n    Key: saveFile,\n    ContentType: req.body.ContentType,\n    Expires: 60 * 60, // 1 hour\n  };\n\n  s3.getSignedUrl('putObject', params, (err, url) => {\n    if (err) {\n      res.status(500).json({\n        status: 'Error',\n        message: `Couldn't get presigned URL for PutObject: ${err.message}`\n      });\n      return;\n    }\n\n    res.json({\n      status: 'Success',\n      message: '',\n      data: {\n        up: url,\n        url: `${domain}/${saveFile}`\n      }\n    });\n  });\n});\n\napp.use(\n  '/openapi/v1/audio/transcriptions',authV2,\n  upload2.single('file'),\n  async (req, res, next) => {\n    //console.log( \"boday\",req.body ,  req.body.model );\n    if(req.file.buffer) {\n      const fileBuffer = req.file.buffer;\n      const formData = new FormData();\n      formData.append('file',  fileBuffer,  { filename:  req.file.originalname }  );\n      formData.append('model',  req.body.model );\n     try{\n       let url = `${API_BASE_URL}/v1/audio/transcriptions` ;\n      let responseBody = await axios.post( url , formData, {\n              headers: {\n              Authorization: 'Bearer '+ process.env.OPENAI_API_KEY ,\n              'Content-Type': 'multipart/form-data',\n              'Mj-Version': pkg.version\n            }\n        })   ;\n        // console.log('responseBody', responseBody.data  );\n       res.json(responseBody.data );\n      }catch(e){\n        //console.log('goog',e );\n        res.status( 400 ).json( {error: e } );\n      }\n\n    }else{\n      res.status(400).json({'error':'uploader fail'});\n    }\n  }\n);\n\n//代理图片编辑\napp.use('/openapi/v1/images/edits',authV2,upload2.any() , GptImageEdit )\n\n//代理openai 接口\napp.use('/openapi' ,authV2, turnstileCheck, proxy(API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return req.originalUrl.replace('/openapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    proxyReqOpts.headers['Authorization'] ='Bearer '+ process.env.OPENAI_API_KEY;\n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  //limit: '10mb'\n}));\n\n//代理sunoApi 接口 \napp.use('/sunoapi' ,authV2,sunoProxy );\napp.use('/suno' ,authV2,sunoProxy );\n\n\n\n//代理luma 接口 \napp.use('/luma' ,authV2, lumaProxy  );\napp.use('/pro/luma' ,authV2, lumaProxy );\n\n//代理 viggle 文件\napp.use('/viggle/asset',authV2 ,  upload2.single('file'), viggleProxyFileDo );\napp.use('/pro/viggle/asset',authV2 ,  upload2.single('file'), viggleProxyFileDo );\n//代理 viggle  \napp.use('/viggle' ,authV2, viggleProxy);\napp.use('/pro/viggle' ,authV2, viggleProxy);\n\napp.use('/runwayml' ,authV2, runwaymlProxy  );\napp.use('/runway' ,authV2, runwayProxy  );\napp.use('/kling' ,authV2, klingProxy  );\n\napp.use('/ideogram/remix' ,authV2,  upload2.single('image_file'), ideoProxyFileDo  );\napp.use('/ideogram' ,authV2, ideoProxy  );\napp.use('/pika' ,authV2, pikaProxy  );\napp.use('/udio' ,authV2, udioProxy  );\n\napp.use('/pixverse' ,authV2, pixverseProxy  );\n\n// WebDAV 代理接口\nrouter.post('/webdav-proxy', authV2, async (req, res) => {\n  try {\n    const { url, method, username, password, data } = req.body\n    \n    if (!url || !method || !username || !password) {\n      return res.status(400).json({ error: '缺少必要参数' })\n    }\n    \n    const auth = Buffer.from(`${username}:${password}`).toString('base64')\n    const headers: any = {\n      'Authorization': `Basic ${auth}`,\n    }\n    \n    if (method === 'PUT') {\n      headers['Content-Type'] = 'application/json'\n    }\n    \n    const axiosConfig: any = {\n      method,\n      url,\n      headers,\n      timeout: 30000,\n    }\n    \n    if (method === 'PUT' && data) {\n      axiosConfig.data = data\n    }\n    \n    const response = await axios(axiosConfig)\n    res.json({ \n      success: true, \n      status: response.status,\n      data: response.data \n    })\n  }\n  catch (error: any) {\n    res.status(error.response?.status || 500).json({ \n      success: false,\n      error: error.message,\n      status: error.response?.status\n    })\n  }\n})\n\n\n\napp.use('', router)\napp.use('/api', router)\napp.set('trust proxy', 1)\n\napp.listen(3002, () => globalThis.console.log('Server is running on port 3002'))\n"
  },
  {
    "path": "service/src/middleware/auth.ts",
    "content": "import { isNotEmptyString } from '../utils/is'\nimport { Request, Response, NextFunction } from 'express';\nimport FormData from 'form-data';\nimport fetch from 'node-fetch';\nimport md5 from 'md5';\n\n// 存储IP地址和错误计数的字典\nconst ipErrorCount = {};\n\n// 存储被禁止登录的IP地址及禁止结束时间的字典\nconst bannedIPs = {};\n\nexport const mlog =(...arg)=>{\n  //const M_DEBUG = process.env.M_DEBUG\n  // if(['error','log'].indexOf( arg[0] )>-1 ){ //必须显示的\n  // }else  if(! isNotEmptyString(process.env.M_DEBUG) ) return ;\n  \n  const currentDate = new Date();\n  const hours = currentDate.getHours().toString().padStart(2, '0');\n  const minutes = currentDate.getMinutes().toString().padStart(2, '0');\n  const seconds = currentDate.getSeconds().toString().padStart(2, '0');\n  const currentTime = `${hours}:${minutes}:${seconds}`;\n  console.log( currentTime,...arg)\n}\n\nexport const verify=  async ( req :Request , res:Response ) => {\n  try {\n    checkLimit( req, res );\n    const { token } = req.body as { token: string }\n    if (!token)\n      throw new Error('Secret key is empty')\n    \n    const auth_secret_keys = process.env.AUTH_SECRET_KEY? process.env.AUTH_SECRET_KEY.trim().split(',').filter(item => item !== ''):[];\n    if (!auth_secret_keys.includes(token))\n      throw new Error('密钥无效 | Secret key is invalid')\n    clearLimit( req, res);\n    res.send({ status: 'Success', message: 'Verify successfully', data: null })\n  }\n  catch (error) {\n    res.send({ status: 'Fail', message: error.message, data: null })\n  }\n}\n\nexport const auth = async ( req :Request , res:Response , next:NextFunction ) => {\n  \n\n  const AUTH_SECRET_KEY = process.env.AUTH_SECRET_KEY\n  if (isNotEmptyString(AUTH_SECRET_KEY)) {\n    try {\n      checkLimit( req, res );\n      const Authorization = req.header('Authorization')\n      //const auth_secret_keys = process.env.AUTH_SECRET_KEY.trim().split(',').filter(item => item !== '');\n      const auth_secret_keys = process.env.AUTH_SECRET_KEY? process.env.AUTH_SECRET_KEY.trim().split(',').filter(item => item !== ''):[];\n      if (!Authorization || !auth_secret_keys.includes(Authorization.replace('Bearer ', '').trim()))\n        throw new Error('Error: 无访问权限 | No access rights')\n      \n      clearLimit( req, res);\n      next()\n    }\n    catch (error) {\n      res.send({ status: 'Unauthorized', message: error.message ?? 'Please authenticate.', data: null })\n    }\n  }\n  else {\n    next()\n  }\n}\n\nconst getIp= ( req :Request)=>{\n  if (req.header && req.header('x-forwarded-for')) return req.header('x-forwarded-for');\n  return  req.ip;\n}\nconst checkLimit=  ( req :Request , res:Response )=>{\n  if ( !isNotEmptyString( process.env.AUTH_SECRET_ERROR_COUNT )) {\n    return ;\n  }\n  \n  const bTime = process.env.AUTH_SECRET_ERROR_TIME??10;\n  // 允许的最大错误次数\n  const maxErrorCount =  +process.env.AUTH_SECRET_ERROR_COUNT;\n  // 禁止登录的时间（毫秒）\n  let banTime = (+bTime) * 60*1000; // 10分钟\n  if( banTime<=0 ) banTime= 10*60*1000;\n\n  const ipAddress =getIp(req);\n\n   if (bannedIPs[ipAddress] && Date.now() < bannedIPs[ipAddress]) {\n    const timeLeft = Math.ceil((bannedIPs[ipAddress] - Date.now()) / 1000);\n    console.log(\"myIP \",ipAddress,  ipErrorCount[ipAddress]  );\n    //return res.status(403).send(`IP地址被禁止登录，剩余时间: ${timeLeft}秒`);\n     let ts = timeLeft>60? (timeLeft/60).toFixed(0)+'分钟':  timeLeft+'秒'\n     throw new Error(`Error: ${ipAddress} 验证次数过多，请在${ts}后重试！`)\n  }\n  ipErrorCount[ipAddress] = ipErrorCount[ipAddress]?(  ipErrorCount[ipAddress]+1) : 1;\n  if (ipErrorCount[ipAddress] >= maxErrorCount) {\n      bannedIPs[ipAddress] = Date.now() + banTime;\n  } \n}\nconst clearLimit=  ( req :Request , res:Response )=>{\n  const ipAddress =getIp(req);\n  bannedIPs[ipAddress] = 0;\n  ipErrorCount[ipAddress]= 0;\n}\n\nexport const authV2 = async ( req :Request , res:Response , next:NextFunction ) => {\n  \n  const AUTH_SECRET_KEY = process.env.AUTH_SECRET_KEY\n  //const auth_secret_keys = AUTH_SECRET_KEY.trim().split(',').filter(item => item !== '');\n  const auth_secret_keys = process.env.AUTH_SECRET_KEY? process.env.AUTH_SECRET_KEY.trim().split(',').filter(item => item !== ''):[];\n  if (isNotEmptyString(AUTH_SECRET_KEY)) {\n    try {\n\n      checkLimit( req, res );\n      const Authorization = req.header('X-Ptoken')\n      if ( !Authorization || !auth_secret_keys.includes(Authorization.trim()))\n        throw new Error('Error: 无访问权限 | No access rights')\n      clearLimit( req, res);\n      next()\n       //throw new Error('Error: 无访问权限 | No access rights')\n    }\n    catch (error) { \n      res.status(423);\n      res.send({ code: 'token_check', message: error.message ?? 'Please authenticate.', data: null })\n    }\n  }\n  else {\n    next()\n  }\n}\n\nexport const turnstileCheck= async ( req :Request , res:Response , next:NextFunction ) => {\n\n   const TURNSTILE_SITE = process.env.TURNSTILE_SITE\n    if (!isNotEmptyString(TURNSTILE_SITE)) {\n      next();\n      return ;\n    }\n    //TURNSTILE_NO_CHECK\n    if ( isNotEmptyString( process.env.TURNSTILE_NO_CHECK)) { //前端显示当时后端不check\n       next();\n       return ;\n    }\n    try{\n      if( checkCookie( req ) ) {\n        next();\n        return ;\n      }\n      const Authorization = req.header('X-Vtoken')\n        if ( !Authorization  )  throw new Error('无权限访问,请刷新重试 | No access rights by Turnstile')\n\n      const SECRET_KEY=  process.env.TURNSTILE_SECRET_KEY\n      let formData = new FormData();\n      formData.append('secret', SECRET_KEY);\n      formData.append('response', Authorization);\n      //formData.append('remoteip', ip);\n\n      const result = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n          body: formData,\n          method: 'POST',\n      });\n\n      const outcome:any = await result.json();\n      //console.log('outcome>> ', outcome );\n      if (!outcome.success)   throw new Error('无权限访问,请刷新重试 | No access rights by Turnstile')\n       \n      next();\n    }catch (error) { \n      res.status(422);\n      mlog( 'Turnstile_Error')\n      res.send({ code: 'Turnstile_Error', message: error.message ?? 'Please authenticate.'  })\n    }\n    \n    //throw new Error('Error: 无访问权限 | No access rights by Turnstile')\n   \n\n   \n}\n\nconst getCookie=( time:string )=>{\n  return time+'_'+(md5(time + process.env.TURNSTILE_SECRET_KEY ).substring(0,10) );  \n}\nexport const regCookie= async( req :Request , res:Response , next:NextFunction )=>{\n  try{\n      const Authorization = req.header('X-Vtoken')\n        if ( !Authorization ) throw new Error('Turnstile token 缺失')\n\n      const SECRET_KEY=  process.env.TURNSTILE_SECRET_KEY\n      let formData = new FormData();\n      formData.append('secret', SECRET_KEY);\n      formData.append('response', Authorization);\n      //formData.append('remoteip', ip);\n\n      const result = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n          body: formData,\n          method: 'POST',\n      });\n\n      const outcome:any = await result.json();\n      //console.log('outcome>> ', outcome );\n      if (!outcome.success)   throw new Error('Turnstile 错误,请刷新重试 | No access rights by Turnstile')\n      const now= `${ (Date.now()/1000).toFixed(0)}`;\n      \n      res.status(200);\n      //req.cookies.username;\n      //res.cookie('gptmj',  getCookie( now ), { maxAge: 5*3600*1000, httpOnly: true });\n      res.send({ok:'ok' ,ctoken: getCookie( now ) })\n    }catch (error) { \n      res.status(422);\n       mlog('reg_cookie error ');\n      res.send({ code: 'reg_cookie', message: error.message ?? 'Please authenticate.'  })\n    }\n}\n\nconst checkCookie= ( req :Request ):boolean=>{  \n   //console.log( 'cookies : ',  req.header('X-Ctoken')  );\n   if( ! req.header('X-Ctoken')) return false; \n   const gptmj =  req.header('X-Ctoken') as string;\n   if( gptmj==getCookie(  gptmj.split('_')[0]) ) {\n     mlog('cookie ok ');\n     return true; \n   }\n   return false;\n}\n\n///export { auth }\n"
  },
  {
    "path": "service/src/middleware/limiter.ts",
    "content": "import { rateLimit } from 'express-rate-limit'\nimport { isNotEmptyString } from '../utils/is'\n\nconst MAX_REQUEST_PER_HOUR = process.env.MAX_REQUEST_PER_HOUR\n\nconst maxCount = (isNotEmptyString(MAX_REQUEST_PER_HOUR) && !isNaN(Number(MAX_REQUEST_PER_HOUR)))\n  ? parseInt(MAX_REQUEST_PER_HOUR)\n  : 0 // 0 means unlimited\n\nconst limiter = rateLimit({\n  windowMs: 60 * 60 * 1000, // Maximum number of accesses within an hour\n  max: maxCount,\n  statusCode: 200, // 200 means success，but the message is 'Too many request from this IP in 1 hour'\n  message: async (req, res) => {\n    res.send({ status: 'Fail', message: 'Too many request from this IP in 1 hour', data: null })\n  },\n})\n\nexport { limiter }\n"
  },
  {
    "path": "service/src/myfun.ts",
    "content": "import axios from 'axios';\nimport { Request, Response, NextFunction } from 'express';\nimport { isNotEmptyString } from './utils/is';\nimport FormData  from 'form-data'\nimport  proxy from \"express-http-proxy\"\nimport pkg from '../package.json'\n\n const API_BASE_URL = isNotEmptyString(process.env.OPENAI_API_BASE_URL)\n    ? process.env.OPENAI_API_BASE_URL\n    : 'https://api.openai.com'\n\nexport const lumaProxy=proxy(process.env.LUMA_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.LUMA_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.LUMA_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n});\n\nexport const runwayProxy=proxy(process.env.RUNWAY_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.RUNWAY_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.RUNWAY_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n});\n\n//runwaymlProxy\n\nexport const runwaymlProxy=proxy(process.env.RUNWAYML_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    let url =  req.originalUrl;\n    let server= process.env.RUNWAYML_SERVER??  API_BASE_URL\n    if( server.indexOf('runwayml.com')>-1 ){\n        url= req.originalUrl.replace('/runwayml', '')\n    }\n    return url  //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.RUNWAYML_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.RUNWAYML_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    proxyReqOpts.headers['X-Runway-Version'] = '2024-11-06'; //'X-Runway-Version': \n    return proxyReqOpts;\n  },\n  \n});\n\nexport const klingProxy=proxy(process.env.KLING_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.KLING_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.KLING_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n});\n\nexport const viggleProxy=proxy(process.env.VIGGLE_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.VIGGLE_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.VIGGLE_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\n\nexport const ideoProxy=proxy(process.env.IDEO_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) { \n    if ( process.env.IDEO_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.IDEO_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\nexport const pikaProxy=proxy(process.env.PIKA_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) { \n    if ( process.env.PIKA_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.PIKA_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\nexport const pixverseProxy=proxy(process.env.PIXVERSE_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) { \n    if ( process.env.PIXVERSE_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.PIXVERSE_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\n\n\n\nexport const udioProxy=proxy(process.env.UDIO_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return  req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) { \n    if ( process.env.UDIO_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.UDIO_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\n\n\n//req, res, next\nexport const ideoProxyFileDo=async( req:Request, res:Response, next?:NextFunction)=>{ \n    console.log('req.originalUrl', req.originalUrl );\n    let  API_BASE_URL = isNotEmptyString(process.env.OPENAI_API_BASE_URL)\n    ? process.env.OPENAI_API_BASE_URL\n    : 'https://api.openai.com'\n    API_BASE_URL= process.env.IDEO_SERVER??  API_BASE_URL\n    if(req.file.buffer) {\n      const fileBuffer = req.file.buffer;\n      const formData = new FormData();\n      formData.append('image_file',  fileBuffer,  { filename:  req.file.originalname }  );\n      formData.append('image_request',  req.body.image_request );\n     try{\n       let url = `${API_BASE_URL}${req.originalUrl}` ;\n      let responseBody = await axios.post( url , formData, {\n              headers: {\n              Authorization: 'Bearer '+ (process.env.IDEO_KEY??process.env.OPENAI_API_KEY) ,\n              'Content-Type': 'multipart/form-data',\n              //'Mj-Version': pkg.version\n            }\n        })   ; \n       res.json(responseBody.data );\n      }catch(e){ \n        res.status( 400 ).json( {error: e } );\n      }\n\n    }else{\n      res.status(400).json({'error':'uploader fail'});\n    }\n    \n}\n\nexport const viggleProxyFileDo= async( req:Request, res:Response, next?:NextFunction)=>{\n    // if ( process.env.VIGGLE_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.VIGGLE_KEY;\n    // else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    console.log('req.originalUrl', req.originalUrl );\n    let  API_BASE_URL = isNotEmptyString(process.env.OPENAI_API_BASE_URL)\n    ? process.env.OPENAI_API_BASE_URL\n    : 'https://api.openai.com'\n    API_BASE_URL= process.env.VIGGLE_SERVER??  API_BASE_URL\n    if(req.file.buffer) {\n      const fileBuffer = req.file.buffer;\n      const formData = new FormData();\n      formData.append('file',  fileBuffer,  { filename:  req.file.originalname }  );\n     // formData.append('model',  req.body.model );\n     try{\n       let url = `${API_BASE_URL}${req.originalUrl}` ;\n      let responseBody = await axios.post( url , formData, {\n              headers: {\n              Authorization: 'Bearer '+ (process.env.VIGGLE_KEY??process.env.OPENAI_API_KEY) ,\n              'Content-Type': 'multipart/form-data',\n              //'Mj-Version': pkg.version\n            }\n        })   ; \n       res.json(responseBody.data );\n      }catch(e){ \n        res.status( 400 ).json( {error: e } );\n      }\n\n    }else{\n      res.status(400).json({'error':'uploader fail'});\n    }\n    \n}\n\nexport const sunoProxy=proxy(process.env.SUNO_SERVER??  API_BASE_URL, {\n  https: false, limit: '10mb',\n  proxyReqPathResolver: function (req) {\n    return req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串\n  },\n  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {\n    //mlog(\"sunoapi\")\n    if ( process.env.SUNO_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.SUNO_KEY;\n    else   proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;  \n    proxyReqOpts.headers['Content-Type'] = 'application/json';\n    proxyReqOpts.headers['Mj-Version'] = pkg.version;\n    return proxyReqOpts;\n  },\n  \n})\n\n\n//主要转发接口\nexport const GptImageEdit = async (\n\trequest: Request,\n\tresponse: Response,\n\tnext?: NextFunction\n) => {\n\ttry {\n\t\tdoGptImageEdit(request, response, next);\n\t} catch (e) {\n\t//mlog(\"error\", \"gpt.image.edit /v1/images/edits\", e);\n\t}\n};\n\nconst doGptImageEdit = async (\n\treq: Request,\n\tres: Response,\n\tnext?: NextFunction\n) => {\n\tconst formData = new FormData();\n\t \n\tconst request = req;\n\tconst response = res;\n\n \n\tconst dd = {\n\t\t \n\t};\n\n\tlet url = API_BASE_URL\n\n\tlet myKey =process.env.OPENAI_API_KEY;;\n\t// 添加其他字段\n\n\ttry {\n\t\tfor (let o in req.body) {\n\t\t\ttry {\n\t\t\t\t//mlog(\"body2 \", o);\n\t\t\t\tformData.append(o, req.body[o]);\n\t\t\t} catch (error) {\n\t\t\t\t//mlog(\"body  error\", o);\n\t\t\t}\n\t\t}\n\n\t\tif (req.files) {\n\t\t\t// 处理上传的文件\n\t\t\treq.files.forEach((file) => {\n\t\t\t\t// 判断是单文件还是多文件上传\n\n\t\t\t\t//mlog(\"fileName >>\", file.fieldname);\n\t\t\t\tformData.append(file.fieldname, file.buffer, {\n\t\t\t\t\tfilename: file.originalname,\n\t\t\t\t\tcontentType: file.mimetype,\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\t//验证IP百名单\n\t\t//await checkWhileIp( +mykey.user.uid,request );\n\n\t\tlet rqUrl = url + \"/v1/images/edits\";\n \n\n\t\tlet responseBody = await axios.post(rqUrl, formData, {\n\t\t\theaders: {\n\t\t\t\tAuthorization: 'Bearer '+ myKey,\n\t\t\t\t\"Content-Type\": \"multipart/form-data\",\n\t\t\t},\n\t\t});\n\t\tres.status(responseBody.status).send(responseBody.data);\n\n\t\tconst ss = { ...responseBody.data };\n\t\tif (ss.data && ss.data.length > 0) {\n\t\t\tfor (let i = 0; i < ss.data.length; i++) {\n\t\t\t\tlet o = ss.data[i];\n\t\t\t\tif (o.b64_json) {\n\t\t\t\t\to.b64_json = \"yes\";\n\t\t\t\t}\n\t\t\t\tss.data[i] = o;\n\t\t\t}\n\t\t}\n\t\t//dd.data = ss;\n\t\t//dd.status = responseBody.status;\n\t} catch (error) {\n\t\tif (error.response) {\n\t\t\tlet responseBody = error.response;\n\t\t\t//let data = error.response.data;\n\t\t\tlet dddata = responseBody.data ?? { dtail: \"openai_hk_error\" };\n\t\t\tlet status = responseBody.status ?? 428;\n\t\t\tres.status( status ).send(dddata);\n\t\t} else {\n\t\t\tresponse.writeHead(405);\n\n\t\t\tlet ss = error ? JSON.stringify(error) : \"gate way error...\";\n\t\t\tresponse.end(\n\t\t\t\t`{\"error\":{\"message\":\"${ss}\",\"type\":\"openai_hk_error\",\"code\":\"gate_way_error\"}}`\n\t\t\t);\n\t\t\t\n\t\t}\n\t}\n\n\t//http2mq(\"gpt-image-edit\", dd);\n};"
  },
  {
    "path": "service/src/types.ts",
    "content": "import type { FetchFn } from 'chatgpt'\n\nexport interface RequestProps {\n  prompt: string\n  options?: ChatContext\n  systemMessage: string\n  temperature?: number\n  top_p?: number\n}\n\nexport interface ChatContext {\n  conversationId?: string\n  parentMessageId?: string\n}\n\nexport interface ChatGPTUnofficialProxyAPIOptions {\n  accessToken: string\n  apiReverseProxyUrl?: string\n  model?: string\n  debug?: boolean\n  headers?: Record<string, string>\n  fetch?: FetchFn\n}\n\nexport interface ModelConfig {\n  apiModel?: ApiModel\n  reverseProxy?: string\n  timeoutMs?: number\n  socksProxy?: string\n  httpsProxy?: string\n  usage?: string\n}\n\nexport type ApiModel = 'ChatGPTAPI' | 'ChatGPTUnofficialProxyAPI' | undefined\n"
  },
  {
    "path": "service/src/utils/index.ts",
    "content": "interface SendResponseOptions<T = any> {\n  type: 'Success' | 'Fail'\n  message?: string\n  data?: T\n}\n\nexport function sendResponse<T>(options: SendResponseOptions<T>) {\n  if (options.type === 'Success') {\n    return Promise.resolve({\n      message: options.message ?? null,\n      data: options.data ?? null,\n      status: options.type,\n    })\n  }\n\n  // eslint-disable-next-line prefer-promise-reject-errors\n  return Promise.reject({\n    message: options.message ?? 'Failed',\n    data: options.data ?? null,\n    status: options.type,\n  })\n}\n"
  },
  {
    "path": "service/src/utils/is.ts",
    "content": "export function isNumber<T extends number>(value: T | unknown): value is number {\n  return Object.prototype.toString.call(value) === '[object Number]'\n}\n\nexport function isString<T extends string>(value: T | unknown): value is string {\n  return Object.prototype.toString.call(value) === '[object String]'\n}\n\nexport function isNotEmptyString(value: any): boolean {\n  return typeof value === 'string' && value.length > 0\n}\n\nexport function isBoolean<T extends boolean>(value: T | unknown): value is boolean {\n  return Object.prototype.toString.call(value) === '[object Boolean]'\n}\n\nexport function isFunction<T extends (...args: any[]) => any | void | never>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Function]'\n}\n\nexport const formattedDate=()=>{\n  const currentDate = new Date(); \n  const year = currentDate.getFullYear();\n  const month = (currentDate.getMonth() + 1).toString().padStart(2, '0');\n  const day = currentDate.getDate().toString().padStart(2, '0'); \n  return  `${year}${month}${day}`;\n   \n}"
  },
  {
    "path": "service/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2020\",\n    \"lib\": [\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"baseUrl\": \".\",\n    \"outDir\": \"build\",\n    \"noEmit\": true\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"build\"\n  ],\n  \"include\": [\n    \"**/*.ts\"\n  ]\n}\n"
  },
  {
    "path": "service/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  entry: ['src/index.ts'],\n  outDir: 'build',\n  target: 'es2020',\n  format: ['esm'],\n  splitting: false,\n  sourcemap: true,\n  minify: false,\n  shims: true,\n  dts: false,\n})\n"
  },
  {
    "path": "src/App.vue",
    "content": "<script setup lang=\"ts\">\nimport { NConfigProvider } from 'naive-ui'\nimport { NaiveProvider } from '@/components/common'\nimport { useTheme } from '@/hooks/useTheme'\nimport { useLanguage } from '@/hooks/useLanguage'\nimport aiOther from \"@/views/mj/aiOther.vue\" \nconst { theme, themeOverrides } = useTheme()\nconst { language } = useLanguage()\n</script>\n\n<template>\n  <NConfigProvider\n    class=\"h-full\"\n    :theme=\"theme\"\n    :theme-overrides=\"themeOverrides\"\n    :locale=\"language\"\n  >\n    <NaiveProvider>\n      <RouterView />\n    </NaiveProvider>\n  </NConfigProvider>\n  <!-- 处理一下chat 与draw 共有的事情 -->\n  <aiOther/>\n</template>\n"
  },
  {
    "path": "src/api/Recognition.ts",
    "content": "import { mlog } from \"./mjapi\";\n\nexport interface recType{\n    timeOut:number \n    asrLanguage?:string\n    listener?: (result: string) => void\n    onEnd?: () => void\n    onStart?: () => void\n}\nexport class Recognition {\n  private recognition: any;\n\n  private listener?: (result: string) => void;\n\n  private isStop = false;\n\n  //选项\n  private recOpt:recType={timeOut:2000} \n  \n  //\n  private handleTime: any ;\n\n  private hTime:Date | undefined;\n  //语言\n  private asrLanguage = 'cmn-Hans-CN'\n  //\n  private onEnd?: () => void;\n  private onStart?: () => void;\n  public setListener(fn: (result: string) => void) {\n    this.listener = fn;\n    return this;\n  }\n  public setOnEnd( fn: ( ) => void){\n    this.onEnd = fn;\n    return this;\n  }\n  public setOpt( opt:recType ){\n    this.recOpt= opt;\n\n    if(opt.listener)  this.setListener(opt.listener)\n    if(opt.onEnd)  this.setListener(opt.onEnd)\n    if(opt.asrLanguage)  this.setLang(opt.asrLanguage);\n    if(opt.onStart) this.onStart= opt.onStart;\n\n    return this;\n  }\n  \n  public setLang( lang:string ){\n    this.asrLanguage = lang;\n    return this;\n  }\n\n  public start() {\n    this.isStop = false;\n    // @ts-ignore\n    if (!window.SpeechRecognition && !window.webkitSpeechRecognition) return;\n    if (!this.recognition) {\n      // @ts-ignore\n      const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();\n      this.recognition = recognition;\n    }\n    const recognition = this.recognition;\n\n    // 返回实时识别结果\n    recognition.interimResults = true;\n    // 设置语言\n    const lang = this.asrLanguage;\n    recognition.lang = lang;\n\n    // 设置是否连续识别\n    recognition.continuous = true;\n\n    this.hTime = new Date();\n    this.handleTime = setInterval( ()=>this.check( this ), this.recOpt.timeOut ) \n\n    // 当识别到语音时触发该事件\n    recognition.addEventListener('result', (event: any) => { \n\n      let transcript = '';\n      for (let index = 0; index < event.results.length; index++) {\n        const item = event.results[index];\n        // 中文添加逗号\n        if (transcript && lang?.includes('Han')) transcript += '，';\n\n        transcript += (item as unknown as SpeechRecognitionAlternative[])[0]?.transcript;\n      }\n      if (!transcript) return; \n      this.hTime = new Date();\n      this.listener?.(transcript);\n    });\n\n    // 当识别结束时触发该事件\n    recognition.addEventListener('end', () => {\n      mlog('recognition onEnd',  this.isStop );\n      if (this.isStop) {\n        this.onEnd?.();\n        this.handleTime && clearInterval( this.handleTime )\n        return;\n      }\n      // 继续监听\n      recognition.start();\n    });\n\n    // 启动语音识别\n    recognition.start();\n    this.onStart?.();\n\n    return this;\n  }\n\n  public stop() {\n    this.isStop = true;\n    this.recognition?.stop();\n    return this;\n  }\n\n  private check( that:Recognition ){\n     if( !that.hTime ) {\n         mlog('mcheck 未定义');\n        return ;\n     }  \n     const nTime =  new Date();\n     \n     const dt =  nTime.getTime()- that.hTime.getTime();\n     mlog('mcheck', dt,that.recOpt.timeOut );\n     if( dt> that.recOpt.timeOut ){\n        that.stop();\n     }\n     return this;\n  }\n}\n\n\nexport const supportLanguages: Record<string, string> = {\n  'cmn-Hans-CN': '普通话 (中国大陆)',\n  'cmn-Hans-HK': '普通话 (香港)',\n  'yue-Hant-HK': '粵語 (香港)',\n  'en-US': 'English(United States)',\n  'en-GB': 'English(United Kingdom)',\n  'en-IN': 'English(India)',\n  'es-ES': 'Español',\n  'fr-FR': 'Français',\n  'de-DE': 'Deutsch',\n  'it-IT': 'Italiano',\n  'ja-JP': '日本語',\n  'ko-KR': '한국어',\n  'ar-SA': 'العربية',\n  'pt-BR': 'Português',\n  'ru-RU': 'Русский',\n  'nl-NL': 'Nederlands',\n  'tr-TR': 'Türkçe',\n  'sv-SE': 'Svenska',\n  'hi-IN': 'हिन्दी',\n  'el-GR': 'Ελληνικά',\n  'he-IL': 'עברית',\n  'id-ID': 'Bahasa Indonesia',\n  'pl-PL': 'Polski',\n  'th-TH': 'ไทย',\n  'cs-CZ': 'Čeština',\n  'hu-HU': 'Magyar',\n  'da-DK': 'Dansk',\n  'fi-FI': 'Suomi',\n  'no-NO': 'Norsk',\n  'sk-SK': 'Slovenčina',\n  'uk-UA': 'Українська',\n  'vi-VN': 'Tiếng Việt',\n};\n\nfunction sleep(time: number) {\n  return new Promise((resolve) => setTimeout(resolve, time));\n}\n\n//浏览器文字播放\nexport async function speakText(content: string, callback: (playing: boolean) => void) {\n  if (!window.speechSynthesis) return;\n  if (speechSynthesis.speaking) {\n    speechSynthesis.cancel();\n    callback(false);\n  }\n\n  await sleep(300);\n\n  const msg = new SpeechSynthesisUtterance(content);\n  msg.lang = 'zh';\n  msg.rate = 1;\n  msg.addEventListener('end', () => {\n    callback(false);\n  });\n  msg.addEventListener('error', () => {\n    callback(false);\n  });\n  callback(true);\n  speechSynthesis.speak(msg);\n}"
  },
  {
    "path": "src/api/chat.ts",
    "content": "//import { reactive } from 'vue'\n\nimport { gptConfigStore, gptConfigType } from \"@/store\";\nimport { ss } from '@/utils/storage'\nimport { mlog } from \"./mjapi\";\nimport { debounce } from \"@/utils/functions/debounce\";\n\n//let time_limit= 0\n\nexport class chatSetting{\n  private uuid: number;\n  private localKey='chat-setting';\n  private time_limit=0;\n  private mObj:gptConfigType[]=[];\n  \n  //private gptConfig: gptConfigType\n    // 构造函数\n  constructor(uuid: number) {\n    this.uuid = uuid;\n    //this.gptConfig = gptConfigStore.myData;\n    //this.init();\n  }\n \n  public setUuid(uuid: number){\n    this.uuid = uuid;\n    return this\n  }\n  public getGptConfig():gptConfigType {\n    mlog(\"toMyuid16\",\"getGptConfig\", this.uuid )\n     const index = this.findIndex();\n     if( index<=-1) return gptConfigStore.myData;\n     const arr = this.getObjs();\n     const rz=  arr[index];\n     //gptConfigStore.setMyData( rz );\n     gptConfigStore.myData.model= rz.model;\n     return rz;\n  }\n  public getObjsDebounce=debounce(  this.getObjs ,600);\n  //卡死 可疑点\n  public getObjs():gptConfigType[]{\n     const now=  Math.floor(Date.now() / 1)\n     const dt= now- this.time_limit;\n     mlog(\"toMyuid15\",\"getObjs\", this.uuid , dt)\n     if(dt<500  ){ //防止卡死\n      return this.mObj ;\n     }\n     this.time_limit=now ;\n   \n     const obj = ss.get( this.localKey ) as  undefined| gptConfigType[];\n   \n    this.mObj= obj? obj:[]\n    return this.mObj;\n  }\n  public findIndex(){ \n    mlog(\"toMyuid8\",\"findIndex\")\n    return  this.getObjs().findIndex(v=>v.uuid && v.uuid==this.uuid  )\n  }\n  public save( obj : Partial<gptConfigType>){\n    mlog(\"toMyuid8\",\"save\")\n    let  sobj ={ ...gptConfigStore.myData , ...obj };\n    sobj.uuid= this.uuid;\n    const index = this.findIndex();\n    let arr = this.getObjs();\n    if( index>-1  )arr[index]= sobj;\n    else arr.push( sobj ); \n    ss.set(this.localKey, arr );\n    return this ;\n  }\n\n   \n}"
  },
  {
    "path": "src/api/dtoStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\nexport interface DtoItem{\n    url?:string\n    status:string\n    last_feed:number //最后更新时间\n    mid:string\n    id:string //这个是唯一ID\n    type:string //image video images\n    data?:any //这个是返回全部数据\n    plat:string\n    title:string,\n    model?:string\n}\n\n\n\nexport class DtoStore{ \n  private localKey='dto-store';\n  public save(obj:DtoItem ){\n    if(!obj.id) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id);\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id == id )\n  }\n\n  public getObjs():DtoItem[]{\n     const obj = ss.get( this.localKey ) as  undefined| DtoItem[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):DtoItem|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( id:string ){\n    //if(!obj.data.task_id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/ideo.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sleep } from \"./suno\";\n\n\nexport interface IdeoImageData {\n  is_image_safe: boolean;\n  prompt: string;\n  resolution: string;\n  seed: number;\n  url: string;\n}\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.IDEO_KEY){\n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.IDEO_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= '';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.IDEO_SERVER){\n        \n        return `${ gptServerStore.myData.IDEO_SERVER}${pro_prefix}/ideogram${url}`;\n    }\n    return `${pro_prefix}/ideogram${url}`;\n}\n \n\nexport const ideoSubmit= async( data:any ):Promise<IdeoImageData[]>=>{\n    let rz:IdeoImageData[]\n    let rzdata:any={image_request:data.image_request}\n    if(data.file) { \n        //mlog('文件上传', data.file  ); \n        const formData = new FormData(); \n        formData.append('image_file',   data.file )\n        formData.append('image_request',  JSON.stringify(data.image_request) )\n    \n        let d:any = await ideoFetch( '/remix', formData,{upFile:true})\n        //mlog(' 文件上传 back', d ); \n        rz= d.data as IdeoImageData[]\n    }else{\n        let  d:any = await ideoFetch('/generate ' ,rzdata ) \n        //mlog('back', d ); \n        rz= d.data as IdeoImageData[]\n    }\n    return rz;\n\n}\nexport const ideoFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('ideoFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\n// export  async function FeedViggleTask(id:string){  \n//     const ss = new viggleStore()\n//     const hk= new lumaHkStore();\n//     const hkObj= hk.getOneById(id)\n//     for(let i=0; i<500;i++){\n//         let url= '/video-task/by-ids';\n//         if(hkObj && hkObj.isHK ) url= '/pro/video-task/by-ids';\n//         const d= await viggleFetch(url,{ids:[id]})\n//         mlog('FeedViggleTask', d )\n       \n//         if(d.data && d.data.length>0){\n//             let task= d.data[0] as ViggleTask;\n//             task.last_feed=new Date().getTime()\n//             ss.save( task )\n//             homeStore.setMyData({act:'FeedViggleTask'})\n//             if ( d.data[0].status==0) return\n//         }\n//         await sleep(2000)\n//     }\n\n// }"
  },
  {
    "path": "src/api/index.ts",
    "content": "import type { AxiosProgressEvent, GenericAbortSignal } from 'axios'\nimport { post } from '@/utils/request'\nimport { homeStore, useAuthStore, useSettingStore } from '@/store'\n\n\nexport function fetchChatAPI<T = any>(\n  prompt: string,\n  options?: { conversationId?: string; parentMessageId?: string },\n  signal?: GenericAbortSignal,\n) {\n  return post<T>({\n    url: '/chat',\n    data: { prompt, options },\n    signal,\n  })\n}\n\nexport function fetchChatConfig<T = any>() {\n  return post<T>({\n    url: '/config',\n  })\n}\n\nexport function fetchChatAPIProcess<T = any>(\n  params: {\n    prompt: string\n    options?: { conversationId?: string; parentMessageId?: string }\n    signal?: GenericAbortSignal\n    onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void },\n) {\n  const settingStore = useSettingStore()\n  const authStore = useAuthStore()\n\n  let data: Record<string, any> = {\n    prompt: params.prompt,\n    options: params.options,\n  }\n\n  if (authStore.isChatGPTAPI) {\n    data = {\n      ...data,\n      systemMessage: settingStore.systemMessage,\n      temperature: settingStore.temperature,\n      top_p: settingStore.top_p,\n    }\n  }\n\n  return post<T>({\n    url: '/chat-process',\n    data,\n    signal: params.signal,\n    onDownloadProgress: params.onDownloadProgress,\n  })\n}\n\nexport function fetchSession<T>() {\n  if (homeStore.myData.isClient)\n  return {\"status\":\"Success\",\"message\":\"\",\"data\":{\"isHideServer\":false,\"isUpload\":false,\"auth\":false,\"model\":\"ChatGPTAPI\",\"amodel\":\"gpt-4\",\"isApiGallery\":false,\"cmodels\":\"\",\"baiduId\":\"9d5fa7fc2f5fd585aa8fd3010d19be1e\",\"googleId\":\"\",\"notify\":\"\",\"disableGpt4\":\"\",\"isWsrv\":\"\",\"uploadImgSize\":\"1\",\"gptUrl\":\"\",\"theme\":\"dark\",\"isCloseMdPreview\":false}}\n  \n  return post<T>({\n    url: '/session',\n  })\n}\n\nexport function fetchVerify<T>(token: string) {\n  return post<T>({\n    url: '/verify',\n    data: { token },\n  })\n}\n\nexport * from \"./mjapi\"\nexport * from \"./mjsave\"\nexport * from \"./openapi\"\nexport * from \"./units\"\nexport * from \"./mic\"\nexport * from \"./chat\"\nexport * from \"./sse/fetchsse\"\nexport * from \"./Recognition\"\nexport * from \"./luma\"\nexport * from \"./ideo\"\nexport * from \"./realtime\"\n\n"
  },
  {
    "path": "src/api/kling.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { KlingTask, klingStore } from \"./klingStore\";\nimport { sleep } from \"./suno\";\n\n\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.KLING_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.KLING_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= '';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.KLING_SERVER  ){\n      \n        return `${ gptServerStore.myData.KLING_SERVER}${pro_prefix}/kling${url}`;\n    }\n    return `${pro_prefix}/kling${url}`;\n}\n\n\nexport const klingFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('runwayFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const klingFeed= async(id:string,cat:string,prompt:string)=>{\n    const sunoS = new klingStore();\n    let url= '/v1/images/generations/' //images或videos\n    if (cat=='text2video'){\n        url='/v1/videos/text2video/';\n    }\n    if(cat=='image2video'){\n        url='/v1/videos/image2video/';\n    }\n    url= url+id;\n    for(let i=0; i<200;i++){\n        try{\n            \n            let a= await klingFetch( url )\n            let task= a  as KlingTask;\n            task.last_feed=new Date().getTime()\n            task.cat= cat\n            if(prompt){\n              task.prompt= prompt\n            }\n            //ss.save( task )\n            //mlog(\"a\",a  )\n            sunoS.save( task )\n            homeStore.setMyData({act:'KlingFeed'});\n            if(  task.data.task_status =='failed' || 'succeed'== task.data.task_status ){\n                break;\n            }\n        }catch(e){\n            break;\n        }\n        await sleep(5200)\n    }\n}\n"
  },
  {
    "path": "src/api/klingStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n \n\nexport interface KlingTask {\n    cat?: string //类别\n    prompt?: string //提示词\n    last_feed?: number //最后更新时间\n    code: number;\n    message: string;\n    request_id: string;\n    data: {\n        task_id: string;\n        task_status: string;\n        task_status_msg: string;\n        created_at: number;\n        updated_at: number;\n        task_result?: {\n        images: Array<{\n            index: number;\n            url: string;\n        }> | null;\n        videos: Array<{\n            id: string;\n            url: string;\n            duration: string;\n        }> | null;\n        };\n    };\n}\n\nexport class klingStore{\n  //private id: string;\n  private localKey='kling-store';\n  public save(obj:KlingTask ){\n    if(!obj.data.task_id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.data.task_id==obj.data.task_id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.data.task_id == id )\n  }\n\n  public getObjs():KlingTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| KlingTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):KlingTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( id:string ){\n    //if(!obj.data.task_id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.data.task_id==id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/luma.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { LumaMedia, lumaHkStore, lumaStore } from \"./lumaStore\";\nimport { sleep } from \"./suno\";\n\n\n\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.LUMA_KEY){\n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.LUMA_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nconst getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.LUMA_SERVER){\n        if(gptServerStore.myData.LUMA_SERVER.indexOf('/pro')>0){\n            return `${ gptServerStore.myData.LUMA_SERVER}/luma${url}`;\n        }\n        return `${ gptServerStore.myData.LUMA_SERVER}${pro_prefix}/luma${url}`;\n    }\n    return `${pro_prefix}/luma${url}`;\n}\n\nexport const lumaFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('sunoFetch', url  );\n    let headers= {'Content-Type':'application/json'}\n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const FeedLumaTask= async(id:string)=>{\n    if(id=='')return '';\n    const lumaS = new lumaStore();\n    const hk= new lumaHkStore();\n    const hkObj= hk.getOneById(id)\n    for(let i=0; i<120;i++){\n        let url= '/generations/'+id;\n        if(hkObj && hkObj.isHK ) url= '/pro/generations/'+id;\n\n        let d:LumaMedia = await lumaFetch( url );\n        if(d.id){\n            d.last_feed = new Date().getTime()\n            lumaS.save(d);\n            homeStore.setMyData({act:'FeedLumaTask'});\n            if( d.state=='completed' && d.video && d.video?.download_url  ){ //有的时候  completed 但是 没链接\n                break;\n            }\n        }\n        await sleep(5*1000);\n    }\n}\n\nexport const isHkServer=()=>{\n    const url= gptServerStore.myData.LUMA_SERVER.toLocaleLowerCase();\n    if(url!=''){\n     return (url.indexOf('hk')>-1 &&  url.indexOf('pro')==-1 ) ;\n    }\n    return (homeStore.myData.session && homeStore.myData.session.isHk) ;\n}"
  },
  {
    "path": "src/api/lumaStore.ts",
    "content": "import { ss } from '@/utils/storage'\n \n type LumaVideo = {\n    url: string;\n    width: number;\n    height: number;\n    thumbnail: string | null;\n    download_url?: string;\n};\n\n \nexport type LumaMedia = {\n    id: string;\n    prompt: string;\n    state: string;\n    created_at?: string;\n    video?: LumaVideo;\n    liked?: boolean | null;\n    estimate_wait_seconds?: number | null;\n    last_feed?:number\n};\nexport class lumaStore{\n  //private id: string;\n  private localKey='luma-store';\n  public save(obj:LumaMedia ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():LumaMedia[]{\n     const obj = ss.get( this.localKey ) as  undefined| LumaMedia[];\n     if(!obj) return [];\n     return obj;\n  }\n  public delete( obj:LumaMedia ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}\n\nexport type LumaHk={\n  id: string\n  isHK:boolean\n}\n\nexport class lumaHkStore{\n  //private id: string;\n  private localKey='luma-HK';\n  public save(obj:LumaHk ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():LumaHk[]{\n     const obj = ss.get( this.localKey ) as  undefined| LumaHk[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):LumaHk|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n}"
  },
  {
    "path": "src/api/mic.ts",
    "content": "\n\nexport const tts=(index:Number)=>{\n\n}\n\n\n \n"
  },
  {
    "path": "src/api/mjapi.ts",
    "content": "\n //import { useChat } from '@/views/chat/hooks/useChat'\n\nimport { gptConfigStore, gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { copyToClip } from \"@/utils/copy\";\nimport { isNumber } from \"@/utils/is\";\nimport { localGet, localSaveAny } from \"./mjsave\";\nimport { t } from \"@/locales\";\n//import { useMessage } from \"naive-ui\";\nexport interface gptsType{\n    gid:string\n    name:string\n    logo:string\n    info:string\n    use_cnt?:string\n    bad?:string|number\n}\n //const { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } = useChat()\nexport function upImg(file:any   ):Promise<any>\n{\n    const maxSize= homeStore.myData.session.uploadImgSize? (+homeStore.myData.session.uploadImgSize):5\n    return new Promise((h,r)=>{\n        const filename = file.name;\n        if(file.size>(1024*1024 * maxSize)){\n            r(t('mjchat.no1m',{m:maxSize}))\n            return ;\n        }\n        if (! (filename.endsWith('.jpg') ||\n            filename.endsWith('.gif') ||\n            filename.endsWith('.png') ||\n            filename.endsWith('.jpeg') )) {\n            r(t('mjchat.imgExt') );\n            return ;\n        }\n        const reader = new FileReader();\n        // 当读取操作完成时触发该事件\n        //reader.onload = (e:any)=> st.value.fileBase64 = e.target.result;\n        reader.onload = (e:any)=>  h( e.target.result);\n        reader.readAsDataURL(file);\n    })\n    \n}\n\nexport const clearImageBase64= ( str:string)=>{\n    let arr= str.split('base64,',2 )\n    return arr[1]??arr[0];\n}\n\nexport const file2blob= (selectedFile: any  )=>{\n    return new Promise<{blob:Blob,filename:string}>((resolve, reject) => {\n        const reader = new FileReader();\n        mlog('selectedFile', selectedFile )\n        reader.onload = function (event:any ) {\n            // 将文件内容转换为 Blob\n            const blob = new Blob([event.target.result], { type: selectedFile.type });\n\n            // 在这里可以使用生成的 Blob 对象\n            //console.log(blob);\n            resolve({blob,filename:selectedFile.name });\n        };\n        reader.onerror = (e)=> reject(e);\n\n        // 开始读取文件\n        reader.readAsArrayBuffer(selectedFile);\n        \n    })\n     \n}\n\nexport const blob2file= ( blob:Blob,fileName:string )=>{\n    const file = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });\n    return file;\n}\n\nexport const  isFileMp3= (filename:string )=>{\n    //let arr='.mp3, .mp4, .mpeg, .mpga, .m4a, .wav, .webm'.split(/[, ]+/ig);\n    // 修复： https://github.com/Dooy/chatgpt-web-midjourney-proxy/issues/666\n    let arr='.mp3, .mpeg, .mpga, .m4a, .wav, .webm'.split(/[, ]+/ig);\n    mlog('fileIsMp3', arr );\n    filename= filename.toLocaleLowerCase();\n    for(let ext of arr ){\n        if(filename.endsWith(ext)) return true;\n    }\n    return false;\n}\n\nfunction containsChinese(str:string ) {\n  return false; //11.18 都不需要翻译\n//   var reg = /[\\u4e00-\\u9fa5]/g; // 匹配中文的正则表达式\n//   return reg.test(str);\n}\n\nexport  async function train( text:string){\n\n    return new Promise<string>((resolve, reject) => {\n\n\n        if( text.trim()  =='') {\n           reject( t('mjchat.placeInput'));\n            return ;\n        }\n\n        \n        if( !containsChinese(text.trim()) ){\n            resolve( text.trim() );\n            return ;\n        }\n        \n        // myTranslate( text.trim())\n        //     .then((d:any)=>  resolve( d.content.replace(/[?.!]+$/, \"\")))\n        //     .catch(( )=>   reject('翻译发生错误'))\n        resolve( text.trim() )\n    }) \n}\n\nexport const mlog = (msg: string, ...args: unknown[]) => {\n    //localStorage.setItem('debug',1 )\n    const logStyles = [\n    // 'padding: 4px 8px',\n    // 'color: #fff',\n    // 'border-radius: 3px',\n    'color:',\n  ].join(';')\n    const debug= localStorage.getItem('debug')\n    if( !debug  ) return ;\n    const style = `${logStyles}${msg.includes('error') ? 'red' : '#dd9089'}`\n    console.log(`%c[mjgpt]`,  style, msg , ...args)\n}\n\nexport const myTrim = (str: string, delimiter: string)=>{\n    // 构建正则表达式，使用动态的定界符\n    const regex = new RegExp(`^${delimiter}+|${delimiter}+$`, 'g');\n    \n    // 使用正则表达式去除字符串两端的定界符\n    return str.replace(regex, '');\n}\n\nfunction getHeaderApiSecret(){\n    if(!gptServerStore.myData.MJ_API_SECRET){\n        const authStore = useAuthStore()\n        if( authStore.token ) return { 'x-ptoken':  authStore.token };\n        return {}\n    }\n    return {\n        'mj-api-secret':  gptServerStore.myData.MJ_API_SECRET\n    }\n}\n\nconst getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    if(gptServerStore.myData.MJ_SERVER){\n        return `${ gptServerStore.myData.MJ_SERVER}${url}`;\n    }\n    return `/mjapi${url}`;\n}\n\nexport const mjFetch=(url:string,data?:any)=>{\n    mlog('mjFetch2024', url  );\n    let header = {'Content-Type':'application/json'};\n    header= {...header,...getHeaderApiSecret() }\n\n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'}; \n        opt.headers=header;\n        if(data) {\n            opt.body= JSON.stringify(data) ;\n             opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then(d2=>d2.json().then(d=> {\n                if(d2.ok) resolve(d);\n                else{\n                    reject({error: d.error??  (d??'Network response was not ok!'),code:'response_fail',url:getUrl(url), status:d2.status })\n                }\n            }).catch(e=>reject({error:e? e.toString() :'json_error',code:'json_error',url:getUrl(url) , status:d2.status  }))\n        ).catch(e=>reject({error:e? e.toString() :'fetch fail',data ,code:'fetch_fail',url:getUrl(url)  }))\n    })\n     \n}\n\nexport const myFetch=(url:string,data?:any)=>{\n    //mlog('myFetch', url  );\n    let header = {'Content-Type':'application/json'};\n    //header= {...header  }\n\n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'}; \n        opt.headers=header;\n        if(data) {\n            opt.body= JSON.stringify(data) ;\n             opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then(d=>d.json().then(d=> resolve(d))\n        .catch(e=>reject(e)))\n        .catch(e=>reject(e))\n    })\n     \n}\nexport const my2Fetch=(url:string,data?:any)=>{\n    mlog('mjFetch', url  );\n    let header = {'Content-Type':'application/json'};\n    //header= {...header  }\n\n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'}; \n        opt.headers=header;\n        if(data) {\n            opt.body= JSON.stringify(data) ;\n             opt.method='POST';\n        }\n        fetch((url),  opt )\n        .then(d=>d.json().then(d=> resolve(d))\n        .catch(e=>reject(e)))\n        .catch(e=>reject(e))\n    })\n     \n}\n\n\nexport const flechTask= ( chat:Chat.Chat)=>{\n    let cnt=0;\n    const check= async ()=>{\n        cnt++;\n        if(!chat.mjID){\n            chat.text +=\"\\n获取失败\" ;\n            chat.loading=false;\n            homeStore.setMyData({act:'updateTask', actData:chat });\n            return ;\n        }\n        const ts=  await mjFetch(`/mj/task/${chat.mjID}/fetch`);\n        chat.opt= ts;\n        chat.loading=   (cnt>=99)?false:true; \n        //chat.progress=ts.progress;\n    \n        if(ts.progress && ts.progress== \"100%\") chat.loading=false;\n\n        homeStore.setMyData({act:'updateChat', actData:chat });\n        //\"NOT_START\" //[\"SUBMITTED\",\"IN_PROGRESS\"].indexOf(ts.status)>-1\n        if( [\"FAILURE\",\"SUCCESS\"].indexOf(ts.status)==-1 && cnt<100 ){\n           \n            setTimeout(() =>   check( ) , 5000 )\n        } \n        mlog('task', ts.progress,ts, chat.uuid,chat.index  );\n    }\n    check();\n}\nexport const subTask= async (data:any, chat:Chat.Chat )=>{\n   let d:any;\n   mlog('subTask', data )\n   try{\n    //return ;\n    if(  data.action &&data.action=='change' ){ //执行变化\n        d=  await mjFetch('/mj/submit/change' , data.data  );\n    }else if( data.action &&data.action==\"CustomZoom\") { //自定义变焦\n            d =  await mjFetch('/mj/submit/action' , data.data  );\n            if(d.result){\n                let bdata= data.maskData;\n                bdata.taskId= d.result;\n                d=  await mjFetch('/mj/submit/modal' , bdata );\n            }\n    }else if( data.action &&data.action=='mask') { //局部重绘\n        d =  await mjFetch('/mj/submit/action' , data.data  );\n        if(d.result){\n            let bdata= data.maskData;\n            bdata.taskId= d.result;\n            d=  await mjFetch('/mj/submit/modal' , bdata );\n        }\n    }else if( data.action &&data.action=='blend') { //blend\n        d=  await mjFetch('/mj/submit/blend' ,  data.data );\n    }else if( data.action &&data.action=='shorten') { //shorten \n        d=  await mjFetch('/mj/submit/shorten' ,  data.data );\n        //  mlog('mjFetch shorten' , data );\n    }else if( data.action &&data.action=='face') { //换脸 \n        d=  await mjFetch('/mj/insight-face/swap' , data.data  ); \n        //mlog('换年服务', data.data );\n        //return; \n    }else if( data.action && data.action=='mj.edit.image') { //图编辑\n       d=  await mjFetch('/mj/submit/edits' , data.data  ); \n    }else if( data.action &&data.action=='mj.edit.video') { //图生视频\n        d=  await mjFetch('/mj/submit/video' , data.data  ); \n    }else if( data.action &&data.action=='img2txt') { //图生文 \n        d=  await mjFetch('/mj/submit/describe' , data.data  ); \n    }else if( data.action &&data.action=='changeV2') { //执行动作！\n        d=  await mjFetch('/mj/submit/action' , data.data  );\n        if  (d.description&&  d.description.indexOf('confirm')>-1){\n            d=  await mjFetch('/mj/submit/modal' , { taskId:d.result, prompt: d.properties.finalPrompt??''} );\n        }\n    }else {\n        let toData =  {\n            \"base64Array\":data.fileBase64??[],\n            \"notifyHook\": \"\",\n            \"prompt\": data.drawText,\n            \"state\": \"\",\n            botType:'MID_JOURNEY'\n            };\n            if(data.bot && data.bot=='NIJI_JOURNEY'){\n                toData.botType= data.bot;\n            }\n            d=  await mjFetch('/mj/submit/imagine' ,toData );\n            mlog('submit',d );\n            //return ;\n    }\n    //mlog(\"subTask rz >> \", d )\n    if(d.code==21  ){\n        d=  await mjFetch('/mj/submit/modal' , { taskId:d.result} );\n    }\n        \n     backOpt(d, chat);\n   }catch(e:any ){\n     mlog('mjFetchError', e )\n     chat.text='失败！'+\"\\n```json\\n\"+JSON.stringify(e, null, 2)+\"\\n```\\n\";\n     chat.loading=false;\n     homeStore.setMyData({act:'updateChat', actData:chat });\n   }\n   \n    \n    //if( chat.uuid &&  chat.index) updateChat(chat.uuid,chat.index, chat)\n}\nconst backOpt= (d:any, chat:Chat.Chat )=>{\n     if(d.code==1 || d.code==22){\n        chat.text= d.code==22? d.description :'提交成功！';\n        chat.mjID= d.result;\n        flechTask( chat )\n        chat.loading=true;\n        homeStore.setMyData({act:'updateChat', actData:chat });\n        //chat.m= d.result;\n    }else{\n        chat.text='失败！'+\"\\n```json\\n\"+JSON.stringify(d, null, 2)+\"\\n```\\n\";\n        chat.loading=false;\n        homeStore.setMyData({act:'updateChat', actData:chat });\n    }\n}\n\nexport const mjSeed= async ( mjid:string )=>{\n     const ts=  await mjFetch(`/mj/task/${mjid}/image-seed`);\n     return ts;\n}\n\n\n\nexport const getSeed = async (cchat:Chat.Chat,message:any )=>{\n   // const message = useMessage();\n  // let cchat = props.chat;\n  if(!cchat.mjID ) return ;\n  let seed=0 ;\n  if(cchat.opt?.seed) seed =cchat.opt?.seed;\n  else{\n   try{\n        message.info('获取中...');\n      const res:any  = await mjSeed( cchat.mjID);\n      seed= res.result;\n      if(seed>0 ) {\n       \n        if ( cchat.opt ){\n          cchat.opt.seed = seed;\n\n           homeStore.setMyData({act:'updateChat', actData:cchat });\n        }\n        message.success('获取成功');\n      }\n      \n   } catch(e){\n      message.error('获取失败')\n   }\n  }\n  mlog('getSeed',seed);\n  if(seed>0 ) {\n    await copyToClip(`${seed}`);\n    message.success('复制seed成功');\n  }\n  \n}\n\nexport const getLastVersion=  async ()=>{\n    const url='https://api.github.com/repos/Dooy/chatgpt-web-midjourney-proxy/tags?per_page=1';\n    const a= await myFetch(url);\n    mlog('lastVersion', a ); \n    return a;\n    \n}\n\nexport const canVisionModel= (model:string)=>{\n    mlog('canVisionModel ',model );\n    //['gpt-4-all','gpt-4-v'].indexOf(model)==-1 && model.indexOf('gpt-4-gizmo')==-1\n    if( ['gpt-4-all','gpt-4-v','gpt-4v','gpt-3.5-net','gpt-4o-all'].indexOf(model)>-1 ) return true;\n    if(model.indexOf('-all')>-1 )return true; //各种all模型\n    if(model.indexOf('gpt-4-gizmo')>-1 )return true;  // || model.indexOf('claude-3-opus')>-1cha\n     \n    return false;\n}\nexport const isCanBase64Model=(model:string)=>{\n\n    //默认是支持\n    if( model.includes('gpt-3') || model=='gpt-4'){\n        return false\n    }\n    return true\n    //gpt-4o\n    //customVisionModel\n    let arr=['gpt-4o','gemini','1.5','sonnet','opus','deepseek' ];\n    for( let m of arr){\n        if(model.indexOf(m)>-1) return true\n    }\n    if(model.indexOf('gpt-4o')>-1 || ( model.indexOf('gemini')>-1 && model.indexOf('1.5')>-1 ) ){\n        return true\n    }\n    //if(model.indexOf('sonnet')>-1 ) return true ;\n    let visionArr=['gemini-pro-vision','gpt-4o-2024-08-06','gpt-4o-2024-11-20','gpt-4o','gpt-4o-2024-05-13','gpt-4o-mini','gpt-4o-mini-2024-07-18','gemini-pro-1.5','gpt-4-turbo','gpt-4-turbo-2024-04-09','gpt-4-vision-preview','luma-video','claude-3-5-sonnet-20240620' ,'claude-3-sonnet-20240229','claude-3-opus-20240229', defaultVisionModel() ]\n    if( homeStore.myData.session.customVisionModel ){ \n        homeStore.myData.session.customVisionModel.split(/[ ,]+/ig).map( (v:string)=>{\n            visionArr.push( v.toLocaleLowerCase() )\n        });\n    }\n    return visionArr.indexOf(model)>-1\n}\nexport const canBase64Model= (model:string)=>{\n    if( isCanBase64Model(model)) return model; \n   return defaultVisionModel();\n}\n\nexport const defaultVisionModel=()=>{\n    if( homeStore.myData.session && homeStore.myData.session.visionModel ){\n        return  homeStore.myData.session.visionModel\n    }\n    return 'gpt-4-vision-preview'\n}\n\nexport const isTTS= ( model:string )=>{\n    if(model.indexOf('tts-1')===0 )return true; \n    return false ;\n}\n\nfunction isStringOnlyDigits(input: string): boolean {\n    // 使用正则表达式检查字符串是否只包含数字\n    const regex = /^[0-9]+$/;\n    return regex.test(input);\n}\nexport const loadGallery  = async ()=>{\n     let localKey= 'mj-list-condition';\n     const d2:any = await localGet(localKey);\n     //mlog('d2',d2 , (Date.now()- d2.ctime));\n     if(d2 && (Date.now()- d2.ctime)<300*1000 ){\n\n        return d2.d as any[];\n     }\n     let  d =  await mjFetch(`/mj/gallery`);\n     //mlog('tsList', d.data.list   );\n     if( !d.data.list  ||  d.data.list.length ==0 ) return [];\n     const list =d.data.list as any[];\n     const ids = list.filter(v=> isStringOnlyDigits(v.reqid)).map(v=> +v.reqid ) ;\n     mlog('ids',  ids   );\n     if(ids.length==0) return [];\n     ///mj/task/list-by-condition\n     d=  await mjFetch('/mj/task/list-by-condition',{ids } );\n\n     if( d.length>0 ) localSaveAny({ctime: Date.now(), d}, localKey);\n     return d as any[] ;\n}\n\n//从剪贴板中读取文件\nexport   function getFileFromClipboard(event:any ){\n    let rz=[];\n    if ( event.clipboardData || event.originalEvent ) {\n        let clipboardData = (event.clipboardData || event.originalEvent.clipboardData);\n        if (clipboardData.items) {\n            let items = clipboardData.items;\n            // mlog('getFileFromClipboard',  items  );\n            for (let i = 0; i < items.length; i++) {\n                if (items[i].type.indexOf(\"image\") !== -1 || items[i].kind === 'file') {\n                    //rz.push( await fileToBase64(  items[i].getAsFile()) );\n                    //mlog('fff', items[i] );\n                    rz.push( items[i].getAsFile()) \n                }\n            }\n\n        }\n    }\n    //console.log('passs>>' ,rz );\n    return rz;\n}\n"
  },
  {
    "path": "src/api/mjsave.ts",
    "content": "import { gptServerStore, homeStore } from \"@/store\";\nimport localforage from \"localforage\"\nimport { mlog } from \"./mjapi\";\n\nlocalforage.config({\n    driver      : localforage.INDEXEDDB, // Force WebSQL; same as using setDriver()\n    name        : 'mj',\n    version     : 1.0,\n    size        : 4980736, // Size of database, in bytes. WebSQL-only for now.\n    storeName   : 'mjkv', // Should be alphanumeric, with underscores.\n    description : 'some description'\n});\n\nexport async function saveImg( key:string, value:string ){\n   await localforage.setItem( key, value )\n}\nexport async function getImg( key:string ): Promise<any>\n{\n   return await localforage.getItem( key )\n}\n\n//本地存储使用了 \nexport const localSave= async (  key:string, value:any)=>{\n    await localforage.setItem( key, value )\n}\n//本地存储获取\nexport const localGet= async( key:string )=>{\n    return await localforage.getItem( key )\n}\n\nexport const localSaveAny = async( value:any,key?:string )=>{ \n    if(!key) key=`MJ:r:${Date.now()}:${Math.floor(Math.random() * 100)}`  ;\n    await localSave(key,value);\n    return key;\n}\n\n\nexport function img2base64(img:any) {\n    let canvas = document.createElement('canvas');\n    canvas.width = img.width;\n    canvas.height = img.height;\n    let ctx = canvas.getContext('2d');\n    if( ! ctx) return \"\";\n    ctx.drawImage(img, 0, 0);\n    return canvas.toDataURL('image/jpeg');\n}\n\nexport function url2base64More(url:string,key?:string){\n    return new Promise<{key:string,base64:string}>((resolve, reject) => {\n\n        const img = new Image();\n        img.crossOrigin = \"anonymous\";\n        img.onload=()=>{ \n            const base64 = img2base64(img) ; \n            localSaveAny(base64,key).then(d=>resolve({key:d, base64})).catch(e=>reject(e));\n        }\n        img.onerror=(e)=>reject(e);\n        img.src =  url;\n    });\n    \n}\n\nexport const url2base64= async (url:string,key?:string)=>{\n    try{\n        return await url2base64More (url,key);\n    }catch(e){\n        return await url2base64More( wsrvUrl(url) ,key);\n    }\n}\n\nexport const wsrvUrl=(url:string)=>{\n    const arr = url.split(/([a-z\\-]+)ttachments/ig, 3 );\n    if( arr.length==3){\n        url= `https://cdn.discordapp.com/${arr[1]}ttachments`+ arr[2];\n    }\n    return `https://wsrv.nl/?url=`+ encodeURIComponent(url);\n}\n\nexport const mjImgUrl= (url:string)=>{\n    if (gptServerStore.myData.MJ_CDN_WSRV || homeStore.myData.session.isWsrv ) return wsrvUrl(url);\n    return url;\n}\n\nexport const getMjAll= async ( ChatState:Chat.ChatState)=>{\n    let rz:Chat.Chat[]=[]\n    ChatState.chat.forEach(v=>{\n       // mlog('uid>>', v.uuid );\n        v.data.forEach(chat=>{\n            if( chat.mjID ){\n               // mlog('MJID>> ',chat.mjID);\n                rz.push(chat );\n            }\n        })\n    });\n    return rz ;\n\n}"
  },
  {
    "path": "src/api/mp4img.ts",
    "content": "import { FFmpeg } from '@ffmpeg/ffmpeg'\nimport type { LogEvent } from '@ffmpeg/ffmpeg/dist/esm/types'\nimport { fetchFile, toBlobURL } from '@ffmpeg/util'\nimport { mlog } from './mjapi'\nconst baseURL = 'https://unpkg.com/@ffmpeg/core-mt@0.12.6/dist/esm'\n\n export async function myTestTranscode( vidoUrl:string) {\n      mlog('vidoUrl>> ', vidoUrl )\n     const ffmpeg = new FFmpeg()\n     //await ffmpeg.load();\n      \n      //message.value = 'Loading ffmpeg-core.js'\n      ffmpeg.on('log', ({ message: msg }: LogEvent) => {\n        //message.value = msg\n        mlog('FFmpeg', msg)\n      })\n      mlog('FFmpegs url23 ' )\n      try{\n      await ffmpeg.load({\n        coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),\n        wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),\n        workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript')\n      })\n      }catch(e){\n         mlog('FFmpegs url3 er ', e  )\n      }\n       \n        //await ffmpeg.load();\n        mlog('FFmpegs url3 ' )\n      //message.value = 'Start transcoding'\n      await ffmpeg.writeFile('input.mp4', await fetchFile(vidoUrl))\n      //await ffmpeg.exec(['-i', 'test.avi', 'test.mp4'])\n      await ffmpeg.exec(['-sseof', '-3', '-i', 'input.mp4', '-update', '1', '-q:v', '1', 'last_frame.jpg'])\n      //message.value = 'Complete transcoding'\n      const data = await ffmpeg.readFile( 'last_frame.jpg')\n      //const url = URL.createObjectURL(new Blob([data.buffer], { type: 'image/jpeg' }));\n      const url = URL.createObjectURL(new Blob([(data as Uint8Array).buffer],  { type: 'image/jpeg' } ))\n      mlog('FFmpeg url ', url )\n      // 创建一个临时的<a>元素\n        const a = document.createElement('a');\n        a.href = url;\n        a.download ='last_frame.jpg'; // 设置下载文件的名称\n\n        // 将 <a> 元素添加到 DOM，然后触发点击事件以启动下载\n        document.body.appendChild(a);\n        a.click();\n\n        // 触发下载后，从 DOM 中移除 <a> 元素，并释放 URL 对象\n        document.body.removeChild(a);\n        URL.revokeObjectURL(url);\n      \n    }"
  },
  {
    "path": "src/api/openapi.ts",
    "content": "\nimport { gptConfigStore, gptServerStore, homeStore,useAuthStore } from \"@/store\";\nimport { mlog,myTrim } from \"./mjapi\";\nimport { fetchSSE } from \"./sse/fetchsse\";\nimport axios from 'axios';\nimport { localGet, localSaveAny } from \"./mjsave\";\nimport { isNumber, isObject } from \"@/utils/is\";\nimport { t } from \"@/locales\";\nimport { ChatMessage } from \"gpt-tokenizer/esm/GptEncoding\";\nimport { chatSetting } from \"./chat\";\nimport { MessageApiInjection } from \"naive-ui/es/message/src/MessageProvider\";\nimport { ideoSubmit } from \"./ideo\";\nimport { error } from \"console\";\n//import {encode,  encodeChat}  from \"gpt-tokenizer\"\n//import {encode,  encodeChat} from \"gpt-tokenizer/cjs/encoding/cl100k_base.js\";\n//import { get_encoding } from '@dqbd/tiktoken'\n//import FormData from 'form-data';\n\n\nexport const KnowledgeCutOffDate: Record<string, string> = {\n  default: \"2021-09\",\n  \"gpt-4-1106-preview\": \"2023-04\",\n  \"gpt-4-0125-preview\": \"2023-12\",\n  \"gpt-4-vision-preview\": \"2023-04\",\n  \"gpt-4-turbo-2024-04-09\": \"2023-12\", \n  \"gpt-4o-2024-05-13\": \"2023-10\", \n  \"o1-preview-2024-09-12\": \"2023-10\", \n  \"o1-preview\": \"2023-10\", \n  \"o1\": \"2023-10\", \n  \"o1-2024-12-17\": \"2023-10\", \n  \"o1-mini\": \"2023-10\", \n  \"o1-mini-2024-09-12\": \"2023-10\", \n  \"gpt-4o\": \"2023-10\", \n  \"gpt-4o-mini\": \"2023-10\", \n  \"gpt-4o-mini-2024-07-18\": \"2023-10\", \n  \"gpt-4o-2024-08-06\": \"2023-10\", //chatgpt-4o-latest\n  \"chatgpt-4o-latest\": \"2023-10\", \n  \"gpt-4o-2024-11-20\": \"2023-10\", \n  \"gpt-4-turbo\": \"2023-12\", \n  \"gpt-4-turbo-preview\": \"2023-12\",\n  \"claude-3-opus-20240229\": \"2023-08\",\n  \"claude-3-sonnet-20240229\": \"2023-08\",\n  \"claude-3-haiku-20240307\": \"2023-08\",\n  \"claude-3-5-sonnet-20240620\": \"2024-04\",\n  \"claude-3-5-sonnet-20241022\": \"2024-04\",\n  \"claude-3-7-sonnet-20250219\": \"2024-04\",\n  \"gemini-pro\": \"2023-12\",\n  \"gemini-pro-vision\": \"2023-12\",\n  \"gpt-4.5-preview-2025-02-27\": \"2024-10\",\n  \"gpt-4.5-preview\": \"2024-10\",\n  \"deepseek-v3\": \"2023-12\",\n  \"deepseek-r1\": \"2023-12\",\n  \"gpt-5\": \"2024-10\",\n  \"gpt-5-mini\": \"2024-06\",\n  \"gpt-5-nano\": \"2024-06\",\n  \"gemini-pro-1.5\": \"2024-04\"\n};\n\nconst getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    if(gptServerStore.myData.OPENAI_API_BASE_URL){\n        return `${ gptServerStore.myData.OPENAI_API_BASE_URL}${url}`;\n    }\n    return `/openapi${url}`;\n}\nexport const gptGetUrl = getUrl\nexport const gptFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('gptFetch', url  );\n    let headers= {'Content-Type':'application/json'}\n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then(d=>d.json().then(d=> resolve(d))\n        .catch(e=>reject(e)))\n        .catch(e=>reject(e))\n    })\n\n}\n\nexport const regCookie= async (n:string )=>{\n    if( n=='' ) return ;\n    //mlog('regCookie:', n)\n    let headers= {'Content-Type':'application/json', 'x-vtoken':n  }\n    //headers={...headers,...getHeaderAuthorization()}\n    let opt:RequestInit ={method:'GET'};\n    opt.headers= headers ;\n    const ck= await  new Promise<any>((resolve, reject) => {\n    fetch('/api/reg', opt )\n        .then(d=>d.json().then(d=> resolve(d))\n        .catch(e=>reject(e)))\n        .catch(e=>reject(e))\n     });\n    homeStore.setMyData({ctoken:ck.ctoken })\n     \n    mlog('regCookie:',   ck,n  )\n}\n // 前端直传 cloudflare r2\nfunction uploadR2(file: File) {\n\treturn new Promise<any>((resolve, reject) => {\n\t\t\t//预签名\n\t\t\taxios.post(gptGetUrl(\"/pre_signed\"), { file_name: file.name, content_type: file.type }, {\n\t\t\t\t\theaders: { 'Content-Type': 'application/json' }\n\t\t\t}).then(response => {\n\t\t\t\t\t\t\tif (response.data.status == \"Success\") {\n\t\t\t\t\t\t\t\t\tconst signedUrl = response.data.data.up;\n\t\t\t\t\t\t\t\t\t//上传\n\t\t\t\t\t\t\t\t\tfetch(signedUrl, {\n\t\t\t\t\t\t\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\t\t\t\t\t\t\tbody: file,\n\t\t\t\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'Content-Type': file.type,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}).then(res2 => {\n\t\t\t\t\t\t\t\t\t\t\tif (res2.ok) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tconsole.log('Upload successful!', response.data.data.url);\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn resolve({ url: response.data.data.url });\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn reject(res2)\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}).catch(error => {\n\t\t\t\t\t\t\t\t\t\t\treturn reject(error)\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\treturn reject(response.data);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t).catch(error => reject(error));\n\t});\n}\n\nexport const GptUploader =   ( _url :string, FormData:FormData )=>{\n\n    //R2上传\n    const upLoaderR2= ()=>{\n        const file = FormData.get('file') as File;\n\t\treturn uploadR2(file);\n    }\n\n    //执行上传\n    const uploadNomalDo = (url:string, headers:any)=>{\n        return new Promise<any>((resolve, reject) => {\n                axios.post( url , FormData, {\n                headers\n            }).then(response =>  resolve(response.data )\n            ).catch(error =>reject(error)  );\n        })\n    }\n\n    //除R2外默认流程\n    const uploadNomal= (url:string)=>{ \n        url= gptServerStore.myData.UPLOADER_URL? gptServerStore.myData.UPLOADER_URL :  gptGetUrl( url );\n        let headers=   {'Content-Type': 'multipart/form-data' } \n        if(gptServerStore.myData.OPENAI_API_BASE_URL && url.indexOf(gptServerStore.myData.OPENAI_API_BASE_URL)>-1  ) {\n            headers={...headers,...getHeaderAuthorization()}\n            \n        }else{\n            const authStore = useAuthStore()\n            if( authStore.token ) {\n                const  header2={ 'x-ptoken':  authStore.token };\n                headers= {...headers, ...header2}\n            }\n        }\n        if( homeStore.myData.vtoken ){\n            const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken };\n             headers= {...headers, ...vtokenh}\n        }\n        return  uploadNomalDo(url,headers );\n        \n    }\n\n    //处理上传流程 \n    const uploadType=   ( (homeStore.myData.session.uploadType??'') as string).toLocaleLowerCase() ;\n    let headers=   {'Content-Type': 'multipart/form-data' }\n    \n    //R2\n    if(uploadType=='r2' ){\n        return upLoaderR2(); \n    //容器\n    }else if( uploadType=='container' ) { \n         const authStore = useAuthStore()\n        if( authStore.token ) {\n            const  header2={ 'x-ptoken':  authStore.token };\n            headers= {...headers, ...header2}\n        }\n        let url= `/openapi${_url}`\n        return  uploadNomalDo(url,headers );\n\n    //前端API\n    }else if( uploadType=='api' ) { \n        headers={...headers,...getHeaderAuthorization()}\n        let url= `${ gptServerStore.myData.OPENAI_API_BASE_URL}${_url}`\n        return  uploadNomalDo(url,headers );\n    \n    //自定义链接\n    }else if( uploadType=='myurl' ) { \n        return  uploadNomalDo(_url,headers );\n    }\n\n    //默认上传流程\n    if(homeStore.myData.session.isUploadR2){\n    return upLoaderR2();\n    }\n    return uploadNomal( _url);\n}\n\nexport const whisperUpload = ( FormData:FormData )=>{\n    const url = gptGetUrl('/v1/audio/transcriptions');\n    let headers=   {'Content-Type': 'multipart/form-data' }\n    headers={...headers,...getHeaderAuthorization()}\n    return new Promise<any>((resolve, reject) => {\n            axios.post( url , FormData, {\n            headers\n        }).then(response =>  resolve(response.data )\n        ).catch(error =>reject(error)  );\n    })\n}\n\n//gpt 文件上传 /v1/image/edits\nexport const gptUploadFile=   (url :string, FormData:FormData)=>{\n    url=  gptGetUrl( url);\n    let headers=   {'Content-Type': 'multipart/form-data' }\n    headers={...headers,...getHeaderAuthorization()}\n\n    return axios.post( url , FormData, {  headers  })\n\n}\n\nexport const subGPT= async (data:any, chat:Chat.Chat )=>{\n   let d:any;\n   let action= data.action;\n   // mlog(\"gp-image-1 base64Array \",   data.base64Array   )\n   //chat.myid=  `${Date.now()}`;\n   const isDall=  action=='gpt.dall-e-3' || isDallImageModel( data.data?.model) ||  data.data?.model?.indexOf('banana')\n   \n   //if(  action=='gpt.dall-e-3' && data.data && data.data.model && data.data.model.indexOf('ideogram')>-1 ){ //ideogram\n   if( isDall && data.data && data.data.model && data.data.model.indexOf('ideogram')>-1 ){ //ideogram\n         mlog(\"ddlog 数据 \", data.data  )\n         try{\n            let d= await ideoSubmit(data.data );\n            mlog(\"ddlog 数据返回 \", d  )\n             const rz = d[0];\n            chat.text= rz.prompt//rz.p??`图片已完成`;\n            chat.opt={imageUrl:rz.url } ;\n            chat.loading = false;\n            homeStore.setMyData({act:'updateChat', actData:chat });\n\n         }catch(e){\n            //chat.text='失败！'+\"\\n```json\\n\"+JSON.stringify(d, null, 2)+\"\\n```\\n\";\n            chat.text='失败！'+\"\\n```json\\n\"+   e  +\"\\n```\\n\";\n            chat.loading=false;\n            homeStore.setMyData({act:'updateChat', actData:chat });\n         }\n   }else if( isDall  && data.data.base64Array!=undefined ){ //执行变化\n        mlog(\"gp-image-1 base64Array \",data.data ,  data.data.base64Array   )\n     //let d= await gptFetch('/v1/images/edits', data.data);\n     const formData = new FormData( ); \n     for(let o in data.data ){\n        if(o=='base64Array'){\n            for(let f of data.data.base64Array){\n                 formData.append('image[]', f.file )\n            }\n        }else{\n            if(o=='size' && data.data[o]=='auto'){\n                continue;\n            }\n            formData.append(o, data.data[o])\n        }\n       \n\n     }\n    mlog(\"formData  \",  formData   )\n    \n    //const jda=    upd.data\n    try {\n        const ds = await gptUploadFile('/v1/images/edits', formData)\n        const d=ds.data;\n        if(ds.status!=200) throw \"Fail with status:\"+ ds.status\n        //const d= jda;\n        //mlog(\"gp-image-1 结果 \",  d   )\n    \n      \n        let key= 'dall:'+chat.myid;\n        const rz : any= d.data[0];\n        if(rz.b64_json){\n            const base64='data:image/png;base64,'+rz.b64_json;\n            await localSaveAny(base64,key)\n        }\n       \n        chat.text= rz.revised_prompt??`图片已完成`;\n        chat.opt={imageUrl:rz.url?rz.url: 'https://www.openai-hk.com/res/img/open.png' } ;\n        chat.loading = false;\n        homeStore.setMyData({act:'updateChat', actData:chat });\n    } catch (e) {\n        chat.text='失败！'+\"\\n```json\\n\"+ (d?JSON.stringify(d, null, 2):e) +\"\\n```\\n\";\n        chat.loading=false;\n        homeStore.setMyData({act:'updateChat', actData:chat });\n    }\n    \n\n   }else if( isDall ){ //执行变化\n       // chat.model= 'dall-e-3';\n       \n\n       let d= await gptFetch('/v1/images/generations', data.data);\n       try{\n            const rz : any= d.data[0];\n            let key= 'dall:'+chat.myid;\n      \n            if(rz.b64_json){\n                const base64='data:image/png;base64,'+rz.b64_json;\n                await localSaveAny(base64,key)\n            }\n            chat.text= rz.revised_prompt??`图片已完成`;\n            chat.opt={imageUrl:rz.url?rz.url: 'https://www.openai-hk.com/res/img/open.png' } ;\n            chat.loading = false;\n            homeStore.setMyData({act:'updateChat', actData:chat });\n       }catch(e){\n            //chat.text='失败！'+\"\\n```json\\n\"+JSON.stringify(d, null, 2)+\"\\n```\\n\";\n            chat.text='失败！'+\"\\n```json\\n\"+ (d?JSON.stringify(d, null, 2):e) +\"\\n```\\n\";\n            chat.loading=false;\n            homeStore.setMyData({act:'updateChat', actData:chat });\n       }\n\n   }\n\n}\n\nexport const isDallImageModel =(model:string|undefined)=>{\n    if(!model) return false;\n    if( model.indexOf('flux')>-1 ) return true; \n    if( model.indexOf('ideogram')>-1 ) return true; \n    if( model.indexOf('gpt-image')>-1 ) return true;  \n   \n    return ['dall-e-2' ,'dall-e-3','ideogram' ].indexOf(model)>-1\n      \n}\n\ninterface subModelType{\n    message:any[]\n    onMessage:(d:{text:string,isFinish:boolean,isAll?:boolean})=>void\n    onError?:(d?:any)=>void\n    signal?:AbortSignal\n    model?:string\n    uuid?:string|number\n}\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.OPENAI_API_KEY){\n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.OPENAI_API_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const getSystemMessage = (uuid?:number )=>{\n    //KnowledgeCutOffDate\n    let sysTem= gptConfigStore.myData.systemMessage;\n    if( uuid ){\n        const chatS= new chatSetting(uuid);\n        sysTem= chatS.getGptConfig().systemMessage ;\n    }\n    if(  sysTem ) return sysTem;\n    let model= gptConfigStore.myData.model?gptConfigStore.myData.model: \"gpt-3.5-turbo\";\n    let producer= 'You are ChatGPT, a large language model trained by OpenAI.'\n    if(model.includes('claude')) producer=  'You are Claude, a large language model trained by Anthropic.';\n    if(model.includes('gemini')) producer=  'You are Gemini, a large language model trained by Google.';\n    if(model.includes('deepseek')) producer=  'You are DeepSeek, a large language model trained by DeepSeek.';\n    if(model.includes('grok')) producer=  'You are grok, a large language model trained by xAi.';\n    //用户自定义系统\n    if(homeStore.myData.session.systemMessage )  producer= homeStore.myData.session.systemMessage\n    \n    let DEFAULT_SYSTEM_TEMPLATE = `${producer}`;\n\nif ( KnowledgeCutOffDate[model] || model.indexOf('gpt-')>-1 )DEFAULT_SYSTEM_TEMPLATE+=`\nKnowledge cutoff: ${KnowledgeCutOffDate[model]??KnowledgeCutOffDate.default}`\nDEFAULT_SYSTEM_TEMPLATE+=`\nCurrent model: ${model}\nCurrent time: ${ new Date().toLocaleString()}\nLatex inline: $x^2$\nLatex block: $$e=mc^2$$`;\nreturn DEFAULT_SYSTEM_TEMPLATE;\n\n}\n\nexport const isNewModel=(model:string)=>{\n    return model.startsWith('o1-') ||   model.includes('gpt-5')\n}\nexport const subModel= async (opt: subModelType)=>{\n    //\n    let model= opt.model?? ( gptConfigStore.myData.model?gptConfigStore.myData.model: \"gpt-3.5-turbo\");\n    let max_tokens= gptConfigStore.myData.max_tokens;\n    let temperature= 0.5;\n    let top_p= 1;\n    let presence_penalty= 0 , frequency_penalty=0;\n    if(opt.uuid){\n        const chatSet= new chatSetting( +opt.uuid);\n        const gStore= chatSet.getGptConfig();\n        temperature= gStore.temperature??temperature;\n        top_p = gStore.top_p??top_p;\n        presence_penalty = gStore.presence_penalty??presence_penalty;\n        frequency_penalty = gStore.frequency_penalty??frequency_penalty;\n        max_tokens= gStore.max_tokens;\n    }\n    if(model=='gpt-4-vision-preview' && max_tokens>2048) max_tokens=2048;\n\n    //gptServerStore.myData.GPTS_GX\n    if( gptServerStore.myData.GPTS_GX ){\n        model= model.replace('gpt-4-gizmo-','')\n    }\n\n    let body:any ={\n            max_tokens ,\n            model ,\n          //  temperature,\n            top_p,\n            presence_penalty ,frequency_penalty,\n            \"messages\": opt.message\n           ,stream:true\n        }\n    if(isNewModel(model)){\n        body ={\n            max_completion_tokens:max_tokens ,\n            model ,\n            //temperature,\n            top_p,\n            presence_penalty ,frequency_penalty,\n            \"messages\": opt.message\n           ,stream:false\n        }\n    }\n    if(body.stream){ \n        let  headers ={\n                'Content-Type': 'application/json'\n                //,'Authorization': 'Bearer ' +gptServerStore.myData.OPENAI_API_KEY\n                ,'Accept': 'text/event-stream '\n        }\n        headers={...headers,...getHeaderAuthorization()}\n\n        try {\n            let is_reasoning_content=false\n\n            await fetchSSE( gptGetUrl('/v1/chat/completions'),{\n                method: 'POST',\n                headers: headers,\n                signal:opt.signal,\n                onMessage: async (data:string)=> {\n                    //mlog('🐞测试'  ,  data )  ;\n                    if(data=='[DONE]') opt.onMessage({text:'',isFinish:true})\n                    else {\n                        const obj= JSON.parse(data );\n                        if( obj.choices[0].delta?.reasoning_content ){\n                            if (!is_reasoning_content){\n                                opt.onMessage({text:\"\\n<think>\\n\"  ,isFinish: false})\n                            }\n                            opt.onMessage({text:obj.choices[0].delta?.reasoning_content  ,isFinish:obj.choices[0].finish_reason!=null })\n                            is_reasoning_content=true\n                        }else{\n                            if(is_reasoning_content){\n                                 opt.onMessage({text:\"\\n</think>\\n\" ,isFinish: false})\n                            }\n                            is_reasoning_content=false\n                            opt.onMessage({text:obj.choices[0].delta?.content??'' ,isFinish:obj.choices[0].finish_reason!=null })\n                        }\n                    }\n                },\n                onError(e ){\n                    //console.log('eee>>', e )\n                    mlog('❌未错误',e    )\n                    opt.onError && opt.onError(e)\n                },\n                body:JSON.stringify(body)\n            });\n        } catch (error ) {\n            mlog('❌未错误2',error  )\n            opt.onError && opt.onError(error)\n        }\n    }else{ \n        try {\n            mlog('🐞非流输出',body  )\n            opt.onMessage({text: t('mj.thinking') ,isFinish: false })\n            let obj :any= await gptFetch( '/v1/chat/completions',body  )\n            //mlog('结果 >>',obj   )\n            opt.onMessage({text:obj.choices[0].message.content??'' ,isFinish: true ,isAll:true})\n            \n        } catch (error ) {\n            mlog('❌未错误2',error  )\n            opt.onError && opt.onError(error)\n        }\n    }\n}\n\nexport const getInitChat = (txt:string )=>{\n    let promptMsg: Chat.Chat= {\n        dateTime: new Date().toLocaleString(),\n        text:  txt ,\n        inversion: true,\n        error: false,\n        conversationOptions: null,\n        requestOptions: { prompt:txt, options: null },\n        }\n        return promptMsg;\n}\n\nexport interface ttsType{\n        model: string,\n        input: string ,\n        voice?: string,\n\n}\nexport const subTTS = async (tts:ttsType )=>{\n    if(!tts.voice) tts.voice='alloy';\n    let url= getUrl('/v1/audio/speech');\n    let headers=  {\n        'Content-Type': 'application/json'\n      }\n     headers={...headers,...getHeaderAuthorization()}\n    const response = await fetch(url, {\n      method: 'POST',\n      headers,\n      body: JSON.stringify(tts),\n    });\n\n    if (!response.ok) {\n      throw new Error(`API request failed with status ${response.status}`);\n    }\n    const audioData = await response.arrayBuffer();\n    const contentType = response.headers.get('Content-Type')\n    const blob = new Blob([audioData], { type: contentType??'audio/mpeg' });\n    mlog('blob', blob);\n    const saveID = await localSaveAny( blob );\n    const pp= await bolbObj(blob );\n    return { blob,saveID ,...pp };\n\n}\n\nexport const bolbObj= ( blob:Blob )=>{\n    return new Promise<{player:HTMLAudioElement,duration:number }>((resolve, reject) => {\n        const player = new window.Audio();\n        player.src = URL.createObjectURL(blob);\n\n        player.addEventListener('loadedmetadata', () => {\n            mlog('时长', player.duration);\n            resolve({player,duration: player.duration });\n        });\n        player.addEventListener('error',(e )=>{\n            reject(e )\n        })\n        player.load();\n    })\n\n}\n\nfunction formatDate(): string[] {\n  const today = new Date()\n  const year = today.getFullYear()\n  const month = today.getMonth() + 1\n  const lastDay = new Date(year, month, 0)\n  const formattedFirstDay = `${year}-${month.toString().padStart(2, '0')}-01`\n  const formattedLastDay = `${year}-${month.toString().padStart(2, '0')}-${lastDay.getDate().toString().padStart(2, '0')}`\n  return [formattedFirstDay, formattedLastDay]\n}\n\n//\n\nexport const  gptUsage=async ()=>{\n\n    // fetch(getUrl(url),  opt )\n    //     .then(d=>d.json().then(d=> resolve(d))\n    //     .catch(e=>reject(e)))\n    //     .catch(e=>reject(e))\n    const [startDate, endDate] = formatDate();\n    const urlUsage = `/v1/dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}`\n    const usageData = await gptFetch(urlUsage);\n    const billData = await gptFetch('/v1/dashboard/billing/subscription');\n\n    const usage = Math.round(usageData.total_usage) / 100\n     mlog('gpt', usage , billData  );\n     //remaining = subscriptionData.system_hard_limit_usd - totalUsage;\n     return {usage,remaining:Math.round( (billData.hard_limit??billData.hard_limit_usd*100) - usageData.total_usage ) / 100 ,hard_limit_usd:billData.hard_limit_usd } ;\n\n}\n\nexport const openaiSetting= ( q:any,ms:MessageApiInjection )=>{\n    //mlog()\n    mlog('setting', q )\n    if(q.settings){\n        mlog('q.setting', q.settings )\n        try {\n            let obj = JSON.parse( q.settings );\n            const url = obj.url ?? undefined;\n            const key = obj.key ?? undefined;\n            //let setQ= { }\n            gptServerStore.setMyData(  {\n                OPENAI_API_BASE_URL:url, \n                MJ_SERVER:url, \n                SUNO_SERVER:url,\n                LUMA_SERVER:url,\n                RUNWAY_SERVER:url,\n                VIGGLE_SERVER:url,\n                IDEO_SERVER:url,\n                KLING_SERVER:url,\n                PIKA_SERVER:url,\n                UDIO_SERVER:url,\n                PIXVERSE_SERVER:url,\n                RIFF_SERVER:url,\n                \n                \n                \n                OPENAI_API_KEY:key,\n                MJ_API_SECRET:key, \n                SUNO_KEY:key,\n                LUMA_KEY:key,\n                RUNWAY_KEY:key,\n                VIGGLE_KEY:key,\n                IDEO_KEY:key,\n                KLING_KEY:key,\n                PIKA_KEY:key,\n                UDIO_KEY:key,\n                PIXVERSE_KEY:key,\n                RIFF_KEY:key,\n             } )\n            blurClean();\n            gptServerStore.setMyData( gptServerStore.myData );\n            ms.success(\"设置服务端成功！\")\n            \n        } catch (error) {\n            \n        }\n    }\n    else if(isObject(q)){\n        mlog('setting2', q )\n        gptServerStore.setMyData(  q )\n        //gptServerStore.setMyData( gptServerStore.myData );\n        blurClean();\n        gptServerStore.setMyData( gptServerStore.myData );\n\n    }\n\n}\nexport const blurClean= ()=>{\n  mlog('blurClean');\n  gptServerStore.myData.OPENAI_API_BASE_URL =myTrim( myTrim(gptServerStore.myData.OPENAI_API_BASE_URL.trim(),'/'), '\\\\' );\n  gptServerStore.myData.OPENAI_API_KEY = gptServerStore.myData.OPENAI_API_KEY.trim();\n  gptServerStore.myData.MJ_SERVER =myTrim( myTrim( gptServerStore.myData.MJ_SERVER.trim(),'/'),'\\\\');\n  gptServerStore.myData.MJ_API_SECRET = gptServerStore.myData.MJ_API_SECRET.trim();\n  gptServerStore.myData.UPLOADER_URL=  myTrim( myTrim( gptServerStore.myData.UPLOADER_URL.trim(),'/'),'\\\\');\n}\n\nexport const countTokens= async ( dataSources:Chat.Chat[], input:string ,uuid:number )=>{\n    const chatSet= new chatSetting(uuid);\n    const myStore= chatSet.getGptConfig();\n    let rz={system:0,input:0 ,history:0,remain:330,modelTokens:'4k',planOuter:myStore.max_tokens  }\n    const model =myStore.model;\n    const max= getModelMax(model );\n    let unit= 1024;\n    if(  model=='gpt-4-1106-preview' || model=='gpt-4-vision-preview' ) unit=1000;\n    //gpt-4-turbo-2024-04-09\n    if (model.indexOf('gpt-4-turbo')>-1 ) unit=1000;\n    rz.modelTokens= `${max}k`\n    //cl100k_base.encode(input)\n\n    const encode= await encodeAsync();\n    rz.input = encode(input).length;\n    rz.system = encode(getSystemMessage() ).length;\n    const encodeChat = await encodeChatAsync();\n    const msg= await getHistoryMessage(  dataSources,1 ) ;\n    rz.history= msg.length==0?0: encodeChat(msg, model.indexOf('gpt-4')>-1? 'gpt-4':'gpt-3.5-turbo').length\n    //\n    rz.remain = unit *max- rz.history- rz.planOuter- rz.input- rz.system; \n\n    return rz ;\n}\nconst getModelMax=( model:string )=>{\n    let max=4;\n    model= model.toLowerCase();\n    if( model.indexOf('8k')>-1  ){\n        return 8;\n    }else if( model.indexOf('16k')>-1 || model=='gpt-3.5-turbo-1106' || model=='gpt-3.5-turbo-0125' ){\n        return 16;\n    }else if( model.indexOf('32k')>-1  ){\n        return 32;\n    }else if( model.indexOf('grok')>-1 ){\n       return 128; \n    }else if(  model.indexOf('gpt-4.5')>-1|| model.indexOf('gpt-4-turbo')>-1||  model.indexOf('gpt-4o')>-1 ||   model.indexOf('o1-')>-1){\n        return 128; \n    }else if( model.indexOf('64k')>-1 || model.indexOf('deepseek')>-1 ){\n        return 64;\n    }else if( model.indexOf('128k')>-1 \n    || model=='gpt-4-1106-preview' \n    || model=='gpt-4-0125-preview' \n    || model=='gpt-4-vision-preview' ){\n        return 128; \n    }else if( model.indexOf('gpt-4')>-1  ){  \n        max=8;\n    }else if( model.toLowerCase().includes('claude-3') ){\n        //options.maxModelTokens = 120*1024;\n        //options.maxResponseTokens = 4096\n        return 120;\n    }\n\n    return max;\n}\n\nexport const encodeAsync = async ( ) => {\n  const { encode } = await import('gpt-tokenizer');\n\n  return encode;//(str).length;\n};\nexport const encodeChatAsync = async ( ) => {\n  const { encodeChat } = await import('gpt-tokenizer');\n\n  return encodeChat;//(obj,model ).length;\n};\n\n\nexport const getHistoryMessage= async (dataSources:Chat.Chat[],loadingCnt=1 ,start=1000)=>{\n    let i=0;\n    let rz: ChatMessage[] = [];\n    //const loadingCnt= 1;// 1就是没有loading，3 就是有loading\n    let istart = (isNumber( start)&& start>=0 )? Math.min(start  ,   dataSources.length - loadingCnt ):  dataSources.length- loadingCnt  ;\n    mlog('istart',istart, start);\n    for( let ii=  istart  ; ii>=0 ; ii-- ){ //let o of dataSources.value\n        if(i>=gptConfigStore.myData.talkCount) break;\n        i++;\n\n        let o = dataSources[ii];\n        //mlog('o',ii ,o);\n        let content= o.text;\n        if( o.inversion && o.opt?.images && o.opt.images.length>0 ){\n            //获取附件信息 比如 图片 文件等\n            try{\n               let str =  await localGet(  o.opt.images[0]) as string;\n               let fileBase64= JSON.parse(str) as string[];\n               let arr =  fileBase64.filter( (ff:string)=>ff.indexOf('http')>-1);\n               if(arr.length>0) content = arr.join(' ')+' '+ content ;\n               mlog(t('mjchat.attr') ,o.opt.images[0] , content );\n            }catch(ee){\n            }\n        }\n\n        //mlog('d',gptConfigStore.myData.talkCount ,i ,o.inversion , o.text);\n        rz.push({content , role: !o.inversion ? 'assistant' : 'user'});\n    }\n    rz.reverse();\n    mlog('rz',rz);\n    return rz ;\n}\n\n\nexport const isDisableMenu=(menu:string)=>{\n\n return (homeStore.myData.session  && homeStore.myData.session.menuDisable && homeStore.myData.session.menuDisable.indexOf( menu)>-1 )\n}"
  },
  {
    "path": "src/api/pika.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sleep } from \"./suno\";\nimport { RunwayTask, runwayStore } from \"./runwayStore\";\nimport { PikaTask, pikaStore } from \"./pikaStore\";\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.RUNWAY_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.PIKA_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.PIKA_SERVER  ){\n        if(gptServerStore.myData.PIKA_SERVER.indexOf('/pro')>0){\n            return `${ gptServerStore.myData.PIKA_SERVER}/pika${url}`;\n        }\n        return `${ gptServerStore.myData.PIKA_SERVER}${pro_prefix}/pika${url}`;\n    }\n    return `${pro_prefix}/pika${url}`;\n}\n\n\nexport const pikaFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('pikaFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const pikaFeed= async(id:string)=>{\n    const sunoS = new pikaStore();\n    for(let i=0; i<200;i++){\n        try{\n            let a= await pikaFetch('/feed/' +id )\n            let task= a  as PikaTask;\n            mlog(\"task\",a )\n            if(!task.videos || task.videos.length==0) continue;\n            task.last_feed=new Date().getTime()\n            \n            \n            sunoS.save( task )\n            homeStore.setMyData({act:'PikaFeed'});\n            if( task.videos[0].status=='error' || 'finished'== task.videos[0].status ){\n                break;\n            }\n        }catch(e){\n        }\n        await sleep(5200)\n    }\n\n}\n\n "
  },
  {
    "path": "src/api/pikaStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\ninterface Video {\n  id: string;\n  status: string;\n  seed: number;\n  resultUrl: string;\n  sharingUrl: string;\n  videoPoster: string;\n  imageThumb: string;\n  duration: number;\n  error: string;\n  progress: number;\n}\n\n// 定义主结构体接口\nexport interface PikaTask {\n  id: string;\n  promptText: string;\n  videos: Video[];\n  last_feed?:number;\n}\n\nexport class pikaStore{\n  //private id: string;\n  private localKey='pika-store';\n  public save(obj:PikaTask ){\n    if(!obj.id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():PikaTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| PikaTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):PikaTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( obj:PikaTask ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/pixverse.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { pixverseRep, pixverseStore, pixverseTask } from \"./pixverseStore\";\nimport { sleep } from \"./suno\";\n// import { KlingTask, klingStore } from \"./klingStore\";\n// import { sleep } from \"./suno\";\n\n\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.KLING_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.PIXVERSE_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= '';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.PIXVERSE_SERVER  ){\n      \n        return `${ gptServerStore.myData.PIXVERSE_SERVER}${pro_prefix}/pixverse${url}`;\n    }\n    return `${pro_prefix}/pixverse${url}`;\n}\n\n\nexport const pixFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('runwayFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const pixFeed= async( id:number)=>{\n    const sunoS = new pixverseStore();\n    let url= `/feed/${id}`;\n    for(let i=0; i<200;i++){\n         try{\n            \n            let a= await pixFetch( url )\n            //let task= a  as KlingTask;\n            if(a.ErrCode==0 && a.Resp){\n            //task.last_feed=new Date().getTime()\n                let d= a.Resp as pixverseRep\n                const task:pixverseTask={ video_id:id,last_feed:new Date().getTime(), data:d } \n                sunoS.save( task )\n                homeStore.setMyData({act:'PixFeed'});\n                mlog('pixFetch', a )\n                if (d.video_status==1){\n                    break;\n                }\n                \n            }\n         }catch(e){\n         }\n        await sleep(5200)\n    }\n\n\n}\n"
  },
  {
    "path": "src/api/pixverseStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\nexport interface pixverseRep{\n        video_status: number;\n        created_at: string;\n        first_frame: string;\n        prompt: string;\n        model: string;\n        negative_prompt: string;\n        quality: string;\n        motion_mode: string;\n        video_duration: number;\n        last_frame: string;\n        extended?: number;\n        url: string;\n}\nexport interface pixverseTask {\n    video_id: number;\n    last_feed?: number //最后更新时间\n    data?:pixverseRep\n}\n\n\n\n\nexport class pixverseStore{\n  //private id: string;\n  private localKey='pixverse-store';\n  public save(obj:pixverseTask ){\n    if(!obj.video_id) throw \"video_id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.video_id==obj.video_id);\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:number){ \n    return this.getObjs().findIndex( v=>v.video_id == id )\n  }\n\n  public getObjs():pixverseTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| pixverseTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:number):pixverseTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( id:number ){\n    //if(!obj.data.task_id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.video_id==id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/realtime.ts",
    "content": "export const instructions = `System settings:\nTool use: enabled.\n\nInstructions:\n- You are an artificial intelligence agent responsible for helping test realtime voice capabilities\n- Please make sure to respond with a helpful voice via audio\n- Be kind, helpful, and curteous\n- It is okay to ask the user questions\n- Use tools and functions you have available liberally, it is part of the training apparatus\n- Be open to exploration and conversation\n- Remember: this is just for fun and testing!\n\nPersonality:\n- Be upbeat and genuine\n- Try speaking quickly as if excited\n`;\nexport interface RealtimeEvent {\n  time: string;\n  source: 'client' | 'server';\n  count?: number;\n  event: { [key: string]: any };\n}"
  },
  {
    "path": "src/api/riff.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { pixverseRep, pixverseStore, pixverseTask } from \"./pixverseStore\";\nimport { sleep } from \"./suno\";\nimport { riffAudio, riffStore, riffTask } from \"./riffStore\";\n// import { KlingTask, klingStore } from \"./klingStore\";\n// import { sleep } from \"./suno\";\n\n\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.RIFF_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.RIFF_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= '';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.RIFF_SERVER  ){\n      \n        return `${ gptServerStore.myData.RIFF_SERVER}${pro_prefix}/riffusion${url}`;\n    }\n    return `${pro_prefix}/riffusion${url}`;\n}\n\n\nexport const riffFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('riffFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const riffFeed= async( ids:string)=>{\n    const sunoS = new riffStore();\n    let url= `/feed/${ids}`;\n    for(let i=0; i<200;i++){\n         try{\n            \n            let a= await riffFetch( url )\n             mlog('riffFetch', a )\n            if(a.generations && a.generations.length >0){\n                for(let o of a.generations){\n                    mlog('riffFetch-one', o )\n                    let d:riffAudio= o as riffAudio\n                    const   task:riffTask={ id:d.id,last_feed:new Date().getTime(),riff:d,status: a.status } \n                    sunoS.save( task )\n                }\n                if(a.status=='success'){\n                    homeStore.setMyData({act:'RiffFeed'});\n                    break;\n                }\n            }else{\n                let arr= ids.split(',')\n                for(let id of arr){\n                    const task:riffTask={ id,last_feed:new Date().getTime(), status: 'submitted' } \n                    sunoS.save( task )\n                }\n            }\n            homeStore.setMyData({act:'RiffFeed'});\n\n\n            \n         }catch(e){\n         }\n        await sleep(5200)\n    }\n\n\n}\n"
  },
  {
    "path": "src/api/riffStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\nexport interface riffAudio {\n    audio_url?: string;\n    duration_s: number;\n    id: string;\n    image_url?: string;\n    lyrics?: string;\n    model_display_name: string;\n    sound?: string;\n    title?: string;\n    topic?: string;\n}\nexport interface riffTask {\n    id:string\n    status:string\n    riff?:riffAudio\n    last_feed?: number //最后更新时间\n    \n}\n\n\nexport class riffStore{\n  //private id: string;\n  private localKey='riff-store';\n  public save(obj:riffTask ){\n    if(!obj.id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id == id )\n  }\n\n  public getObjs():riffTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| riffTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):riffTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( id:string ){ \n    let arr=  this.getObjs();\n    \n    let i= arr.findIndex( v=>v.id==id );\n    //mlog('ddd',i , arr)\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/runway.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sleep } from \"./suno\";\nimport { RunwayTask, runwayStore } from \"./runwayStore\";\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.RUNWAY_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.RUNWAY_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.RUNWAY_SERVER  ){\n        if(gptServerStore.myData.RUNWAY_SERVER.indexOf('/pro')>0){\n            return `${ gptServerStore.myData.RUNWAY_SERVER}/runway${url}`;\n        }\n        return `${ gptServerStore.myData.RUNWAY_SERVER}${pro_prefix}/runway${url}`;\n    }\n    return `${pro_prefix}/runway${url}`;\n}\n\n\nexport const runwayFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('runwayFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const runwayFeed= async(id:string)=>{\n    const sunoS = new runwayStore();\n    for(let i=0; i<200;i++){\n        try{\n            let a= await runwayFetch('/tasks/' +id )\n            let task= a.task  as RunwayTask;\n            task.last_feed=new Date().getTime()\n            //ss.save( task )\n            mlog(\"a\",a.task  )\n            sunoS.save( task )\n            homeStore.setMyData({act:'RunwayFeed'});\n            if( a.task.status=='FAILED' || 'SUCCEEDED'== a.task.status ){\n                break;\n            }\n        }catch(e){\n        }\n        await sleep(5200)\n    }\n\n}\n\n\nexport const runwayUpload= async (file:any , type :string)=>{\n     let obj={\n            \"filename\": file.name,\n            \"numberOfParts\": 1,\n            type //\"DATASET_PREVIEW\"\n        }\n    const  d:any = await runwayFetch('/uploads',obj)\n    mlog(\"runwayUpload\",d)\n\n    const response= await fetch( d.uploadUrls[0], {\n        method: 'PUT',\n        body: file,\n        headers: {\n            'Content-Type': d.uploadHeaders[\"Content-Type\"],\n            'Accept': '/',\n            'Accept-Language': 'zh-CN,zh;q=0.9',\n            'Connection': 'keep-alive'\n        }\n    }) ;\n    //const djson:any = await response.json();\n    if (response.status!=200){\n      throw \"upload file faile\"\n    }\n    //mlog(\"runwayUpload2\", djson)\n    // return djson uploads/0e01608a-89f8-4cb8-920a-669813fb224f/complete\n    let obj2={\"parts\":[{\"PartNumber\":1,\"ETag\":\"ca3b00c313b6fd9a5c48889ad16f7d5e\"}]}\n    const  d2:any = await runwayFetch(`/uploads/${d.id}/complete`, obj2 )\n    mlog(\"runwayUpload2\", d2)\n    return d2;\n}\n"
  },
  {
    "path": "src/api/runwayStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\ninterface Options {\n    name: string;\n    seconds: number;\n    gen2Options?: Gen2Options;\n    exploreMode?: boolean;\n    assetGroupName?: string;\n    recordingEnabled?: boolean;\n    text_prompt?:string\n}\n\ninterface Gen2Options {\n    mode: string;\n    seed: number;\n    interpolate: boolean;\n    upscale: boolean;\n    watermark: boolean;\n    motion_score: number;\n    use_motion_score: boolean;\n    use_motion_vectors: boolean;\n    text_prompt: string;\n    image_prompt?: string;\n    init_image?: string;\n}\n\ninterface Artifact {\n    id: string;\n    createdAt: string;\n    updatedAt: string;\n    userId: number;\n    createdBy: number;\n    taskId: string;\n    parentAssetGroupId: string;\n    filename: string;\n    url: string;\n    fileSize: string;\n    isDirectory: boolean;\n    previewUrls: string[];\n    private: boolean;\n    privateInTeam: boolean;\n    deleted: boolean;\n    reported: boolean;\n    metadata: Metadata;\n    favorite: boolean;\n}\n\ninterface Metadata {\n    frameRate: number;\n    duration: number;\n    dimensions: number[];\n    size: Size;\n}\n\ninterface Size {\n    width: number;\n    height: number;\n}\n\nexport interface RunwayTask {\n    id: string;\n    name: string;\n    image: any; // Can be changed to a specific type if needed\n    createdAt: string;\n    updatedAt: string;\n    taskType: string;\n    options: Options;\n    status: string;\n    error: any; // Can be changed to a specific type if needed\n    progressText: any; // Can be changed to a specific type if needed\n    progressRatio: string;\n    estimatedTimeToStartSeconds?: number; // Can be changed to a specific type if needed\n    artifacts?: Artifact[];\n    sharedAsset: any; // Can be changed to a specific type if needed\n    last_feed?:number;\n}\n\nexport class runwayStore{\n  //private id: string;\n  private localKey='runway-store';\n  public save(obj:RunwayTask ){\n    if(!obj.id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():RunwayTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| RunwayTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):RunwayTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( obj:RunwayTask ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/runwayml.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sleep } from \"./suno\";\nimport { RunwayMlStore, RunwayMlTask } from \"./runwaymlStore\";\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.RUNWAY_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.RUNWAY_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.RUNWAY_SERVER  ){\n        return `${ gptServerStore.myData.RUNWAY_SERVER}${pro_prefix}/runwayml${url}`;\n    }\n    return `${pro_prefix}/runwayml${url}`;\n}\n\n\nexport const runwayMlFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('runwayFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    const otherHeader ={ 'X-Runway-Version': '2024-11-06'}\n\n    headers={...headers,...getHeaderAuthorization()} //,...otherHeader\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n}\n\nexport interface RunwayMlInput {\n    model:string\n    promptText:string\n}\n\nexport const runwayMlFeed= async(id:string, input:RunwayMlInput)=>{\n    const sunoS = new RunwayMlStore();\n    for(let i=0; i<1200; i++){\n        let d= await runwayMlFetch(`/v1/tasks/${id}`)\n        let task:RunwayMlTask={...d,...input} as RunwayMlTask\n        task.last_feed=new Date().getTime()\n        sunoS.save( task )\n        homeStore.setMyData({act:'runwayml.feed'})\n        if(task.status=='SUCCEEDED' || 'FAILED'== task.status ){\n            break;\n        }\n        //mlog('ddd>>',d )\n        await sleep(5800)\n    }\n}\n\nexport const runwayMlFeedById= async(id:string)=>{\n     const sunoS = new RunwayMlStore();\n     const obj= sunoS.getOneById(id)\n     if (!obj) return ;\n     runwayMlFeed(id,{ model:obj.model,promptText:obj.promptText})\n}\n\n\nexport function getRandomInt(min: number, max: number): number {\n    min = Math.ceil(min);\n    max = Math.floor(max);\n    return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n"
  },
  {
    "path": "src/api/runwaymlStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\nexport interface RunwayMlTask {\n    id: string;\n    status: string;\n    createdAt: string;\n    output?: string[];\n    last_feed?:number; \n    failure?: string\n    failureCode?: string\n    model:string\n    promptText:string\n}\n\n\n\nexport class RunwayMlStore{\n  //private id: string;\n  private localKey='runwayml-store';\n  public save(obj:RunwayMlTask ){\n    if(!obj.id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():RunwayMlTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| RunwayMlTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):RunwayMlTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( obj:RunwayMlTask ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/sse/fetch.ts",
    "content": "/// <reference lib=\"dom\" />\n\nconst fetch = globalThis.fetch\n\nexport { fetch }\n"
  },
  {
    "path": "src/api/sse/fetchsse.ts",
    "content": "import { createParser } from 'eventsource-parser'\n\nimport * as types from './types'\nimport { fetch as globalFetch } from './fetch'\nimport { streamAsyncIterable } from './stream-async-iterable'\n\nexport class ChatGPTError2 extends types.ChatGPTError{\n    reason?:string\n}\nexport async function fetchSSE(\n  url: string,\n  options: Parameters<typeof fetch>[1] & {\n    onMessage: (data: string) => void\n    onError?: (error: any) => void\n  },\n  fetch: types.FetchFn = globalFetch\n) {\n  const { onMessage, onError, ...fetchOptions } = options\n  let res ;\n  try{\n     res = await fetch(url, fetchOptions)\n  }catch(e :any ){ \n    throw {reason: JSON.stringify({message:'fetch error, pleace check url',url ,code:'fetch_error'}) } \n  }\n  if (!res.ok) {\n    let reason: string\n\n    try {\n      reason = await res.text()\n    } catch (err) {\n      reason = res.statusText\n    }\n\n    const msg = `ChatGPT error ${res.status}: ${reason}`\n    const error = new ChatGPTError2(msg, { cause: res })\n    error.statusCode = res.status\n    error.statusText = res.statusText\n    error.reason =reason\n    throw error\n  }\n\n  const parser = createParser((event) => {\n    if (event.type === 'event') {\n      onMessage(event.data)\n    }\n  })\n\n  // handle special response errors\n  const feed = (chunk: string) => {\n    let response = null\n\n    try {\n      response = JSON.parse(chunk)\n    } catch {\n      // ignore\n    }\n\n    if (response?.detail?.type === 'invalid_request_error') {\n      const msg = `ChatGPT error ${response.detail.message}: ${response.detail.code} (${response.detail.type})`\n      const error = new types.ChatGPTError(msg, { cause: response })\n      error.statusCode = response.detail.code\n      error.statusText = response.detail.message\n\n      if (onError) {\n        onError(error)\n      } else {\n        console.error(error)\n      }\n\n      // don't feed to the event parser\n      return\n    }\n\n    parser.feed(chunk)\n  }\n\n  if (!res.body.getReader) {\n    // Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to\n    // web standards, so this is a workaround...\n    const body: NodeJS.ReadableStream = res.body as any\n\n    if (!body.on || !body.read) {\n      throw new types.ChatGPTError('unsupported \"fetch\" implementation')\n    }\n\n    body.on('readable', () => {\n      let chunk: string | Buffer\n      while (null !== (chunk = body.read())) {\n        feed(chunk.toString())\n      }\n    })\n  } else {\n    for await (const chunk of streamAsyncIterable(res.body)) {\n      const str = new TextDecoder().decode(chunk)\n      //console.log(str );\n      feed(str)\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/sse/stream-async-iterable.ts",
    "content": "export async function* streamAsyncIterable<T>(stream: ReadableStream<T>) {\n  const reader = stream.getReader()\n  try {\n    while (true) {\n      const { done, value } = await reader.read()\n      if (done) {\n        return\n      }\n      yield value\n    }\n  } finally {\n    reader.releaseLock()\n  }\n}\n"
  },
  {
    "path": "src/api/sse/types.ts",
    "content": "//import Keyv from 'keyv'\n\nexport type Role = 'user' | 'assistant' | 'system'\n\nexport type FetchFn = typeof fetch\n\nexport type ChatGPTAPIOptions = {\n  apiKey: string\n\n  /** @defaultValue `'https://api.openai.com'` **/\n  apiBaseUrl?: string\n\n  apiOrg?: string\n\n  /** @defaultValue `false` **/\n  debug?: boolean\n\n  completionParams?: Partial<\n    Omit<openai.CreateChatCompletionRequest, 'messages' | 'n' | 'stream'>\n  >\n\n  systemMessage?: string\n\n  /** @defaultValue `4096` **/\n  maxModelTokens?: number\n\n  /** @defaultValue `1000` **/\n  maxResponseTokens?: number\n\n  //messageStore?: Keyv\n  getMessageById?: GetMessageByIdFunction\n  upsertMessage?: UpsertMessageFunction\n\n  fetch?: FetchFn\n}\n\nexport type SendMessageOptions = {\n  /** The name of a user in a multi-user chat. */\n  name?: string\n  parentMessageId?: string\n  conversationId?: string\n  messageId?: string\n  stream?: boolean\n  systemMessage?: string\n  timeoutMs?: number\n  onProgress?: (partialResponse: ChatMessage) => void\n  abortSignal?: AbortSignal\n  completionParams?: Partial<\n    Omit<openai.CreateChatCompletionRequest, 'messages' | 'n' | 'stream'>\n  >\n}\n\nexport type MessageActionType = 'next' | 'variant'\n\nexport type SendMessageBrowserOptions = {\n  conversationId?: string\n  parentMessageId?: string\n  messageId?: string\n  action?: MessageActionType\n  timeoutMs?: number\n  onProgress?: (partialResponse: ChatMessage) => void\n  abortSignal?: AbortSignal\n}\n\nexport interface ChatMessage {\n  id: string\n  text: string\n  role: Role\n  name?: string\n  delta?: string\n  detail?:\n    | openai.CreateChatCompletionResponse\n    | CreateChatCompletionStreamResponse\n\n  // relevant for both ChatGPTAPI and ChatGPTUnofficialProxyAPI\n  parentMessageId?: string\n\n  // only relevant for ChatGPTUnofficialProxyAPI (optional for ChatGPTAPI)\n  conversationId?: string\n}\n\nexport class ChatGPTError extends Error {\n  statusCode?: number\n  statusText?: string\n  isFinal?: boolean\n  accountId?: string\n  \n}\n\n/** Returns a chat message from a store by it's ID (or null if not found). */\nexport type GetMessageByIdFunction = (id: string) => Promise<ChatMessage>\n\n/** Upserts a chat message to a store. */\nexport type UpsertMessageFunction = (message: ChatMessage) => Promise<void>\n\nexport interface CreateChatCompletionStreamResponse\n  extends openai.CreateChatCompletionDeltaResponse {\n  usage: CreateCompletionStreamResponseUsage\n}\n\nexport interface CreateCompletionStreamResponseUsage\n  extends openai.CreateCompletionResponseUsage {\n  estimated: true\n}\n\n/**\n * https://chat.openapi.com/backend-api/conversation\n */\nexport type ConversationJSONBody = {\n  /**\n   * The action to take\n   */\n  action: string\n\n  /**\n   * The ID of the conversation\n   */\n  conversation_id?: string\n\n  /**\n   * Prompts to provide\n   */\n  messages: Prompt[]\n\n  /**\n   * The model to use\n   */\n  model: string\n\n  /**\n   * The parent message ID\n   */\n  parent_message_id: string\n}\n\nexport type Prompt = {\n  /**\n   * The content of the prompt\n   */\n  content: PromptContent\n\n  /**\n   * The ID of the prompt\n   */\n  id: string\n\n  /**\n   * The role played in the prompt\n   */\n  role: Role\n}\n\nexport type ContentType = 'text'\n\nexport type PromptContent = {\n  /**\n   * The content type of the prompt\n   */\n  content_type: ContentType\n\n  /**\n   * The parts to the prompt\n   */\n  parts: string[]\n}\n\nexport type ConversationResponseEvent = {\n  message?: Message\n  conversation_id?: string\n  error?: string | null\n}\n\nexport type Message = {\n  id: string\n  content: MessageContent\n  role: Role\n  user: string | null\n  create_time: string | null\n  update_time: string | null\n  end_turn: null\n  weight: number\n  recipient: string\n  metadata: MessageMetadata\n}\n\nexport type MessageContent = {\n  content_type: string\n  parts: string[]\n}\n\nexport type MessageMetadata = any\n\nexport namespace openai {\n  export interface CreateChatCompletionDeltaResponse {\n    id: string\n    object: 'chat.completion.chunk'\n    created: number\n    model: string\n    choices: [\n      {\n        delta: {\n          role: Role\n          content?: string\n        }\n        index: number\n        finish_reason: string | null\n      }\n    ]\n  }\n\n  /**\n   *\n   * @export\n   * @interface ChatCompletionRequestMessage\n   */\n  export interface ChatCompletionRequestMessage {\n    /**\n     * The role of the author of this message.\n     * @type {string}\n     * @memberof ChatCompletionRequestMessage\n     */\n    role: ChatCompletionRequestMessageRoleEnum\n    /**\n     * The contents of the message\n     * @type {string}\n     * @memberof ChatCompletionRequestMessage\n     */\n    content: string\n    /**\n     * The name of the user in a multi-user chat\n     * @type {string}\n     * @memberof ChatCompletionRequestMessage\n     */\n    name?: string\n  }\n  export declare const ChatCompletionRequestMessageRoleEnum: {\n    readonly System: 'system'\n    readonly User: 'user'\n    readonly Assistant: 'assistant'\n  }\n  export declare type ChatCompletionRequestMessageRoleEnum =\n    (typeof ChatCompletionRequestMessageRoleEnum)[keyof typeof ChatCompletionRequestMessageRoleEnum]\n  /**\n   *\n   * @export\n   * @interface ChatCompletionResponseMessage\n   */\n  export interface ChatCompletionResponseMessage {\n    /**\n     * The role of the author of this message.\n     * @type {string}\n     * @memberof ChatCompletionResponseMessage\n     */\n    role: ChatCompletionResponseMessageRoleEnum\n    /**\n     * The contents of the message\n     * @type {string}\n     * @memberof ChatCompletionResponseMessage\n     */\n    content: string\n  }\n  export declare const ChatCompletionResponseMessageRoleEnum: {\n    readonly System: 'system'\n    readonly User: 'user'\n    readonly Assistant: 'assistant'\n  }\n  export declare type ChatCompletionResponseMessageRoleEnum =\n    (typeof ChatCompletionResponseMessageRoleEnum)[keyof typeof ChatCompletionResponseMessageRoleEnum]\n  /**\n   *\n   * @export\n   * @interface CreateChatCompletionRequest\n   */\n  export interface CreateChatCompletionRequest {\n    /**\n     * ID of the model to use. Currently, only `gpt-3.5-turbo` and `gpt-3.5-turbo-0301` are supported.\n     * @type {string}\n     * @memberof CreateChatCompletionRequest\n     */\n    model: string\n    /**\n     * The messages to generate chat completions for, in the [chat format](/docs/guides/chat/introduction).\n     * @type {Array<ChatCompletionRequestMessage>}\n     * @memberof CreateChatCompletionRequest\n     */\n    messages: Array<ChatCompletionRequestMessage>\n    /**\n     * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.  We generally recommend altering this or `top_p` but not both.\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    temperature?: number | null\n    /**\n     * An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.  We generally recommend altering this or `temperature` but not both.\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    top_p?: number | null\n    /**\n     * How many chat completion choices to generate for each input message.\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    n?: number | null\n    /**\n     * If set, partial message deltas will be sent, like in ChatGPT. Tokens will be sent as data-only [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format) as they become available, with the stream terminated by a `data: [DONE]` message.\n     * @type {boolean}\n     * @memberof CreateChatCompletionRequest\n     */\n    stream?: boolean | null\n    /**\n     *\n     * @type {CreateChatCompletionRequestStop}\n     * @memberof CreateChatCompletionRequest\n     */\n    stop?: CreateChatCompletionRequestStop\n    /**\n     * The maximum number of tokens allowed for the generated answer. By default, the number of tokens the model can return will be (4096 - prompt tokens).\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    max_tokens?: number\n    /**\n     * Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model\\'s likelihood to talk about new topics.  [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details)\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    presence_penalty?: number | null\n    /**\n     * Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model\\'s likelihood to repeat the same line verbatim.  [See more information about frequency and presence penalties.](/docs/api-reference/parameter-details)\n     * @type {number}\n     * @memberof CreateChatCompletionRequest\n     */\n    frequency_penalty?: number | null\n    /**\n     * Modify the likelihood of specified tokens appearing in the completion.  Accepts a json object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token.\n     * @type {object}\n     * @memberof CreateChatCompletionRequest\n     */\n    logit_bias?: object | null\n    /**\n     * A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. [Learn more](/docs/guides/safety-best-practices/end-user-ids).\n     * @type {string}\n     * @memberof CreateChatCompletionRequest\n     */\n    user?: string\n  }\n  /**\n   * @type CreateChatCompletionRequestStop\n   * Up to 4 sequences where the API will stop generating further tokens.\n   * @export\n   */\n  export declare type CreateChatCompletionRequestStop = Array<string> | string\n  /**\n   *\n   * @export\n   * @interface CreateChatCompletionResponse\n   */\n  export interface CreateChatCompletionResponse {\n    /**\n     *\n     * @type {string}\n     * @memberof CreateChatCompletionResponse\n     */\n    id: string\n    /**\n     *\n     * @type {string}\n     * @memberof CreateChatCompletionResponse\n     */\n    object: string\n    /**\n     *\n     * @type {number}\n     * @memberof CreateChatCompletionResponse\n     */\n    created: number\n    /**\n     *\n     * @type {string}\n     * @memberof CreateChatCompletionResponse\n     */\n    model: string\n    /**\n     *\n     * @type {Array<CreateChatCompletionResponseChoicesInner>}\n     * @memberof CreateChatCompletionResponse\n     */\n    choices: Array<CreateChatCompletionResponseChoicesInner>\n    /**\n     *\n     * @type {CreateCompletionResponseUsage}\n     * @memberof CreateChatCompletionResponse\n     */\n    usage?: CreateCompletionResponseUsage\n  }\n  /**\n   *\n   * @export\n   * @interface CreateChatCompletionResponseChoicesInner\n   */\n  export interface CreateChatCompletionResponseChoicesInner {\n    /**\n     *\n     * @type {number}\n     * @memberof CreateChatCompletionResponseChoicesInner\n     */\n    index?: number\n    /**\n     *\n     * @type {ChatCompletionResponseMessage}\n     * @memberof CreateChatCompletionResponseChoicesInner\n     */\n    message?: ChatCompletionResponseMessage\n    /**\n     *\n     * @type {string}\n     * @memberof CreateChatCompletionResponseChoicesInner\n     */\n    finish_reason?: string\n  }\n  /**\n   *\n   * @export\n   * @interface CreateCompletionResponseUsage\n   */\n  export interface CreateCompletionResponseUsage {\n    /**\n     *\n     * @type {number}\n     * @memberof CreateCompletionResponseUsage\n     */\n    prompt_tokens: number\n    /**\n     *\n     * @type {number}\n     * @memberof CreateCompletionResponseUsage\n     */\n    completion_tokens: number\n    /**\n     *\n     * @type {number}\n     * @memberof CreateCompletionResponseUsage\n     */\n    total_tokens: number\n  }\n}\n"
  },
  {
    "path": "src/api/suno.ts",
    "content": "import { gptServerStore,homeStore,useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sunoStore,SunoMedia } from \"./sunoStore\";  \n\nconst getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    if(gptServerStore.myData.SUNO_SERVER){\n        if( gptServerStore.myData.SUNO_SERVER.indexOf('suno')>0 ) return `${ gptServerStore.myData.SUNO_SERVER}${url}`;\n\n        return `${ gptServerStore.myData.SUNO_SERVER}/suno${url}`;\n    }\n    return `/sunoapi${url}`;\n}\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.SUNO_KEY){\n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.SUNO_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\nexport function sleep(time: number) {\n  return new Promise((resolve) => setTimeout(resolve, time));\n}\nexport const lyricsFetch= async ( lid:string)=>{\n    for(let i=0;i<50;i++){\n        let dt:any = await sunoFetch(`/lyrics/${lid}`);\n        mlog(\"ddd\",dt )\n        let time= (i+1)\n        if(time>20) time=20;\n        if(dt.status=='complete') return dt ;\n        if( dt.status=='error') return null;\n        await sleep( time*1000 )\n        \n    }\n    return null;\n   \n}\n\nexport function randStyle(): string {\n    const s: string[] = [\"acoustic\", \"aggressive\", \"anthemic\", \"atmospheric\", \"bouncy\", \"chill\", \"dark\", \"dreamy\", \"electronic\", \"emotional\", \"epic\", \"experimental\", \"futuristic\", \"groovy\", \"heartfelt\", \"infectious\", \"melodic\", \"mellow\", \"powerful\", \"psychedelic\", \"romantic\", \"smooth\", \"syncopated\", \"uplifting\", \"\"];\n    const l: string[] = [\"afrobeat\", \"anime\", \"ballad\", \"bedroom pop\", \"bluegrass\", \"blues\", \"classical\", \"country\", \"cumbia\", \"dance\", \"dancepop\", \"delta blues\", \"electropop\", \"disco\", \"dream pop\", \"drum and bass\", \"edm\", \"emo\", \"folk\", \"funk\", \"future bass\", \"gospel\", \"grunge\", \"grime\", \"hip hop\", \"house\", \"indie\", \"j-pop\", \"jazz\", \"k-pop\", \"kids music\", \"metal\", \"new jack swing\", \"new wave\", \"opera\", \"pop\", \"punk\", \"raga\", \"rap\", \"reggae\", \"reggaeton\", \"rock\", \"rumba\", \"salsa\", \"samba\", \"sertanejo\", \"soul\", \"synthpop\", \"swing\", \"synthwave\", \"techno\", \"trap\", \"uk garage\"];\n    \n    const randomS: string = s[Math.floor(Math.random() * s.length)];\n    const randomL: string = l[Math.floor(Math.random() * l.length)];\n    // const randomS2: string = s[Math.floor(Math.random() * s.length)];\n    // const randomL2: string = l[Math.floor(Math.random() * l.length)];\n\n    return randomS + \" \" + randomL ;\n}\n\nexport const FeedTask= async (ids:string[])=>{\n    const sunoS = new sunoStore();\n    if(ids.length<=0) return;\n    \n    let d:any[] = await sunoFetch('/feed/'+ ids.join(','));\n    mlog('FeedTask',d )\n    d.forEach( (item:SunoMedia) =>{\n         sunoS.save( item)\n        if(item.status== \"complete\" || item.status== \"error\" ){\n            ids= ids.filter(v=>v!=item.id )\n        }\n    });\n    homeStore.setMyData({act:'FeedTask'});\n    await sleep(5*1020 );\n    FeedTask(ids)\n\n}\n\n\nexport const sunoFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('sunoFetch', url  );\n    let headers= {'Content-Type':'application/json'}\n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n"
  },
  {
    "path": "src/api/sunoStore.ts",
    "content": "import { ss } from '@/utils/storage'\n \nexport type SunoMedia = {\n    id: string;\n    video_url: string;\n    audio_url: string;\n    image_url: string;\n    image_large_url: string;\n    is_video_pending: boolean;\n    major_model_version: string;\n    model_name: string;\n    metadata: {\n        tags?: string;\n        prompt: string;\n        gpt_description_prompt?: string ;\n        audio_prompt_id?: string ;\n        history?: string ;\n        concat_history?: string ;\n        type: string;\n        duration: number;\n        refund_credits: boolean;\n        stream: boolean;\n        error_type?: string ;\n        error_message?: string ;\n    };\n    is_liked: boolean;\n    user_id: string;\n    display_name: string;\n    handle: string;\n    is_handle_updated: boolean;\n    is_trashed: boolean;\n    reaction?: any; // You might want to define a proper type for this\n    created_at: string;\n    status: string;\n    title: string;\n    play_count: number;\n    upvote_count: number;\n    is_public: boolean;\n};\nexport class sunoStore{\n  //private id: string;\n  private localKey='suno-store';\n  public save(obj:SunoMedia ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id== id )\n  }\n\n  public getObjs():SunoMedia[]{\n     const obj = ss.get( this.localKey ) as  undefined| SunoMedia[];\n     if(!obj) return [];\n     return obj;\n  }\n  public delete( obj:SunoMedia ){\n    if(!obj.id ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/udio.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\n//import { KlingTask, klingStore } from \"./klingStore\";\nimport { sleep } from \"./suno\";\nimport { udioStore, udioTask } from \"./udioStore\";\n\n\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.UDIO_KEY){ \n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.UDIO_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url; \n    const pro_prefix= ''; \n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.UDIO_SERVER  ){\n      \n        return `${ gptServerStore.myData.UDIO_SERVER}${pro_prefix}${url}`;\n    }\n    return `${pro_prefix}${url}`;\n}\n\n\nexport const udioFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('udioFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport const udioFeedTask= async(id:string)=>{\n    mlog('god >>',id ) \n    const sunoS = new udioStore();\n    for(let i=0;i<50;i++ ){\n        let d= await udioFetch('/udio/fetch/'+id )\n        // .then(d=>{\n        //     mlog('fetch',d , d.data.status )\n        //     if(d.data && d.data.status=='SUCCESS'){\n        //         return\n        //     }\n        // }).catch((e)=>mlog('error ',e  ))\n        if(d.data  ){\n            //mlog('ddd> ' ,  d.data.data );\n            if( d.data.data && d.data.data.songs){\n                for(let ab of d.data.data.songs ){\n                    let song= ab as udioTask\n                    song.status= d.data.status\n                    song.taskId= d.data.task_id\n                    song.failReason= d.data.fail_reason\n                    song.last_feed=new Date().getTime()\n                    sunoS.save( song)\n                    //mlog('d', song )\n                    homeStore.setMyData({act:'udio.feed'});\n                }\n\n            }\n            if(d.data.status=='SUCCESS' ) return\n        }\n        await sleep(5000)\n    }\n}\n"
  },
  {
    "path": "src/api/udioStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\nimport { mlog } from \"./mjapi\";\n\n\nexport interface udioTask {\n    // id: string;\n    // generationId: string;\n    // tags?: string[];\n    // title: string;\n    // artist: string;\n    // lyrics?: string;\n    // //prompt: string;\n    // //disliked: boolean;\n    // duration: number;\n    // finished: boolean;\n    // songPath: string;\n    // //userTags: string[];\n    // createdAt: string;\n    // // errorCode: string | null;\n    // // errorType: string | null;\n    // imagePath: string;\n    // //videoPath: string | null;\n    // // attribution: string;\n    // // description: string;\n    // //publishable: boolean;\n    // errorDetail?: string;\n    // artistImage: string;\n\n    id: string;\n    tags?: string[];\n    title: string;\n    //artist: string;\n    lyrics: string;\n    prompt: string;\n    //disliked: boolean;\n    duration: number;\n    finished: boolean;\n    song_path: string;\n    //user_tags: string[];\n    created_at: string; // ISO 8601 format\n    // error_code: string | null;\n    // error_type: string | null;\n    image_path: string;\n   // video_path?: string ;\n    attribution: string;\n    description: string;\n    publishable: boolean;\n    artist_image: string;\n    error_detail?: string  ;\n    generation_id: string;\n    audio_conditioning_type?:string\n\n    last_feed?: number //最后更新时间\n    status?:string\n    taskId?:string\n    failReason?:string\n}\n\nexport class udioStore{\n  //private id: string;\n  private localKey='udio-store';\n  public save(obj:udioTask ){\n    if(!obj.id ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.id==obj.id );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.id == id )\n  }\n\n  public getObjs():udioTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| udioTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):udioTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n  public delete( id:string ){ \n    let arr=  this.getObjs();\n    \n    let i= arr.findIndex( v=>v.id==id );\n    //mlog('ddd',i , arr)\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n}"
  },
  {
    "path": "src/api/units.ts",
    "content": "import { homeStore } from \"@/store\"\n\nexport const checkDisableGpt4=( model:string )=>{\n    if(!homeStore.myData.session.disableGpt4 || homeStore.myData.session.disableGpt4!='1') return false;\n    const rz =  model.indexOf('gpt-4')>-1 ;\n    if(rz){\n        homeStore.setMyData({isLoader:false,act:'stopLoading'}); \n    }\n    return rz ;\n\n}\n\nexport const isApikeyError=( text:string )=>{\n    text= text.toLocaleLowerCase();\n    if(\n    text.indexOf('error') && ( \n    text.indexOf('无效的令牌')>-1  //one-api 错误\n    || text.indexOf('incorrect api key')>-1  //原生\n    || text.indexOf('key error')>-1 \n    )) return true ;\n    return false;\n}\nexport const isAuthSessionError = ( text:string )=>{\n    text= text.toLocaleLowerCase();\n    if(text.indexOf('token_check')>-1  ) return true ;\n    return false; \n}"
  },
  {
    "path": "src/api/viggle.ts",
    "content": "import { gptServerStore, homeStore, useAuthStore } from \"@/store\";\nimport { mlog } from \"./mjapi\";\nimport { sleep } from \"./suno\";\nimport { ViggleTask, viggleStore } from \"./viggleStore\";\nimport { lumaHkStore } from \"./lumaStore\";\n\nfunction getHeaderAuthorization(){\n    let headers={}\n    if( homeStore.myData.vtoken ){\n        const  vtokenh={ 'x-vtoken':  homeStore.myData.vtoken ,'x-ctoken':  homeStore.myData.ctoken};\n        headers= {...headers, ...vtokenh}\n    }\n    if(!gptServerStore.myData.VIGGLE_KEY){\n        const authStore = useAuthStore()\n        if( authStore.token ) {\n            const bmi= { 'x-ptoken':  authStore.token };\n            headers= {...headers, ...bmi }\n            return headers;\n        }\n        return headers\n    }\n    const bmi={\n        'Authorization': 'Bearer ' +gptServerStore.myData.VIGGLE_KEY\n    }\n    headers= {...headers, ...bmi }\n    return headers\n}\n\nexport const  getUrl=(url:string)=>{\n    if(url.indexOf('http')==0) return url;\n    \n    const pro_prefix= url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''\n    url= url.replaceAll('/pro','')\n    if(gptServerStore.myData.VIGGLE_SERVER){\n        if(gptServerStore.myData.VIGGLE_SERVER.indexOf('/pro')>0){\n            return `${ gptServerStore.myData.VIGGLE_SERVER}/viggle${url}`;\n        }\n        return `${ gptServerStore.myData.VIGGLE_SERVER}${pro_prefix}/viggle${url}`;\n    }\n    return `${pro_prefix}/viggle${url}`;\n}\n\nexport interface tagInfo {\n    id: string;\n    name: string;\n    sort: number;\n}\nexport interface ViggleTemplate {\n    id: string;\n    processedURL: string;\n    processedHdURL: string;\n    processedCoverURL: string;\n    command?: string;\n    webCommand?: string;\n    description: string;\n    webStatus?: number;\n    dcStatus?: number;\n    appStatus?: number;\n    bgURL?: string;\n    bgCoverURL?: string;\n    displayURL?: string;\n    displayHdURL?: string;\n    displayCoverURL?: string;\n    gifURL?: string;\n    webPURL?: string;\n    source?: string;\n    sort?: number;\n    width?: number;\n    height?: number;\n}\n \nexport const viggleFetch=(url:string,data?:any,opt2?:any )=>{\n    mlog('viggleFetch', url  );\n    let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}\n     \n    if(opt2 && opt2.headers ) headers= opt2.headers;\n\n    headers={...headers,...getHeaderAuthorization()}\n   \n    return new Promise<any>((resolve, reject) => {\n        let opt:RequestInit ={method:'GET'};\n       \n        opt.headers= headers ;\n        if(opt2?.upFile ){\n             opt.method='POST';\n             opt.body=data as FormData ;\n        }\n        else if(data) {\n            opt.body= JSON.stringify(data) ;\n            opt.method='POST';\n        }\n        fetch(getUrl(url),  opt )\n        .then( async (d) =>{\n            if (!d.ok) { \n                let msg = '发生错误: '+ d.status\n                try{ \n                  let bjson:any  = await d.json();\n                  msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' ) \n                }catch( e ){ \n                }\n                homeStore.myData.ms &&  homeStore.myData.ms.error(msg )\n                throw new Error( msg );\n            }\n     \n            d.json().then(d=> resolve(d)).catch(e=>{ \n            \n                homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误'+ e )\n                reject(e) \n            }\n        )})\n        .catch(e=>{ \n            if (e.name === 'TypeError' && e.message === 'Failed to fetch') {\n                homeStore.myData.ms &&  homeStore.myData.ms.error('跨域|CORS error'  )\n            }\n            else homeStore.myData.ms &&  homeStore.myData.ms.error('发生错误:'+e )\n            mlog('e', e.stat )\n            reject(e)\n        })\n    })\n\n}\n\nexport  async function FeedViggleTask(id:string){  \n    const ss = new viggleStore()\n    const hk= new lumaHkStore();\n    const hkObj= hk.getOneById(id)\n    for(let i=0; i<500;i++){\n        let url= '/video-task/by-ids';\n        if(hkObj && hkObj.isHK ) url= '/pro/video-task/by-ids';\n        const d= await viggleFetch(url,{ids:[id]})\n        mlog('FeedViggleTask', d )\n       \n        if(d.data && d.data.length>0){\n            let task= d.data[0] as ViggleTask;\n            task.last_feed=new Date().getTime()\n            ss.save( task )\n            homeStore.setMyData({act:'FeedViggleTask'})\n            if ( d.data[0].status==0) return\n        }\n        await sleep(2000)\n    }\n\n}"
  },
  {
    "path": "src/api/viggleStore.ts",
    "content": "import { ss } from \"@/utils/storage\";\n\nexport interface ViggleTask {\n    taskID: string;\n    name: string;\n    status: number;\n    videoDuration: number;\n    bgMode: number;\n    modelInfoID: number;\n    optimize: boolean;\n    watermark: number;\n    freeCredits: number;\n    planCredits: number;\n    purchasedCredits: number;\n    mqType: number;\n    result: string;\n    resultCover: string;\n    createdAt: string;\n    last_feed:number;\n}\n\nexport class viggleStore{\n  //private id: string;\n  private localKey='viggle-store';\n  public save(obj:ViggleTask ){\n    if(!obj.taskID ) throw \"taskID must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.taskID==obj.taskID );\n    if(i>-1) arr[i]= obj;\n    else arr.push(obj);\n     ss.set(this.localKey, arr );\n    return this;\n  } \n  public findIndex(id:string){ \n    return this.getObjs().findIndex( v=>v.taskID== id )\n  }\n\n  public getObjs():ViggleTask[]{\n     const obj = ss.get( this.localKey ) as  undefined| ViggleTask[];\n     if(!obj) return [];\n     return obj;\n  }\n  public getOneById(id:string):ViggleTask|null{\n    const i= this.findIndex(id)\n    if(i<0) return null;\n    let arr=  this.getObjs();\n    return arr[i]\n  }\n\n   public delete( obj:ViggleTask ){\n    if(!obj.taskID ) throw \"id must\";\n    let arr=  this.getObjs();\n    let i= arr.findIndex( v=>v.taskID==obj.taskID );\n    if(i<0) return false\n    arr.splice(i, 1);\n    ss.set(this.localKey, arr );\n    return true;\n  }\n\n}"
  },
  {
    "path": "src/assets/recommend.json",
    "content": "[\n  {\n    \"key\": \"awesome-chatgpt-prompts-zh\",\n    \"desc\": \"ChatGPT 中文调教指南\",\n    \"downloadUrl\": \"https://raw.githubusercontent.com/PlexPt/awesome-chatgpt-prompts-zh/main/prompts-zh.json\",\n    \"url\": \"https://github.com/PlexPt/awesome-chatgpt-prompts-zh\"\n  },\n  {\n    \"key\": \"awesome-chatgpt-prompts-zh-TW\",\n    \"desc\": \"ChatGPT 中文調教指南 (透過 OpenAI / OpenCC 協助，從簡體中文轉換為繁體中文的版本)\",\n    \"downloadUrl\": \"https://raw.githubusercontent.com/PlexPt/awesome-chatgpt-prompts-zh/main/prompts-zh-TW.json\",\n    \"url\": \"https://github.com/PlexPt/awesome-chatgpt-prompts-zh\"\n  }\n]\n"
  },
  {
    "path": "src/components/common/HoverButton/Button.vue",
    "content": "<script setup lang='ts'>\ninterface Emit {\n  (e: 'click'): void\n}\n\nconst emit = defineEmits<Emit>()\n\nfunction handleClick() {\n  emit('click')\n}\n</script>\n\n<template>\n  <button\n    class=\"flex items-center justify-center w-10 h-10 transition rounded-full hover:bg-neutral-100 dark:hover:bg-[#414755]\"\n    @click=\"handleClick\"\n  >\n    <slot />\n  </button>\n</template>\n"
  },
  {
    "path": "src/components/common/HoverButton/index.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport type { PopoverPlacement } from 'naive-ui'\nimport { NTooltip } from 'naive-ui'\nimport Button from './Button.vue'\n\ninterface Props {\n  tooltip?: string\n  placement?: PopoverPlacement\n}\n\ninterface Emit {\n  (e: 'click'): void\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  tooltip: '',\n  placement: 'bottom',\n})\n\nconst emit = defineEmits<Emit>()\n\nconst showTooltip = computed(() => Boolean(props.tooltip))\n\nfunction handleClick() {\n  emit('click')\n}\n</script>\n\n<template>\n  <div v-if=\"showTooltip\">\n    <NTooltip :placement=\"placement\" trigger=\"hover\">\n      <template #trigger>\n        <Button @click=\"handleClick\">\n          <slot />\n        </Button>\n      </template>\n      {{ tooltip }}\n    </NTooltip>\n  </div>\n  <div v-else>\n    <Button @click=\"handleClick\">\n      <slot />\n    </Button>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/common/NaiveProvider/index.vue",
    "content": "<script setup lang=\"ts\">\nimport { defineComponent, h } from 'vue'\nimport {\n  NDialogProvider,\n  NLoadingBarProvider,\n  NMessageProvider,\n  NNotificationProvider,\n  useDialog,\n  useLoadingBar,\n  useMessage,\n  useNotification,\n} from 'naive-ui'\n\nfunction registerNaiveTools() {\n  window.$loadingBar = useLoadingBar()\n  window.$dialog = useDialog()\n  window.$message = useMessage()\n  window.$notification = useNotification()\n}\n\nconst NaiveProviderContent = defineComponent({\n  name: 'NaiveProviderContent',\n  setup() {\n    registerNaiveTools()\n  },\n  render() {\n    return h('div')\n  },\n})\n</script>\n\n<template>\n  <NLoadingBarProvider>\n    <NDialogProvider>\n      <NNotificationProvider>\n        <NMessageProvider>\n          <slot />\n          <NaiveProviderContent />\n        </NMessageProvider>\n      </NNotificationProvider>\n    </NDialogProvider>\n  </NLoadingBarProvider>\n</template>\n"
  },
  {
    "path": "src/components/common/PromptStore/index.vue",
    "content": "<script setup lang='ts'>\nimport type { DataTableColumns } from 'naive-ui'\nimport { computed, h, ref, watch } from 'vue'\nimport { NButton, NCard, NDataTable, NDivider, NInput, NList, NListItem, NModal, NPopconfirm, NSpace, NTabPane, NTabs, NThing, useMessage } from 'naive-ui'\nimport PromptRecommend from '../../../assets/recommend.json'\nimport { SvgIcon } from '..'\nimport { usePromptStore } from '@/store'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { t } from '@/locales'\n\ninterface DataProps {\n  renderKey: string\n  renderValue: string\n  key: string\n  value: string\n}\n\ninterface Props {\n  visible: boolean\n}\n\ninterface Emit {\n  (e: 'update:visible', visible: boolean): void\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits<Emit>()\n\nconst message = useMessage()\n\nconst show = computed({\n  get: () => props.visible,\n  set: (visible: boolean) => emit('update:visible', visible),\n})\n\nconst showModal = ref(false)\n\nconst importLoading = ref(false)\nconst exportLoading = ref(false)\n\nconst searchValue = ref<string>('')\n\n// 移动端自适应相关\nconst { isMobile } = useBasicLayout()\n\nconst promptStore = usePromptStore()\n\n// Prompt在线导入推荐List,根据部署者喜好进行修改(assets/recommend.json)\nconst promptRecommendList = PromptRecommend\nconst promptList = ref<any>(promptStore.promptList)\n\n// 用于添加修改的临时prompt参数\nconst tempPromptKey = ref('')\nconst tempPromptValue = ref('')\n\n// Modal模式，根据不同模式渲染不同的Modal内容\nconst modalMode = ref('')\n\n// 这个是为了后期的修改Prompt内容考虑，因为要针对无uuid的list进行修改，且考虑到不能出现标题和内容的冲突，所以就需要一个临时item来记录一下\nconst tempModifiedItem = ref<any>({})\n\n// 添加修改导入都使用一个Modal, 临时修改内容占用tempPromptKey,切换状态前先将内容都清楚\nconst changeShowModal = (mode: 'add' | 'modify' | 'local_import', selected = { key: '', value: '' }) => {\n  if (mode === 'add') {\n    tempPromptKey.value = ''\n    tempPromptValue.value = ''\n  }\n  else if (mode === 'modify') {\n    tempModifiedItem.value = { ...selected }\n    tempPromptKey.value = selected.key\n    tempPromptValue.value = selected.value\n  }\n  else if (mode === 'local_import') {\n    tempPromptKey.value = 'local_import'\n    tempPromptValue.value = ''\n  }\n  showModal.value = !showModal.value\n  modalMode.value = mode\n}\n\n// 在线导入相关\nconst downloadURL = ref('')\nconst downloadDisabled = computed(() => downloadURL.value.trim().length < 1)\nconst setDownloadURL = (url: string) => {\n  downloadURL.value = url\n}\n\n// 控制 input 按钮\nconst inputStatus = computed (() => tempPromptKey.value.trim().length < 1 || tempPromptValue.value.trim().length < 1)\n\n// Prompt模板相关操作\nconst addPromptTemplate = () => {\n  for (const i of promptList.value) {\n    if (i.key === tempPromptKey.value) {\n      message.error(t('store.addRepeatTitleTips'))\n      return\n    }\n    if (i.value === tempPromptValue.value) {\n      message.error(t('store.addRepeatContentTips', { msg: tempPromptKey.value }))\n      return\n    }\n  }\n  promptList.value.unshift({ key: tempPromptKey.value, value: tempPromptValue.value } as never)\n  message.success(t('common.addSuccess'))\n  changeShowModal('add')\n}\n\nconst modifyPromptTemplate = () => {\n  let index = 0\n\n  // 通过临时索引把待修改项摘出来\n  for (const i of promptList.value) {\n    if (i.key === tempModifiedItem.value.key && i.value === tempModifiedItem.value.value)\n      break\n    index = index + 1\n  }\n\n  const tempList = promptList.value.filter((_: any, i: number) => i !== index)\n\n  // 搜索有冲突的部分\n  for (const i of tempList) {\n    if (i.key === tempPromptKey.value) {\n      message.error(t('store.editRepeatTitleTips'))\n      return\n    }\n    if (i.value === tempPromptValue.value) {\n      message.error(t('store.editRepeatContentTips', { msg: i.key }))\n      return\n    }\n  }\n\n  promptList.value = [{ key: tempPromptKey.value, value: tempPromptValue.value }, ...tempList] as never\n  message.success(t('common.editSuccess'))\n  changeShowModal('modify')\n}\n\nconst deletePromptTemplate = (row: { key: string; value: string }) => {\n  promptList.value = [\n    ...promptList.value.filter((item: { key: string; value: string }) => item.key !== row.key),\n  ] as never\n  message.success(t('common.deleteSuccess'))\n}\n\nconst clearPromptTemplate = () => {\n  promptList.value = []\n  message.success(t('common.clearSuccess'))\n}\n\nconst importPromptTemplate = (from = 'online') => {\n  try {\n    const jsonData = JSON.parse(tempPromptValue.value)\n    let key = ''\n    let value = ''\n    // 可以扩展加入更多模板字典的key\n    if ('key' in jsonData[0]) {\n      key = 'key'\n      value = 'value'\n    }\n    else if ('act' in jsonData[0]) {\n      key = 'act'\n      value = 'prompt'\n    }\n    else {\n      // 不支持的字典的key防止导入 以免破坏prompt商店打开\n      message.warning('prompt key not supported.')\n      throw new Error('prompt key not supported.')\n    }\n\n    for (const i of jsonData) {\n      if (!(key in i) || !(value in i))\n        throw new Error(t('store.importError'))\n      let safe = true\n      for (const j of promptList.value) {\n        if (j.key === i[key]) {\n          message.warning(t('store.importRepeatTitle', { msg: i[key] }))\n          safe = false\n          break\n        }\n        if (j.value === i[value]) {\n          message.warning(t('store.importRepeatContent', { msg: i[key] }))\n          safe = false\n          break\n        }\n      }\n      if (safe)\n        promptList.value.unshift({ key: i[key], value: i[value] } as never)\n    }\n    message.success(t('common.importSuccess'))\n  }\n  catch {\n    message.error('JSON 格式错误，请检查 JSON 格式')\n  }\n  if (from === 'local')\n    showModal.value = !showModal.value\n}\n\n// 模板导出\nconst exportPromptTemplate = () => {\n  exportLoading.value = true\n  const jsonDataStr = JSON.stringify(promptList.value)\n  const blob = new Blob([jsonDataStr], { type: 'application/json' })\n  const url = URL.createObjectURL(blob)\n  const link = document.createElement('a')\n  link.href = url\n  link.download = 'ChatGPTPromptTemplate.json'\n  link.click()\n  URL.revokeObjectURL(url)\n  exportLoading.value = false\n}\n\n// 模板在线导入\nconst downloadPromptTemplate = async () => {\n  try {\n    importLoading.value = true\n    const response = await fetch(downloadURL.value)\n    const jsonData = await response.json()\n    if ('key' in jsonData[0] && 'value' in jsonData[0])\n      tempPromptValue.value = JSON.stringify(jsonData)\n    if ('act' in jsonData[0] && 'prompt' in jsonData[0]) {\n      const newJsonData = jsonData.map((item: { act: string; prompt: string }) => {\n        return {\n          key: item.act,\n          value: item.prompt,\n        }\n      })\n      tempPromptValue.value = JSON.stringify(newJsonData)\n    }\n    importPromptTemplate()\n    downloadURL.value = ''\n  }\n  catch {\n    message.error(t('store.downloadError'))\n    downloadURL.value = ''\n  }\n  finally {\n    importLoading.value = false\n  }\n}\n\n// 移动端自适应相关\nconst renderTemplate = () => {\n  const [keyLimit, valueLimit] = isMobile.value ? [10, 30] : [15, 50]\n\n  return promptList.value.map((item: { key: string; value: string }) => {\n    return {\n      renderKey: item.key.length <= keyLimit ? item.key : `${item.key.substring(0, keyLimit)}...`,\n      renderValue: item.value.length <= valueLimit ? item.value : `${item.value.substring(0, valueLimit)}...`,\n      key: item.key,\n      value: item.value,\n    }\n  })\n}\n\nconst pagination = computed(() => {\n  const [pageSize, pageSlot] = isMobile.value ? [6, 5] : [7, 15]\n  return {\n    pageSize, pageSlot,\n  }\n})\n\n// table相关\nconst createColumns = (): DataTableColumns<DataProps> => {\n  return [\n    {\n      title: t('store.title'),\n      key: 'renderKey',\n    },\n    {\n      title: t('store.description'),\n      key: 'renderValue',\n    },\n    {\n      title: t('common.action'),\n      key: 'actions',\n      width: 100,\n      align: 'center',\n      render(row) {\n        return h('div', { class: 'flex items-center flex-col gap-2' }, {\n          default: () => [h(\n            NButton,\n            {\n              tertiary: true,\n              size: 'small',\n              type: 'info',\n              onClick: () => changeShowModal('modify', row),\n            },\n            { default: () => t('common.edit') },\n          ),\n          h(\n            NButton,\n            {\n              tertiary: true,\n              size: 'small',\n              type: 'error',\n              onClick: () => deletePromptTemplate(row),\n            },\n            { default: () => t('common.delete') },\n          ),\n          ],\n        })\n      },\n    },\n  ]\n}\n\nconst columns = createColumns()\n\nwatch(\n  () => promptList,\n  () => {\n    promptStore.updatePromptList(promptList.value)\n  },\n  { deep: true },\n)\n\nconst dataSource = computed(() => {\n  const data = renderTemplate()\n  const value = searchValue.value\n  if (value && value !== '') {\n    return data.filter((item: DataProps) => {\n      return item.renderKey.includes(value) || item.renderValue.includes(value)\n    })\n  }\n  return data\n})\n</script>\n\n<template>\n  <NModal v-model:show=\"show\" style=\"width: 90%; max-width: 900px;\" preset=\"card\">\n    <div class=\"space-y-4\">\n      <NTabs type=\"segment\">\n        <NTabPane name=\"local\" :tab=\"$t('store.local')\">\n          <div\n            class=\"flex gap-3 mb-4\"\n            :class=\"[isMobile ? 'flex-col' : 'flex-row justify-between']\"\n          >\n            <div class=\"flex items-center space-x-4\">\n              <NButton\n                type=\"primary\"\n                size=\"small\"\n                @click=\"changeShowModal('add')\"\n              >\n                {{ $t('common.add') }}\n              </NButton>\n              <NButton\n                size=\"small\"\n                @click=\"changeShowModal('local_import')\"\n              >\n                {{ $t('common.import') }}\n              </NButton>\n              <NButton\n                size=\"small\"\n                :loading=\"exportLoading\"\n                @click=\"exportPromptTemplate()\"\n              >\n                {{ $t('common.export') }}\n              </NButton>\n              <NPopconfirm @positive-click=\"clearPromptTemplate\">\n                <template #trigger>\n                  <NButton size=\"small\">\n                    {{ $t('common.clear') }}\n                  </NButton>\n                </template>\n                {{ $t('store.clearStoreConfirm') }}\n              </NPopconfirm>\n            </div>\n            <div class=\"flex items-center\">\n              <NInput v-model:value=\"searchValue\" style=\"width: 100%\" />\n            </div>\n          </div>\n          <NDataTable\n            v-if=\"!isMobile\"\n            :max-height=\"400\"\n            :columns=\"columns\"\n            :data=\"dataSource\"\n            :pagination=\"pagination\"\n            :bordered=\"false\"\n          />\n          <NList v-if=\"isMobile\" style=\"max-height: 400px; overflow-y: auto;\">\n            <NListItem v-for=\"(item, index) of dataSource\" :key=\"index\">\n              <NThing :title=\"item.renderKey\" :description=\"item.renderValue\" />\n              <template #suffix>\n                <div class=\"flex flex-col items-center gap-2\">\n                  <NButton tertiary size=\"small\" type=\"info\" @click=\"changeShowModal('modify', item)\">\n                    {{ t('common.edit') }}\n                  </NButton>\n                  <NButton tertiary size=\"small\" type=\"error\" @click=\"deletePromptTemplate(item)\">\n                    {{ t('common.delete') }}\n                  </NButton>\n                </div>\n              </template>\n            </NListItem>\n          </NList>\n        </NTabPane>\n        <NTabPane name=\"download\" :tab=\"$t('store.online')\">\n          <p class=\"mb-4\">\n            {{ $t('store.onlineImportWarning') }}\n          </p>\n          <div class=\"flex items-center gap-4\">\n            <NInput v-model:value=\"downloadURL\" placeholder=\"\" />\n            <NButton\n              strong\n              secondary\n              :disabled=\"downloadDisabled\"\n              :loading=\"importLoading\"\n              @click=\"downloadPromptTemplate()\"\n            >\n              {{ $t('common.download') }}\n            </NButton>\n          </div>\n          <NDivider />\n          <div class=\"max-h-[360px] overflow-y-auto space-y-4\">\n            <NCard\n              v-for=\"info in promptRecommendList\"\n              :key=\"info.key\" :title=\"info.key\"\n              :bordered=\"true\"\n              embedded\n            >\n              <p\n                class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n                :title=\"info.desc\"\n              >\n                {{ info.desc }}\n              </p>\n              <template #footer>\n                <div class=\"flex items-center justify-end space-x-4\">\n                  <NButton text>\n                    <a\n                      :href=\"info.url\"\n                      target=\"_blank\"\n                    >\n                      <SvgIcon class=\"text-xl\" icon=\"ri:link\" />\n                    </a>\n                  </NButton>\n                  <NButton text @click=\"setDownloadURL(info.downloadUrl) \">\n                    <SvgIcon class=\"text-xl\" icon=\"ri:add-fill\" />\n                  </NButton>\n                </div>\n              </template>\n            </NCard>\n          </div>\n        </NTabPane>\n      </NTabs>\n    </div>\n  </NModal>\n\n  <NModal v-model:show=\"showModal\" style=\"width: 90%; max-width: 600px;\" preset=\"card\">\n    <NSpace v-if=\"modalMode === 'add' || modalMode === 'modify'\" vertical>\n      {{ t('store.title') }}\n      <NInput v-model:value=\"tempPromptKey\" />\n      {{ t('store.description') }}\n      <NInput v-model:value=\"tempPromptValue\" type=\"textarea\" />\n      <NButton\n        block\n        type=\"primary\"\n        :disabled=\"inputStatus\"\n        @click=\"() => { modalMode === 'add' ? addPromptTemplate() : modifyPromptTemplate() }\"\n      >\n        {{ t('common.confirm') }}\n      </NButton>\n    </NSpace>\n    <NSpace v-if=\"modalMode === 'local_import'\" vertical>\n      <NInput\n        v-model:value=\"tempPromptValue\"\n        :placeholder=\"t('store.importPlaceholder')\"\n        :autosize=\"{ minRows: 3, maxRows: 15 }\"\n        type=\"textarea\"\n      />\n      <NButton\n        block\n        type=\"primary\"\n        :disabled=\"inputStatus\"\n        @click=\"() => { importPromptTemplate('local') }\"\n      >\n        {{ t('common.import') }}\n      </NButton>\n    </NSpace>\n  </NModal>\n</template>\n"
  },
  {
    "path": "src/components/common/Setting/About.vue",
    "content": "<script setup lang='ts'>\nimport { computed, onMounted, ref } from 'vue'\nimport { NSpin } from 'naive-ui'\nimport pkg from '../../../../package.json'\nimport { fetchChatConfig ,getLastVersion} from '@/api'\nimport { useAuthStore } from '@/store'\nimport { gptUsage  } from \"@/api\";\n\ninterface ConfigState {\n  timeoutMs?: number\n  reverseProxy?: string\n  apiModel?: string\n  socksProxy?: string\n  httpsProxy?: string\n  usage?: string\n  remaining?: string\n  hard_limit_usd?: string\n}\n\nconst authStore = useAuthStore()\n\nconst loading = ref(false)\n\nconst config = ref<ConfigState>()\nconst st = ref({lastVersion:''})\n\nconst isChatGPTAPI = computed<boolean>(() => !!authStore.isChatGPTAPI)\n\nasync function fetchConfig() {\n  try {\n    loading.value = true\n    // const { data } = await fetchChatConfig<ConfigState>()\n    // config.value = data\n    \n\n    const dd= await gptUsage();\n    config.value= {usage:dd.usage?`${dd.usage}`:'-'\n      ,remaining:dd.remaining?`${dd.remaining}`:'-'\n      ,hard_limit_usd:dd.hard_limit_usd?`${dd.hard_limit_usd}`:'-'\n      , \"apiModel\": \"ChatGPTAPI\",\n        \"reverseProxy\": \"-\",\n        \"timeoutMs\": 100000,\n        \"socksProxy\": \"-\",\n        \"httpsProxy\": \"-\", } ;\n\n  }\n  finally {\n    loading.value = false\n  }\n}\nconst getLastFrom= ()=>{\n  const str = localStorage.getItem('lastVersion');\n  if(!str) return '';\n  const obj = JSON.parse(str);\n  if( Date.now()- obj.t>1000*60*60 ){\n    return '';\n  }\n  return obj.v;\n}\nonMounted( () => {\n  fetchConfig();\n  \n  let t = getLastFrom();\n  if(t){\n     st.value.lastVersion = t ;\n  }else {\n    getLastVersion().then(res=>{\n      if(  res[0] && res[0].name ){\n        st.value.lastVersion = res[0].name;\n        localStorage.setItem('lastVersion',JSON.stringify( {v:  res[0].name,t: Date.now() } ))\n      }\n    });\n  }\n})\nconst  isShow = computed(()=>{\n  return st.value.lastVersion && st.value.lastVersion != `v${pkg.version}`\n});\n</script>\n\n<template>\n  <NSpin :show=\"loading\">\n    <div class=\"p-4 space-y-4\">\n      <h2 class=\"text-xl font-bold\">\n        Version - {{ pkg.version }}\n        <a class=\"text-red-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\" target=\"_blank\" v-if=\" isShow  \"> ({{ $t('mj.findVersion') }} {{ st.lastVersion }})</a>\n        <a class=\"text-gray-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\" target=\"_blank\" v-else-if=\"st.lastVersion\"> ({{ $t('mj.yesLastVersion') }})</a>\n      </h2>\n      <div class=\"p-2 space-y-2 rounded-md bg-neutral-100 dark:bg-neutral-700\">\n        <p v-html=\"$t('mj.infoStar')\"></p>\n      </div>\n      <p>{{ $t(\"setting.api\") }}：{{ config?.apiModel ?? '-' }}</p>\n      <p v-if=\"isChatGPTAPI\" class=\" flex items-center justify-between\">\n        <div>\n        {{ $t(\"setting.monthlyUsage\") }}：{{ config?.usage ?? '-' }}\n        </div>\n        <div>\n        {{ $t(\"mj.totalUsage\") }}：{{ config?.hard_limit_usd ?(+config?.hard_limit_usd).toFixed(2): '-' }}\n        </div>\n        <div>\n        {{ $t(\"setting.balance\") }}：{{ config?.remaining ?? '-' }}\n        </div>\n      </p>\n      <p v-if=\"!isChatGPTAPI\">\n        {{ $t(\"setting.reverseProxy\") }}：{{ config?.reverseProxy ?? '-' }}\n      </p>\n       \n      <!-- <p>{{ $t(\"setting.timeout\") }}：{{ config?.timeoutMs ?? '-' }}</p>  -->\n      <!-- <p>{{ $t(\"setting.socks\") }}：{{ config?.socksProxy ?? '-' }}</p>\n      <p>{{ $t(\"setting.httpsProxy\") }}：{{ config?.httpsProxy ?? '-' }}</p> -->\n    </div>\n  </NSpin>\n</template>\n"
  },
  {
    "path": "src/components/common/Setting/Advanced.vue",
    "content": "<script lang=\"ts\" setup>\nimport { ref } from 'vue'\nimport { NButton, NInput, NSlider, useMessage } from 'naive-ui'\nimport { useSettingStore } from '@/store'\nimport type { SettingsState } from '@/store/modules/settings/helper'\nimport { t } from '@/locales'\n\nconst settingStore = useSettingStore()\n\nconst ms = useMessage()\n\nconst systemMessage = ref(settingStore.systemMessage ?? '')\n\nconst temperature = ref(settingStore.temperature ?? 0.5)\n\nconst top_p = ref(settingStore.top_p ?? 1)\n\nfunction updateSettings(options: Partial<SettingsState>) {\n  settingStore.updateSetting(options)\n  ms.success(t('common.success'))\n}\n\nfunction handleReset() {\n  settingStore.resetSetting()\n  ms.success(t('common.success'))\n  window.location.reload()\n}\n</script>\n\n<template>\n  <div class=\"p-4 space-y-5 min-h-[200px]\">\n    <div class=\"space-y-6\">\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[120px]\">{{ $t('setting.role') }}</span>\n        <div class=\"flex-1\">\n          <NInput v-model:value=\"systemMessage\" type=\"textarea\" :autosize=\"{ minRows: 1, maxRows: 4 }\" />\n        </div>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateSettings({ systemMessage })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[120px]\">{{ $t('setting.temperature') }} </span>\n        <div class=\"flex-1\">\n          <NSlider v-model:value=\"temperature\" :max=\"2\" :min=\"0\" :step=\"0.1\" />\n        </div>\n        <span>{{ temperature }}</span>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateSettings({ temperature })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[120px]\">{{ $t('setting.top_p') }} </span>\n        <div class=\"flex-1\">\n          <NSlider v-model:value=\"top_p\" :max=\"1\" :min=\"0\" :step=\"0.1\" />\n        </div>\n        <span>{{ top_p }}</span>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateSettings({ top_p })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[120px]\">&nbsp;</span>\n        <NButton size=\"small\" @click=\"handleReset\">\n          {{ $t('common.reset') }}\n        </NButton>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/common/Setting/General.vue",
    "content": "<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue'\nimport { NButton, NInput, NPopconfirm, NSelect, useMessage } from 'naive-ui'\nimport type { Language, Theme } from '@/store/modules/app/helper'\nimport { SvgIcon } from '@/components/common'\nimport { useAppStore, useUserStore } from '@/store'\nimport type { UserInfo } from '@/store/modules/user/helper'\nimport { getCurrentDate } from '@/utils/functions'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { t } from '@/locales'\nimport { getWebDAVConfig, saveWebDAVConfig, syncToWebDAV, syncFromWebDAV } from '@/utils/webdav'\n\nconst appStore = useAppStore()\nconst userStore = useUserStore()\n\nconst { isMobile } = useBasicLayout()\n\nconst ms = useMessage()\n\nconst theme = computed(() => appStore.theme)\n\nconst userInfo = computed(() => userStore.userInfo)\n\nconst avatar = ref(userInfo.value.avatar ?? '')\n\nconst name = ref(userInfo.value.name ?? '')\n\nconst description = ref(userInfo.value.description ?? '')\n\nconst backgroundImage = ref(userInfo.value.backgroundImage ?? '')\n\nconst webdavUrl = ref('')\nconst webdavUsername = ref('')\nconst webdavPassword = ref('')\nconst showWebDAVConfig = ref(false)\n\n// 加载 WebDAV 配置\nconst loadedConfig = getWebDAVConfig()\nif (loadedConfig) {\n  webdavUrl.value = loadedConfig.url\n  webdavUsername.value = loadedConfig.username\n  webdavPassword.value = loadedConfig.password\n}\n\nconst language = computed({\n  get() {\n    return appStore.language\n  },\n  set(value: Language) {\n    appStore.setLanguage(value)\n  },\n})\n\nconst themeOptions: { label: string; key: Theme; icon: string }[] = [\n  {\n    label: 'Auto',\n    key: 'auto',\n    icon: 'ri:contrast-line',\n  },\n  {\n    label: 'Light',\n    key: 'light',\n    icon: 'ri:sun-foggy-line',\n  },\n  {\n    label: 'Dark',\n    key: 'dark',\n    icon: 'ri:moon-foggy-line',\n  },\n]\n\nconst languageOptions: { label: string; key: Language; value: Language }[] = [\n  { label: '简体中文', key: 'zh-CN', value: 'zh-CN' },\n  { label: '繁體中文', key: 'zh-TW', value: 'zh-TW' },\n  { label: 'English', key: 'en-US', value: 'en-US' },\n  { label: '한국어', key: 'ko-KR', value: 'ko-KR' },\n  { label: 'Русский язык', key: 'ru-RU', value: 'ru-RU' },\n  { label: 'Tiếng Việt', key: 'vi-VN', value: 'vi-VN' },\n  { label: 'Français', key: 'fr-FR', value: 'fr-FR' },\n  { label: 'Türkçe', key: 'tr-TR', value: 'tr-TR' },\n]\n\nfunction updateUserInfo(options: Partial<UserInfo>) {\n  userStore.updateUserInfo(options)\n  ms.success(t('common.success'))\n}\n\nfunction handleReset() {\n  userStore.resetUserInfo()\n  ms.success(t('common.success'))\n  window.location.reload()\n}\n\nfunction exportData(): void {\n  const date = getCurrentDate()\n  const data: string = localStorage.getItem('chatStorage') || '{}'\n  const jsonString: string = JSON.stringify(JSON.parse(data), null, 2)\n  const blob: Blob = new Blob([jsonString], { type: 'application/json' })\n  const url: string = URL.createObjectURL(blob)\n  const link: HTMLAnchorElement = document.createElement('a')\n  link.href = url\n  link.download = `chat-store_${date}.json`\n  document.body.appendChild(link)\n  link.click()\n  document.body.removeChild(link)\n}\n\nfunction importData(event: Event): void {\n  const target = event.target as HTMLInputElement\n  if (!target || !target.files)\n    return\n\n  const file: File = target.files[0]\n  if (!file)\n    return\n\n  const reader: FileReader = new FileReader()\n  reader.onload = () => {\n    try {\n      const data = JSON.parse(reader.result as string)\n      localStorage.setItem('chatStorage', JSON.stringify(data))\n      ms.success(t('common.success'))\n      location.reload()\n    }\n    catch (error) {\n      ms.error(t('common.invalidFileFormat'))\n    }\n  }\n  reader.readAsText(file)\n}\n\nfunction clearData(): void {\n  localStorage.removeItem('chatStorage')\n  location.reload()\n}\n\nfunction handleImportButtonClick(): void {\n  const fileInput = document.getElementById('fileInput2') as HTMLElement\n  if (fileInput)   fileInput.click()\n}\n\nfunction saveWebDAV(): void {\n  if (!webdavUrl.value || !webdavUsername.value || !webdavPassword.value) {\n    ms.error(t('setting.webdavConfigError'))\n    return\n  }\n  saveWebDAVConfig({\n    url: webdavUrl.value,\n    username: webdavUsername.value,\n    password: webdavPassword.value,\n  })\n  ms.success(t('common.success'))\n  showWebDAVConfig.value = false\n}\n\nasync function testWebDAVConnection(): Promise<void> {\n  if (!webdavUrl.value || !webdavUsername.value || !webdavPassword.value) {\n    ms.error(t('setting.webdavConfigError'))\n    return\n  }\n  \n  const loading = ms.loading('正在测试连接...', { duration: 0 })\n  \n  try {\n    const url = new URL(webdavUrl.value.replace(/\\/$/, ''))\n    const rootUrl = `${url.origin}${url.pathname.split('/')[1] ? `/${url.pathname.split('/')[1]}/` : '/'}`\n    \n    const response = await fetch('/api/webdav-proxy', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        url: rootUrl,\n        method: 'PROPFIND',\n        username: webdavUsername.value,\n        password: webdavPassword.value,\n      }),\n    })\n    \n    const result = await response.json()\n    loading.destroy()\n    \n    if (result.success || result.status === 207)\n      ms.success('连接成功！')\n    else if (result.status === 401)\n      ms.error('认证失败，请检查用户名和密码')\n    else\n      ms.error(`连接失败: ${result.error || result.status}`)\n  }\n  catch (error: any) {\n    loading.destroy()\n    ms.error(`测试失败: ${error.message}`)\n  }\n}\n\nasync function handleUploadToWebDAV(): Promise<void> {\n  const config = getWebDAVConfig()\n  if (!config) {\n    ms.warning(t('setting.webdavNotConfigured'))\n    showWebDAVConfig.value = true\n    return\n  }\n  \n  const loading = ms.loading('上传中...', { duration: 0 })\n  \n  try {\n    await syncToWebDAV()\n    loading.destroy()\n    ms.success('已强制上传本地数据到云端')\n  }\n  catch (error: any) {\n    loading.destroy()\n    ms.error(`上传失败: ${error.message}`)\n  }\n}\n\nasync function handleDownloadFromWebDAV(): Promise<void> {\n  const config = getWebDAVConfig()\n  if (!config) {\n    ms.warning(t('setting.webdavNotConfigured'))\n    showWebDAVConfig.value = true\n    return\n  }\n  \n  const loading = ms.loading('下载中...', { duration: 0 })\n  \n  try {\n    await syncFromWebDAV()\n    loading.destroy()\n    ms.success('已从云端下载数据，页面即将刷新')\n    setTimeout(() => location.reload(), 1000)\n  }\n  catch (error: any) {\n    loading.destroy()\n    ms.error(`下载失败: ${error.message}`)\n  }\n}\n</script>\n\n<template>\n  <div class=\"p-4 space-y-5 min-h-[200px]\">\n    <div class=\"space-y-6\">\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.avatarLink') }}</span>\n        <div class=\"flex-1\">\n          <NInput v-model:value=\"avatar\" placeholder=\"\" />\n        </div>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateUserInfo({ avatar })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.name') }}</span>\n        <div class=\"w-[200px]\">\n          <NInput v-model:value=\"name\" placeholder=\"\" />\n        </div>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateUserInfo({ name })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.backgroundImage') }}</span>\n        <div class=\"w-[200px]\">\n          <NInput v-model:value=\"backgroundImage\" placeholder=\"\" />\n        </div>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateUserInfo({ backgroundImage })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.description') }}</span>\n        <div class=\"flex-1\">\n          <NInput v-model:value=\"description\" placeholder=\"\" />\n        </div>\n        <NButton size=\"tiny\" text type=\"primary\" @click=\"updateUserInfo({ description })\">\n          {{ $t('common.save') }}\n        </NButton>\n      </div>\n      <div\n        class=\"flex items-center space-x-4\"\n        :class=\"isMobile && 'items-start'\"\n      >\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.chatHistory') }}</span>\n\n        <div class=\"flex flex-wrap items-center gap-4\">\n          <NButton size=\"small\" @click=\"exportData\">\n            <template #icon>\n              <SvgIcon icon=\"ri:download-2-fill\" />\n            </template>\n            {{ $t('common.export') }}\n          </NButton>\n\n          <input id=\"fileInput2\" type=\"file\" style=\"display:none\" @change=\"importData\">\n          <NButton size=\"small\" @click=\"handleImportButtonClick\">\n            <template #icon>\n              <SvgIcon icon=\"ri:upload-2-fill\" />\n            </template>\n            {{ $t('common.import') }}\n          </NButton>\n\n          <NButton size=\"small\" type=\"success\" @click=\"handleUploadToWebDAV\">\n            <template #icon>\n              <SvgIcon icon=\"ri:cloud-fill\" />\n            </template>\n            {{ $t('setting.webdavUpload') }}\n          </NButton>\n\n          <NButton size=\"small\" type=\"warning\" @click=\"handleDownloadFromWebDAV\">\n            <template #icon>\n              <SvgIcon icon=\"ri:download-cloud-fill\" />\n            </template>\n            {{ $t('setting.webdavDownload') }}\n          </NButton>\n\n          <NPopconfirm placement=\"bottom\" @positive-click=\"clearData\">\n            <template #trigger>\n              <NButton size=\"small\">\n                <template #icon>\n                  <SvgIcon icon=\"ri:close-circle-line\" />\n                </template>\n                {{ $t('common.clear') }}\n              </NButton>\n            </template>\n            {{ $t('chat.clearHistoryConfirm') }}\n          </NPopconfirm>\n        </div>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.theme') }}</span>\n        <div class=\"flex flex-wrap items-center gap-4\">\n          <template v-for=\"item of themeOptions\" :key=\"item.key\">\n            <NButton\n              size=\"small\"\n              :type=\"item.key === theme ? 'primary' : undefined\"\n              @click=\"appStore.setTheme(item.key)\"\n            >\n              <template #icon>\n                <SvgIcon :icon=\"item.icon\" />\n              </template>\n            </NButton>\n          </template>\n        </div>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.language') }}</span>\n        <div class=\"flex flex-wrap items-center gap-4\">\n          <NSelect\n            style=\"width: 140px\"\n            :value=\"language\"\n            :options=\"languageOptions\"\n            @update-value=\"value => appStore.setLanguage(value)\"\n          />\n        </div>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.webdavSync') }}</span>\n        <NButton size=\"small\" @click=\"showWebDAVConfig = !showWebDAVConfig\">\n          {{ showWebDAVConfig ? $t('common.hide') : $t('setting.webdavConfig') }}\n        </NButton>\n      </div>\n      <div v-if=\"showWebDAVConfig\" class=\"space-y-4 pl-4 border-l-2\">\n        <div class=\"flex items-center space-x-4\">\n          <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.webdavUrl') }}</span>\n          <div class=\"flex-1\">\n            <NInput v-model:value=\"webdavUrl\" placeholder=\"https://dav.example.com/remote.php/dav/files/username/\" />\n          </div>\n        </div>\n        <div class=\"flex items-center space-x-4\">\n          <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.webdavUsername') }}</span>\n          <div class=\"flex-1\">\n            <NInput v-model:value=\"webdavUsername\" placeholder=\"\" />\n          </div>\n        </div>\n        <div class=\"flex items-center space-x-4\">\n          <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.webdavPassword') }}</span>\n          <div class=\"flex-1\">\n            <NInput v-model:value=\"webdavPassword\" type=\"password\" placeholder=\"\" />\n          </div>\n        </div>\n        <div class=\"flex items-center space-x-4\">\n          <span class=\"flex-shrink-0 w-[100px]\"></span>\n          <NButton size=\"small\" type=\"primary\" @click=\"saveWebDAV\">\n            {{ $t('common.save') }}\n          </NButton>\n          <NButton size=\"small\" @click=\"testWebDAVConnection\">\n            {{ $t('setting.webdavTest') }}\n          </NButton>\n        </div>\n      </div>\n      <div class=\"flex items-center space-x-4\">\n        <span class=\"flex-shrink-0 w-[100px]\">{{ $t('setting.resetUserInfo') }}</span>\n        <NButton size=\"small\" @click=\"handleReset\">\n          {{ $t('common.reset') }}\n        </NButton>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/common/Setting/index.vue",
    "content": "<script setup lang='ts'>\nimport { computed, ref } from 'vue'\nimport { NModal, NTabPane, NTabs } from 'naive-ui'\nimport General from './General.vue'\nimport Advanced from './Advanced.vue'\nimport aiModel from '@/views/mj/aiModel.vue'\nimport aiSetServer from '@/views/mj/aiSetServer.vue'\nimport About from './About.vue'\nimport { homeStore, useAuthStore } from '@/store'\nimport { SvgIcon } from '@/components/common'\n\ninterface Props {\n  visible: boolean\n}\n\ninterface Emit {\n  (e: 'update:visible', visible: boolean): void\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits<Emit>()\n\nconst authStore = useAuthStore()\n\nconst isChatGPTAPI = computed<boolean>(() => !!authStore.isChatGPTAPI)\n\nconst active = ref('General')\n\nconst show = computed({\n  get() {\n    return props.visible\n  },\n  set(visible: boolean) {\n    emit('update:visible', visible)\n  },\n})\n</script>\n\n<template>\n  <NModal v-model:show=\"show\" :auto-focus=\"false\" preset=\"card\" style=\"width: 95%; max-width: 640px\">\n    <div>\n      <NTabs v-model:value=\"active\" type=\"line\" animated>\n        <NTabPane name=\"General\" tab=\"General\">\n          <template #tab>\n            <SvgIcon class=\"text-lg\" icon=\"ri:file-user-line\" />\n            <span class=\"ml-2\">{{ $t('setting.general') }}</span>\n          </template>\n          <div class=\"min-h-[100px]\">\n            <General />\n          </div>\n        </NTabPane>\n        <NTabPane v-if=\"isChatGPTAPI\" name=\"Advanced\" tab=\"Advanced\">\n          <template #tab>\n            <SvgIcon class=\"text-lg\" icon=\"ri:equalizer-line\" />\n            <!-- <span class=\"ml-2\">{{ $t('setting.advanced') }}</span> -->\n            <span class=\"ml-2\">{{ $t('mjset.model') }}</span>\n          </template>\n          <div class=\"min-h-[100px]\">\n            <!-- <Advanced /> -->\n            <aiModel/>\n          </div>\n        </NTabPane>\n\n        <NTabPane name=\"server\" tab=\"server\" v-if=\" ! homeStore.myData.session.isHideServer\">\n          <template #tab>\n            <SvgIcon class=\"text-lg\" icon=\"mingcute:server-line\" />\n            <span class=\"ml-2\">{{ $t('mjset.server') }}</span>\n          </template>\n          <aiSetServer />\n        </NTabPane>\n        <NTabPane name=\"Config\" tab=\"Config\">\n          <template #tab>\n            <SvgIcon class=\"text-lg\" icon=\"ri:list-settings-line\" />\n            <!-- <span class=\"ml-2\">{{ $t('setting.config') }}</span> -->\n            <span class=\"ml-2\">{{ $t('mjset.about') }}</span>\n          </template>\n          <About />\n        </NTabPane>\n\n      </NTabs>\n    </div>\n  </NModal>\n</template>\n"
  },
  {
    "path": "src/components/common/SvgIcon/index.vue",
    "content": "<script setup lang='ts'>\nimport { computed, useAttrs } from 'vue'\nimport { Icon } from '@iconify/vue'\n\ninterface Props {\n  icon?: string\n}\n\ndefineProps<Props>()\n\nconst attrs = useAttrs()\n\nconst bindAttrs = computed<{ class: string; style: string }>(() => ({\n  class: (attrs.class as string) || '',\n  style: (attrs.style as string) || '',\n}))\n</script>\n\n<template>\n  <Icon :icon=\"icon\" v-bind=\"bindAttrs\" />\n</template>\n"
  },
  {
    "path": "src/components/common/UserAvatar/index.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport { NAvatar } from 'naive-ui'\nimport { useUserStore } from '@/store'\nimport defaultAvatar from '@/assets/avatar.jpg'\nimport { isString } from '@/utils/is'\n\nconst userStore = useUserStore()\n\nconst userInfo = computed(() => userStore.userInfo)\n</script>\n\n<template>\n  <div class=\"flex items-center overflow-hidden\">\n    <div class=\"w-10 h-10 overflow-hidden rounded-full shrink-0\">\n      <template v-if=\"isString(userInfo.avatar) && userInfo.avatar.length > 0\">\n        <NAvatar\n          size=\"large\"\n          round\n          :src=\"userInfo.avatar\"\n          :fallback-src=\"defaultAvatar\"\n        />\n      </template>\n      <template v-else>\n        <NAvatar size=\"large\" round :src=\"defaultAvatar\" />\n      </template>\n    </div>\n    <div class=\"flex-1 min-w-0 ml-2\">\n      <h2 class=\"overflow-hidden font-bold text-md text-ellipsis whitespace-nowrap\">\n        {{ userInfo.name ?? 'AI绘图' }}\n      </h2>\n      <p class=\"overflow-hidden text-xs text-gray-500 text-ellipsis whitespace-nowrap\">\n        <span\n          v-if=\"isString(userInfo.description) && userInfo.description !== ''\"\n          v-html=\"userInfo.description\"\n        />\n      </p>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/common/index.ts",
    "content": "import HoverButton from './HoverButton/index.vue'\nimport NaiveProvider from './NaiveProvider/index.vue'\nimport SvgIcon from './SvgIcon/index.vue'\nimport UserAvatar from './UserAvatar/index.vue'\nimport Setting from './Setting/index.vue'\nimport PromptStore from './PromptStore/index.vue'\n\nexport { HoverButton, NaiveProvider, SvgIcon, UserAvatar, Setting, PromptStore }\n"
  },
  {
    "path": "src/components/custom/GithubSite.vue",
    "content": "<template>\n  <div class=\"text-neutral-400\">\n    <span>Star on</span>\n    <a href=\"https://github.com/Chanzhaoyu/chatgpt-bot\" target=\"_blank\" class=\"text-blue-500\">\n      GitHub\n    </a>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/custom/index.ts",
    "content": "import GithubSite from './GithubSite.vue'\n\nexport { GithubSite }\n"
  },
  {
    "path": "src/hooks/useBasicLayout.ts",
    "content": "import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'\n\nexport function useBasicLayout() {\n  const breakpoints = useBreakpoints(breakpointsTailwind)\n  const isMobile = breakpoints.smaller('sm')\n\n  return { isMobile }\n}\n"
  },
  {
    "path": "src/hooks/useIconRender.ts",
    "content": "import { h } from 'vue'\nimport { SvgIcon } from '@/components/common'\n\nexport const useIconRender = () => {\n  interface IconConfig {\n    icon?: string\n    color?: string\n    fontSize?: number\n  }\n\n  interface IconStyle {\n    color?: string\n    fontSize?: string\n  }\n\n  const iconRender = (config: IconConfig) => {\n    const { color, fontSize, icon } = config\n\n    const style: IconStyle = {}\n\n    if (color)\n      style.color = color\n\n    if (fontSize)\n      style.fontSize = `${fontSize}px`\n\n    if (!icon)\n      window.console.warn('iconRender: icon is required')\n\n    return () => h(SvgIcon, { icon, style })\n  }\n\n  return {\n    iconRender,\n  }\n}\n"
  },
  {
    "path": "src/hooks/useLanguage.ts",
    "content": "import { computed } from 'vue'\nimport { enUS, koKR, zhCN, zhTW } from 'naive-ui'\nimport { useAppStore } from '@/store'\nimport { setLocale } from '@/locales'\n\nexport function useLanguage() {\n  const appStore = useAppStore()\n\n  const language = computed(() => {\n    switch (appStore.language) {\n      case 'en-US':\n        setLocale('en-US')\n        return enUS\n      case 'ru-RU':\n        setLocale('ru-RU')\n        return enUS\n      case 'ko-KR':\n        setLocale('ko-KR')\n        return koKR\n      case 'zh-CN':\n        setLocale('zh-CN')\n        return zhCN\n      case 'zh-TW':\n        setLocale('zh-TW')\n        return zhTW\n      case 'vi-VN':\n        setLocale('vi-VN')\n        return zhTW\n      case 'fr-FR':\n        setLocale('fr-FR')\n        return enUS\n      case 'tr-TR':\n        setLocale('tr-TR')\n        return enUS  \n      default:\n        setLocale('zh-CN')\n        return zhCN\n    }\n  })\n\n  return { language }\n}\n"
  },
  {
    "path": "src/hooks/useTheme.ts",
    "content": "import type { GlobalThemeOverrides } from 'naive-ui'\nimport { computed, watch } from 'vue'\nimport { darkTheme, useOsTheme } from 'naive-ui'\nimport { useAppStore } from '@/store'\n\nexport function useTheme() {\n  const appStore = useAppStore()\n\n  const OsTheme = useOsTheme()\n\n  const isDark = computed(() => {\n    if (appStore.theme === 'auto')\n      return OsTheme.value === 'dark'\n    else\n      return appStore.theme === 'dark'\n  })\n\n  const theme = computed(() => {\n    return isDark.value ? darkTheme : undefined\n  })\n\n  const themeOverrides = computed<GlobalThemeOverrides>(() => {\n    if (isDark.value) {\n      return {\n        common: {},\n      }\n    }\n    return {}\n  })\n\n  watch(\n    () => isDark.value,\n    (dark) => {\n      if (dark)\n        document.documentElement.classList.add('dark')\n      else\n        document.documentElement.classList.remove('dark')\n    },\n    { immediate: true },\n  )\n\n  return { theme, themeOverrides }\n}\n"
  },
  {
    "path": "src/icons/403.vue",
    "content": "<template>\n  <div class=\"text-[#142D6E] dark:text-[#3a71ff]\">\n    <svg viewBox=\"0 0 400 300\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><mask id=\"a\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"31\" y=\"31\" width=\"338\" height=\"238\"><path d=\"M368.9 31H31v238h337.9V31Z\" fill=\"#fff\" /></mask><g mask=\"url(#a)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\"><path d=\"m357.4 219.2 3.4-39.3-58.7-5.1-3.4 39.3 58.7 5.1Z\" fill=\"#fff\" /><path d=\"M299.4 213.9h-.4v-.4l-.5-.1v.9l.8.1.1-.5ZM355.5 218.8l-1.3-.1v.5l1.3.1v-.5ZM353 218.5l-1.3-.1v.5l1.3.1v-.5ZM350.4 218.3l-1.3-.1v.5l1.3.1v-.5ZM347.9 218.1l-1.3-.1v.5l1.3.1v-.5ZM345.4 217.9l-1.3-.1v.5l1.3.1v-.5ZM342.8 217.6l-1.3-.1v.5l1.3.1v-.5ZM340.3 217.4l-1.3-.1v.5l1.3.1v-.5ZM337.7 217.2l-1.3-.1v.5l1.3.1v-.5ZM335.2 217l-1.3-.1v.5l1.3.1v-.5ZM332.7 216.8l-1.3-.1v.5l1.3.1v-.5ZM330.1 216.5l-1.3-.1v.5l1.3.1v-.5ZM327.6 216.3l-1.3-.1v.5l1.3.1v-.5ZM325.1 216.1l-1.3-.1v.5l1.3.1v-.5ZM322.5 215.9l-1.3-.1v.5l1.3.1v-.5ZM320 215.7l-1.3-.1v.5l1.3.1v-.5ZM317.5 215.4l-1.3-.1v.5l1.3.1v-.5ZM314.9 215.2l-1.3-.1v.5l1.3.1v-.5ZM312.4 215l-1.3-.1v.5l1.3.1v-.5ZM309.8 214.8l-1.3-.1v.5l1.3.1v-.5ZM307.3 214.6l-1.3-.1v.5l1.3.1v-.5ZM304.8 214.3l-1.3-.1v.5l1.3.1v-.5ZM302.2 214.1l-1.3-.1v.5l1.3.1v-.5ZM357.7 218.6l-.4-.1-.1.4h-.4v.5h.9v-.8ZM357.9 216h-.5l-.1 1.2.5.1.1-1.3ZM358.1 213.7h-.5l-.1 1.2h.5l.1-1.2ZM358.3 211.2h-.5l-.1 1.2h.5l.1-1.2ZM358.6 208.8h-.5l-.1 1.2h.5l.1-1.2ZM358.8 206.3h-.5l-.1 1.2h.5l.1-1.2ZM359 203.9h-.5l-.1 1.2h.5l.1-1.2ZM359.2 201.4h-.5l-.1 1.2h.5l.1-1.2ZM359.4 199h-.5l-.1 1.2h.5l.1-1.2ZM359.6 196.5h-.5l-.1 1.2h.5l.1-1.2ZM359.8 194.1h-.5l-.1 1.2h.5l.1-1.2ZM360 191.6h-.5l-.1 1.2h.5l.1-1.2ZM360.2 189.1h-.5l-.1 1.2h.5l.1-1.2ZM360.4 186.7h-.5l-.1 1.2h.5l.1-1.2ZM360.6 184.2h-.5l-.1 1.2h.5l.1-1.2ZM360.8 181.8h-.5l-.1 1.2h.5l.1-1.2ZM361 179.7l-.8-.1-.1.5h.4v.4h.5v-.8ZM358.9 179.5l-1.3-.1v.5l1.3.1v-.5ZM356.3 179.3l-1.3-.1v.5l1.3.1v-.5ZM353.8 179l-1.3-.1v.5l1.3.1v-.5ZM351.2 178.8l-1.3-.1v.5l1.3.1v-.5ZM348.7 178.6l-1.3-.1v.5l1.3.1v-.5ZM346.2 178.4l-1.3-.1v.5l1.3.1v-.5ZM343.6 178.1l-1.3-.1v.5l1.3.1v-.5ZM341.1 177.9l-1.3-.1v.5l1.3.1v-.5ZM338.6 177.7l-1.3-.1v.5l1.3.1v-.5ZM336 177.5l-1.3-.1v.5l1.3.1v-.5ZM333.5 177.3l-1.3-.1v.5l1.3.1v-.5ZM330.9 177l-1.3-.1v.5l1.3.1v-.5ZM328.4 176.8l-1.3-.1v.5l1.3.1v-.5ZM325.9 176.6l-1.3-.1v.5l1.3.1v-.5ZM323.3 176.4l-1.3-.1v.5l1.3.1v-.5ZM320.6 176.2l-1.3-.1.2.5 1.3.1-.2-.5ZM318.3 175.9l-1.3-.1v.5l1.3.1v-.5ZM315.7 175.7l-1.3-.1v.5l1.3.1v-.5ZM313.2 175.5l-1.3-.1v.5l1.3.1v-.5ZM310.7 175.3l-1.3-.1v.5l1.3.1v-.5ZM308.1 175.1l-1.3-.1v.5l1.3.1v-.5ZM305.6 174.8l-1.3-.1v.5l1.3.1v-.5ZM302.3 175.1h.4v-.5h-.9v.8l.4.1.1-.4ZM299.2 211.1h-.5l-.1 1.2h.5l.1-1.2ZM299.4 208.6h-.5l-.1 1.2h.5l.1-1.2ZM299.6 206.2h-.5l-.1 1.2h.5l.1-1.2ZM299.8 203.7h-.5l-.1 1.2h.5l.1-1.2ZM300 201.3h-.5l-.1 1.2h.5l.1-1.2ZM300.3 198.8h-.5l-.1 1.2h.5l.1-1.2ZM300.5 196.3h-.5l-.1 1.2h.5l.1-1.2ZM300.7 193.9h-.5l-.1 1.2h.5l.1-1.2ZM300.9 191.4h-.5l-.1 1.2h.5l.1-1.2ZM301.1 189h-.5l-.1 1.2h.5l.1-1.2ZM301.3 186.5h-.5l-.1 1.2h.5l.1-1.2ZM301.5 184.1h-.5l-.1 1.2h.5l.1-1.2ZM301.7 181.6h-.5l-.1 1.2h.5l.1-1.2ZM301.9 179.2h-.5l-.1 1.2h.5l.1-1.2ZM302.1 176.7h-.5l-.1 1.2h.5l.1-1.2Z\" fill=\"#DBDBDB\" /><path d=\"m355.2 216.5 2.9-34.4-53.8-4.6-2.9 34.4 53.8 4.6Z\" fill=\"#EBEBEB\" /><path d=\"M333.895 197.096c.2-2.5-1.7-4.7-4.2-4.9-2.5-.2-4.7 1.7-4.9 4.2-.2 2.5 1.7 4.7 4.2 4.9 2.5.2 4.7-1.7 4.9-4.2Zm-7.79-.491c-.1 1.8 1.3 3.4 3.1 3.5 1.8.1 3.4-1.2 3.5-3 .1-1.9-1.3-3.5-3.1-3.6-1.8-.1-3.4 1.3-3.5 3.1Z\" fill=\"#DBDBDB\" /><path d=\"m316.8 195.802.4.5c3.6 4.2 7.5 6.5 11.7 6.8l.7.1c6.8.1 11.6-4.9 11.8-5.1l.4-.4-.3-.4c-.2-.2-4.2-5.9-10.9-6.8-4.4-.6-8.9 1.1-13.3 4.9l-.5.4Zm12.8 5.999c5.2.1 9.2-3.1 10.4-4.3-1.1-1.3-4.6-5.2-9.7-5.8-3.7-.5-7.7.9-11.7 4.2 3.4 3.8 7.1 5.8 11 5.9Z\" fill=\"#DBDBDB\" /><path d=\"m320.004 205.586 19.368-16.587-.846-.988-19.367 16.588.845.987Z\" fill=\"#DBDBDB\" /><path d=\"m368.8 128.1-7.5-15.8-34-13.2-22.9 58.9 45.9 17.7 18.5-47.6Z\" fill=\"#fff\" /><path d=\"m350.4 175.6-1.2-.5-.2.4 1.2.5.2-.4ZM351.3 174l-.4-.2-.5 1.2.4.2.5-1.2ZM348.1 174.6l-1.2-.5-.2.4 1.2.5.2-.4ZM345.7 173.8l-1.2-.5-.2.4 1.2.5.2-.4ZM343.4 172.8l-1.2-.5-.2.4 1.2.5.2-.4ZM352.2 171.7l-.4-.2-.5 1.2.4.2.5-1.2ZM341 171.9l-1.2-.5-.2.4 1.2.5.2-.4ZM338.6 171l-1.2-.5-.2.4 1.2.5.2-.4ZM353.1 169.3l-.4-.2-.5 1.2.4.2.5-1.2ZM336.2 170.1l-1.2-.5-.2.4 1.2.5.2-.4ZM333.9 169.1l-1.2-.5-.2.4 1.2.5.2-.4ZM331.5 168.2l-1.2-.5-.2.4 1.2.5.2-.4ZM354 167l-.4-.2-.5 1.2.4.2.5-1.2ZM329.1 167.3l-1.2-.5-.2.4 1.2.5.2-.4ZM326.8 166.4l-1.2-.5-.2.4 1.2.5.2-.4ZM324.4 165.5l-1.2-.5-.2.4 1.2.5.2-.4ZM354.9 164.6l-.4-.2-.5 1.2.4.2.5-1.2ZM322.1 164.6l-1.2-.5-.2.4 1.2.5.2-.4ZM319.7 163.6l-1.2-.5-.2.4 1.2.5.2-.4ZM355.8 162.2l-.4-.2-.5 1.2.4.2.5-1.2ZM317.3 162.7l-1.2-.5-.2.4 1.2.5.2-.4ZM315 161.8l-1.2-.5-.2.4 1.2.5.2-.4ZM312.6 160.9l-1.2-.5-.2.4 1.2.5.2-.4ZM356.8 159.8l-.4-.2-.5 1.2.4.2.5-1.2ZM310.2 160l-1.2-.5-.2.4 1.2.5.2-.4ZM307.9 159.1l-1.2-.5-.2.4 1.2.5.2-.4ZM357.7 157.5l-.4-.2-.5 1.2.4.2.5-1.2ZM305.4 158l-.7-.3-.4-.2-.2.5 1.2.5.1-.5ZM305.7 155.4l-.4-.2-.5 1.2.4.2.5-1.2ZM358.6 155.1l-.4-.2-.5 1.2.4.2.5-1.2ZM306.6 153.1l-.4-.2-.5 1.2.4.2.5-1.2ZM359.5 152.8l-.4-.2-.5 1.2.4.2.5-1.2ZM307.5 150.7l-.4-.2-.5 1.2.4.2.5-1.2ZM360.4 150.4l-.4-.2-.5 1.2.4.2.5-1.2ZM308.5 148.3l-.4-.2-.5 1.2.4.2.5-1.2ZM361.3 148l-.4-.2-.5 1.2.4.2.5-1.2ZM309.4 146l-.4-.2-.5 1.2.4.2.5-1.2ZM362.3 145.7l-.4-.2-.5 1.2.4.2.5-1.2ZM310.3 143.6l-.4-.2-.5 1.2.4.2.5-1.2ZM363.2 143.3l-.4-.2-.5 1.2.4.2.5-1.2ZM311.2 141.2l-.4-.2-.5 1.2.4.2.5-1.2ZM364.1 140.9l-.4-.2-.5 1.2.4.2.5-1.2ZM312.1 138.9l-.4-.2-.5 1.2.4.2.5-1.2ZM365 138.6l-.4-.2-.5 1.2.4.2.5-1.2ZM313 136.5l-.4-.2-.5 1.2.4.2.5-1.2ZM365.9 136.2l-.4-.2-.5 1.2.4.2.5-1.2ZM314 134.1l-.4-.2-.5 1.2.4.2.5-1.2ZM366.9 133.8l-.4-.2-.5 1.2.4.2.5-1.2ZM314.9 131.8l-.4-.2-.5 1.2.4.2.5-1.2ZM367.8 131.5l-.4-.2-.5 1.2.4.2.5-1.2ZM315.8 129.4l-.4-.2-.5 1.2.4.2.5-1.2ZM368.7 129.1l-.4-.2-.5 1.2.4.2.5-1.2ZM316.7 127l-.4-.2-.5 1.2.4.2.5-1.2ZM368.9 127.8l-.5-1.1-.4.2.5 1.1.4-.2ZM317.6 124.7l-.4-.2-.5 1.2.4.2.5-1.2ZM367.8 125.5l-.5-1.1-.4.2.5 1.1.4-.2ZM318.4 122.3l-.4-.2-.4 1.2.4.2.4-1.2ZM366.7 123.2l-.5-1.1-.4.2.5 1.1.4-.2ZM319.5 119.9l-.4-.2-.5 1.2.4.2.5-1.2ZM365.7 120.9l-.5-1.1-.4.2.5 1.1.4-.2ZM364.6 118.6l-.5-1.1-.4.2.5 1.1.4-.2ZM320.4 117.6l-.4-.2-.5 1.2.4.2.5-1.2ZM363.5 116.3l-.5-1.1-.4.2.5 1.1.4-.2ZM321.3 115.2l-.4-.2-.5 1.2.4.2.5-1.2ZM362.4 114l-.5-1.1-.4.2.5 1.1.4-.2ZM322.2 112.8l-.4-.2-.5 1.2.4.2.5-1.2ZM361 111.9l-1.2-.5-.2.4 1.2.5.2-.4ZM323.1 110.5l-.4-.2-.5 1.2.4.2.5-1.2ZM358.6 111l-1.2-.5-.2.4 1.2.5.2-.4ZM356.3 110l-1.2-.5-.2.4 1.2.5.2-.4ZM353.9 109.1l-1.2-.5-.2.4 1.2.5.2-.4ZM324.1 108.1l-.4-.2-.5 1.2.4.2.5-1.2ZM351.5 108.2l-1.2-.5-.2.4 1.2.5.2-.4ZM349.2 107.3l-1.2-.5-.2.4 1.2.5.2-.4ZM325 105.7l-.4-.2-.5 1.2.4.2.5-1.2ZM346.8 106.4l-1.2-.5-.2.4 1.2.5.2-.4ZM344.4 105.5l-1.2-.5-.2.4 1.2.5.2-.4ZM342.1 104.5l-1.2-.5-.2.4 1.2.5.2-.4ZM325.9 103.4l-.4-.2-.5 1.2.4.2.5-1.2ZM339.7 103.6l-1.2-.5-.2.4 1.2.5.2-.4ZM337.3 102.7l-1.2-.5-.2.4 1.2.5.2-.4ZM335 101.8l-1.2-.5-.2.4 1.2.5.2-.4ZM326.8 101l-.4-.2-.5 1.2.4.2.5-1.2ZM332.6 100.9l-1.2-.5-.2.4 1.2.5.2-.4ZM330.2 100.1l-1.2-.5-.2.4 1.2.4.2-.3ZM327.4 99.3l.3.1.2-.4-.7-.3-.4.9.4.2.2-.5Z\" fill=\"#DBDBDB\" /><path d=\"m357 123.5 11.8 4.6-7.5-15.8-4.3 11.2ZM342.201 139.101c.9-2.4-.3-5-2.7-5.9-2.4-.9-5 .3-5.9 2.7-.9 2.4.3 5 2.7 5.9 2.4.9 5-.3 5.9-2.7Zm-7.299-2.699c-.6 1.7.2 3.6 1.9 4.2 1.7.6 3.6-.2 4.2-1.9.6-1.7-.2-3.6-1.9-4.2-1.7-.6-3.6.2-4.2 1.9Z\" fill=\"#DBDBDB\" /><path d=\"m349 142.104.5-.3-.2-.5c-.1-.3-2.3-6.9-8.5-9.6-4-1.7-8.8-1.4-14.1 1l-.6.3.3.6c2.3 5.1 5.4 8.4 9.3 9.9.2.1.5.2.5.1 6.5 2.1 12.5-1.3 12.8-1.5Zm-12.2.4c4.9 1.6 9.7-.4 11.2-1.1-.6-1.6-2.9-6.3-7.6-8.3-3.6-1.6-7.8-1.4-12.5.6 2.2 4.6 5.2 7.6 8.9 8.8Z\" fill=\"#DBDBDB\" /><path d=\"m326.581 143.347 23.261-10.449-.533-1.186-23.261 10.45.533 1.185ZM260.796 107.601c-.8-7.3 4-14 10.9-14.8 6.9-.8 13.2 4.5 14.1 11.9l2.3 19.4 5.5-.6-2.3-19.4c-1.2-10.5-10.3-18.1-20.3-17.1-9.9 1.1-16.9 10.7-15.7 21.2l2.3 19.4 5.5-.6-2.3-19.4Z\" fill=\"#DBDBDB\" /><path d=\"m257.7 127.7 5.5-.6-1.4-11.8-5.5.4 1.4 12ZM286.9 113.4l1.2 10.7 5.5-.6-1.2-10.5-5.5.4Z\" fill=\"#A6A6A6\" /><path d=\"m254.43 160.014 49.952-5.91-4.712-39.822-49.951 5.91 4.711 39.822Z\" fill=\"#FFC412\" /><path d=\"M280.4 135.8c1.1-2.2.1-4.9-2.1-5.9-2.2-1.1-4.9-.1-5.9 2.1-1.1 2.2-.1 4.9 2.1 5.9l-.9 10.1 8.9-1-3.3-9.6c.5-.4 1-.9 1.2-1.6Z\" fill=\"#fff\" /><path d=\"M362.5 81.4c0-7-5.7-12.7-12.7-12.7-7 0-12.7 5.7-12.7 12.7 0 7 5.7 12.7 12.7 12.7 7 0 12.7-5.7 12.7-12.7Zm-22.4.1c0 5.4 4.3 9.7 9.7 9.7 5.3 0 9.7-4.3 9.7-9.7 0-5.4-4.3-9.7-9.7-9.7-5.3 0-9.7 4.3-9.7 9.7Z\" fill=\"#03D5B7\" /><path d=\"m238.498 182.298 4.9-12.2c.2-.5-.1-1.1-.6-1.3-.5-.2-1.1.1-1.3.6l-4.9 12.2c-.2.5.1 1.1.6 1.3.1.1.3.1.4.1.4 0 .8-.3.9-.7ZM225 165.2c-.8-1.9-2.3-3.3-4.2-4.1-1.9-.8-4-.8-5.9 0-1.9.8-3.3 2.3-4.1 4.2-.8 1.9-.8 4 0 5.9.8 1.9 2.3 3.3 4.2 4.1 1 .4 1.9.6 2.9.6s2-.2 3-.6c1.9-.8 3.3-2.3 4.1-4.2.8-1.9.8-4 0-5.9Zm-4.903 8.3c1.4-.6 2.5-1.7 3-3.1.5-1.4.6-2.9 0-4.3s-1.7-2.5-3.1-3c-.7-.4-1.4-.5-2.1-.5-.8 0-1.5.2-2.2.5-1.4.6-2.5 1.7-3 3.1-.5 1.4-.6 2.9 0 4.3s1.7 2.5 3.1 3c1.4.6 2.9.6 4.3 0ZM215.795 196.296c.5-.3.5-1 .2-1.4l-21.3-27.9c-.3-.4-1-.5-1.4-.2-.5.3-.5 1-.2 1.4l21.3 27.9c.2.3.5.4.8.4.2 0 .4-.1.6-.2Z\" fill=\"#FFC412\" /><path d=\"m259.6 80.6-12.5-44.9-65.9 14.6 12.6 45 65.8-14.7Z\" fill=\"#DBDBDB\" /><path d=\"m222.5 41.1 24.6-5.4-1.3-4.7-23.3 5.2v4.9Z\" fill=\"#DBDBDB\" /><path d=\"m259.7 80.6-4.5-43.9-65.8 14.6 4.4 43.9 65.9-14.6Z\" fill=\"#EBEBEB\" /><path d=\"m230.6 42.1 24.6-5.4-.4-4.6-23.3 5.2-.9 4.8Z\" fill=\"#EBEBEB\" /><path d=\"M227.398 65.298c-.4-2.1-2.6-3.5-4.7-3-2.1.4-3.5 2.6-3 4.7.4 2.1 2.6 3.5 4.7 3 2.1-.4 3.5-2.6 3-4.7Zm-6.701 1.505c.3 1.5 1.9 2.5 3.4 2.2 1.5-.3 2.5-1.9 2.2-3.4-.3-1.6-1.8-2.5-3.4-2.2-1.5.3-2.5 1.9-2.2 3.4Z\" fill=\"#fff\" /><path d=\"m213.2 67.999-.3.5.5.3c4 2.6 7.9 3.5 11.4 2.7l.5-.1c5.6-1.6 8.4-7 8.5-7.2l.2-.4-.4-.3c-.2-.2-4.9-3.9-10.7-2.9-3.7.6-7 3.1-9.7 7.4Zm11.9 2.3c4.3-1.2 6.8-4.9 7.6-6.2-1.2-.8-5.1-3.1-9.5-2.4-3.3.6-6.2 2.8-8.7 6.5 3.8 2.3 7.3 3 10.6 2.1Z\" fill=\"#fff\" /><path d=\"m218.069 75.787 11.871-18.64-.927-.591-11.872 18.64.928.591Z\" fill=\"#fff\" /><path d=\"M58.195 88.704h-14.8c.9 2.7 2.7 5.1 5.4 6.7l-5.9 28.5 25.5-.1-4.7-21.8h-8.6c-.5 0-1-.5-1-1 0-.6.4-1 1-1h8.2l-1-4.6c1.7-1 3-2.4 4.1-4.1 1.9-3.1 2.3-6.7 1.5-9.9h-14.8c-.6 0-1-.4-1-1s.4-1 1-1h14c-1-2.2-2.7-4.2-4.9-5.6-6-3.7-13.9-1.8-17.6 4.1-1.7 2.8-2.2 5.9-1.7 8.8h15.3c.6 0 1 .4 1 1s-.4 1-1 1ZM324.1 74.197c4.2-.9 6.9-5.1 6-9.3-.9-4.2-5.1-6.9-9.3-6-4.2.9-6.9 5.1-6 9.3l-15 9.5 10.9 11.2 9.9-14.8c1.2.3 2.4.3 3.5.1Z\" fill=\"#F5F5F5\" /><path d=\"M333.7 74.3c.2-.3.2-.7 0-.9l-9.8-10.2c-.3-.2-.7-.2-.9 0-.2.3-.2.7 0 .9l9.8 10.2c.1.1.2.2.4.2.1 0 .3-.1.5-.2ZM322.7 69.5c.2-.3.2-.7 0-.9l-9.8-10.2c-.3-.2-.7-.2-.9 0-.2.3-.2.7 0 .9l9.9 10.2c.1.1.2.2.4.2.1 0 .3-.1.4-.2ZM325.4 83.9c.2-.3.2-.7 0-.9l-9.8-10.2c-.3-.2-.7-.2-.9 0-.2.3-.2.7 0 .9l9.8 10.2c.1.1.2.2.4.2s.3 0 .5-.2Z\" fill=\"#fff\" /><path d=\"M45.7 140.8h-8.4c-.5 0-1 .5-1 1L31 257.7c0 .3.1.5.3.7.2.2.4.3.7.3h8.8c.5 0 .9-.4 1-1l4.9-115.9c0-.2-.1-.5-.3-.7-.2-.2-.4-.3-.7-.3Zm-6 115.9 4.8-113.9h-6.3L33 256.7h6.7Z\" fill=\"currentColor\" /><path d=\"M154.8 268.8h117.5v-4.9H154.8v4.9Z\" fill=\"#00BC9C\" /><path d=\"m327.6 268.8 14-73H234.2l-14.1 73h107.5Z\" fill=\"#00BC9C\" /><path d=\"m331.9 268.8 14.1-73H238.5l-14 73h107.4Z\" fill=\"#03D5B7\" /><path d=\"M289.7 231.9c0-5-4-9-9-9s-9 4-9 9 4 9 9 9c4.9 0 8.9-4 9-9Zm-15.5 0c0 3.5 2.9 6.5 6.4 6.5 3.6 0 6.5-2.9 6.5-6.4 0-3.6-2.9-6.5-6.4-6.5-3.6 0-6.5 2.9-6.5 6.4Z\" fill=\"#fff\" /><path d=\"M280.8 244.502c.5 0 .9-.1 1.3 0 13.2-.7 21.9-11.3 22.3-11.7l.6-.8-.6-.8c-.4-.5-9.1-11-22.3-11.7-8.7-.4-17.1 3.5-25.2 11.6l-.9.9.9.9c7.7 7.7 15.7 11.6 23.9 11.6Zm1.2-2.604c10.1-.5 17.5-7.5 19.8-9.9-2.3-2.4-9.7-9.4-19.8-9.9-7.6-.4-15.1 2.9-22.3 9.9 7.3 7 14.8 10.3 22.3 9.9Z\" fill=\"#fff\" /><path d=\"m263.81 250.562 35.355-35.355-1.768-1.768-35.355 35.355 1.768 1.768Z\" fill=\"#fff\" /><path d=\"M54.3 256.7H33l5.2-113.9H116c.6 0 1-.4 1-1s-.4-1-1-1H37.3c-.5 0-1 .5-1 1L31 257.7c0 .3.1.5.3.7.2.2.4.3.7.3h22.3c.6 0 1-.4 1-1s-.4-1-1-1Z\" fill=\"currentColor\" /><path d=\"m139.404 157.398.7-5.3c3.3 1.7 7.1 2.8 15.9.3 14.4-4.2 17.4-25.4 19.2-38.1l.2-1.3c1-7.1-.5-13.5-4.3-18.5-4.7-6.2-12.8-10.1-24-11.6-21.9-2.9-29.1 22.3-30.2 26.5-3 1-4.3 4.3-4.3 4.4-1 2.2-1.1 4.3-.3 6.3 1.4 3.5 5.3 5.6 7 6.4l-8 30c-.2.6-2.9 10.9 7.6 14.3 1.7.4 3.9.8 6 .8 1.5 0 3-.2 4.2-.7.3-.1.5-.2.8-.3 5.1-2.3 8.8-7.4 9.5-13.2Zm-1.007-6.997c0-.3.2-.6.5-.8.3-.2.6-.1.9 0 3.5 1.9 6.5 3.5 15.7.8 13.2-3.8 16.1-24.3 17.8-36.5l.2-1.4c.9-6.6-.4-12.4-3.9-17-4.4-5.8-12-9.4-22.6-10.8-22-2.9-28.1 25.3-28.2 25.6-.1.4-.4.7-.8.8-2.3.5-3.5 3.4-3.5 3.4-.8 1.7-.9 3.3-.3 4.8 1.5 3.7 6.6 5.6 6.7 5.7.5.2.7.7.6 1.2l-8.2 30.9c-.1.4-2.6 9 6.2 11.8 3.7.9 6.9 1 9 .2.2-.1.4-.2.7-.3 4.5-2.1 7.7-6.5 8.3-11.7l.9-6.7Z\" fill=\"currentColor\" /><path d=\"M158.599 150.3c9.8 2.9 23.4-3 23.4-3l-9-23.8c-1.09 20.34-14.17 26.74-14.4 26.8ZM116.5 141.502l3.1-15.8c-11.4-8.7-5.3-13.1-1.4-14.6 1.4-.5 3.4-.1 3.4-.1.5 10.4 3.2 13.1 7 12.5 4.1-.6 3.4-10 3.4-10 15.6 4.7 21.3-18 21.3-18 7.9 17.7 27.8 14.5 27.8 14.5 1.7-35.5-29.1-36.3-29.3-36.2-43.6-24.3-70.9 47.9-70.9 47.9 7.2 20.6 35.6 19.8 35.6 19.8Z\" fill=\"currentColor\" /><path d=\"M111.671 121.402a5.202 5.202 0 0 0 2.826 6.789 5.202 5.202 0 0 0 6.789-2.826 5.202 5.202 0 0 0-2.826-6.789 5.203 5.203 0 0 0-6.789 2.826Z\" fill=\"#FFC412\" /><path d=\"M163.286 118.3a7.302 7.302 0 0 0 3.967 9.531 7.301 7.301 0 0 0 9.531-3.967 7.302 7.302 0 0 0-3.967-9.531 7.302 7.302 0 0 0-9.531 3.967Z\" fill=\"#fff\" /><path d=\"M173.195 128.805c2.1-.8 3.7-2.4 4.5-4.5.9-2.1.9-4.3 0-6.4-.8-2.1-2.4-3.7-4.5-4.5-2.1-.9-4.3-.9-6.4 0-2.1.8-3.7 2.4-4.5 4.5-.9 2.1-.9 4.3 0 6.4.8 2.1 2.4 3.7 4.5 4.5 1 .4 2.1.6 3.2.6s2.2-.2 3.2-.6ZM167.6 115.2c-1.6.7-2.8 1.9-3.4 3.4-.6 1.6-.6 3.3 0 4.9.7 1.6 1.9 2.8 3.4 3.4 3.2 1.3 6.9-.2 8.3-3.4.6-1.6.6-3.3 0-4.9-.7-1.6-1.9-2.8-3.4-3.4-.9-.3-1.7-.5-2.5-.5s-1.7.2-2.4.5Z\" fill=\"currentColor\" /><path d=\"M169.213 123.476a1.9 1.9 0 1 0 3.126 2.16 1.9 1.9 0 0 0-3.126-2.16ZM178.197 120.397l3.7-1.3c.5-.2.8-.8.6-1.3-.2-.5-.8-.8-1.3-.6l-3.7 1.3c-.5.2-.8.8-.6 1.3.1.4.5.7.9.7.2 0 .3 0 .4-.1ZM176.7 117.5l3.7-3.7c.4-.4.4-1 0-1.4-.4-.4-1-.4-1.4 0l-3.7 3.7c-.4.4-.4 1 0 1.4.2.2.4.3.7.3.2 0 .5-.1.7-.3Z\" fill=\"currentColor\" /><path d=\"M143.062 114.906a7.302 7.302 0 0 0 3.967 9.531 7.303 7.303 0 0 0 9.532-3.967 7.304 7.304 0 0 0-3.967-9.531 7.303 7.303 0 0 0-9.532 3.967Z\" fill=\"#fff\" /><path d=\"M146.595 110.005c-2.09.8-3.7 2.4-4.5 4.5-.9 2.1-.9 4.3 0 6.4.8 2.1 2.41 3.7 4.5 4.5 1 .4 2.11.6 3.21.6s2.2-.2 3.2-.6c2.1-.8 3.7-2.4 4.5-4.5.9-2.1.9-4.3 0-6.4-.8-2.1-2.4-3.7-4.5-4.5-2.11-.9-4.31-.9-6.41 0ZM143.9 115.2c-.6 1.6-.6 3.3 0 4.9.7 1.6 1.9 2.8 3.4 3.4 1.6.6 3.3.6 4.9 0 1.6-.7 2.8-1.9 3.4-3.4.6-1.6.6-3.3 0-4.9-.7-1.6-1.9-2.8-3.4-3.4-.8-.3-1.6-.5-2.4-.5-2.5 0-4.9 1.5-5.9 3.9Z\" fill=\"currentColor\" /><path d=\"M149.763 119.956a1.9 1.9 0 1 0 3.126 2.16 1.9 1.9 0 0 0-3.126-2.16ZM145.302 111.801c.4-.2.6-.8.4-1.3l-1.8-3.5c-.2-.4-.8-.6-1.3-.4-.4.2-.6.8-.4 1.3l1.8 3.5c.2.4.5.6.9.6.1 0 .3 0 .4-.2ZM149.1 110.4v-5.2c0-.5-.4-1-1-1s-1 .4-1 1v5.2c0 .5.4 1 1 1s1-.5 1-1ZM158.701 127.505c-.3.5-.2 1.1.3 1.4 1.2.7 2.2 1 3.2 1h1.1c.9-.3 1.6-.9 2.1-1.8 1-1.9-1-4-2-4.8l.5-6.6c.1-.6-.3-1.1-.9-1.1-.6-.1-1.1.3-1.1.9l-.6 7.1c0 .4.1.7.4.9 1 .7 2.2 2.1 1.9 2.6-.2.4-.5.7-.9.8-.6.1-1.6-.1-2.6-.7-.5-.3-1.1-.2-1.4.3ZM159.297 105.895c.4-.4.5-1 .1-1.4-.4-.4-1-.5-1.4-.1-3.3 3.1-6.9 1.9-7.1 1.8-.5-.2-1.1.1-1.3.6-.2.5.1 1.1.6 1.3 0 0 1.1.4 2.6.4 1.8 0 4.2-.5 6.5-2.6ZM176.603 112.003c0-.5-.4-1-1-1-4.6-.2-6.2-3.6-6.3-3.8-.2-.5-.8-.7-1.3-.5-.5.2-.7.8-.5 1.3.1.2 2.2 4.7 8.1 5 .6 0 1-.4 1-1ZM158.803 136.402c0 .6.4 1 1 1.1.5 0 .9-.4 1.1-1 .2-1.7-.2-3.1-1-4-.7-.8-1.8-1.2-3.1-1.3-3.2-.2-4.9 3.7-5 3.9-.2.5 0 1.1.5 1.3.5.2 1.1 0 1.3-.5 0 0 1.3-2.8 3-2.7.8.1 1.3.3 1.7.7.5.7.6 1.7.5 2.5Z\" fill=\"currentColor\" /><path d=\"m152.4 71.6-4.3-.6v2.3l5.9.6-1.6-2.3Z\" fill=\"#E2A40A\" /><path d=\"M136.403 67.003c-24 24.6-15.3 43.3-15.3 43.3 1.2-31.1 31.3-38.7 31.3-38.7-7.5-9.9-16-4.6-16-4.6Z\" fill=\"#FFC412\" /><path d=\"M151.899 241.999c1.9.9 11.7 5.4 14.9 4 .8-.4 1.1-.9 1.2-1.3 1.2-3.7-2.5-7.2-26.1-15.9-21.6-8-70.4 19.4-72.5 20.6-.5.3-.7.9-.4 1.4.2.3.6.5.9.5.2 0 .3 0 .5-.2.5-.2 50.1-28.1 70.8-20.4 18.3 6.8 25.8 10.8 24.9 13.4-.8.9-7.2-1-13.4-3.9-.5-.2-1.1 0-1.3.5-.2.5 0 1.1.5 1.3Z\" fill=\"currentColor\" /><path d=\"M160.796 258.495c.9-.8 1.3-2 1.3-3.3-.3-6.8-13.9-17.9-15.4-19.1-.4-.3-1.1-.2-1.4.2-.3.4-.2 1.1.2 1.4 4 3.2 14.4 12.6 14.6 17.6 0 .7-.2 1.3-.6 1.7-.6.3-2.8-.1-5.9-5.2-.3-.4-.9-.6-1.4-.3-.4.3-.6.9-.3 1.4 2.2 3.6 4.4 5.7 6.5 6.1.2.1.5.1.7.1.9 0 1.5-.4 1.6-.5 0-.1.1-.1.1-.1Z\" fill=\"currentColor\" /><path d=\"M147.701 262.501c.9.8 1.9 1.2 2.9 1.2.6 0 1.2-.2 1.9-.5 1-.6 3.3-2.8 1.5-9.4-2.2-8.3-13.4-15.1-13.9-15.4-.5-.3-1.1-.2-1.4.3-.3.5-.2 1.1.3 1.4.1.1 11 6.7 13 14.2 1.2 4.3.4 6.6-.6 7.2-.7.4-1.6.2-2.4-.5-.4-.4-1-.3-1.4.1-.4.4-.3 1 .1 1.4Z\" fill=\"currentColor\" /><path d=\"M133.799 241.999c-.3.5-.1 1.1.4 1.4.1 0 12.7 7.2 12.3 15.4-.2 4.5-1.3 5.2-1.6 5.3-.6.2-1.7-.5-2.4-1.3-.4-.4-1-.5-1.4-.1-.4.4-.5 1-.1 1.4.4.5 1.9 2 3.6 2 .3 0 .6 0 1.1-.1 1.8-.6 2.7-2.9 2.9-7.1.4-9.5-12.8-17-13.4-17.3-.5-.3-1.1-.1-1.4.4Z\" fill=\"currentColor\" /><path d=\"M132.403 258.101c.9.6 1.5 2.3 2.1 3.8.9 2.3 1.8 4.5 3.6 4.9 1.6.3 2.6-.2 3.1-.7 1.4-1.2 1.8-3.8 1.2-7.8-.9-6.3-11.5-13.4-12-13.7-.5-.3-1.1-.2-1.4.3-.3.5-.2 1.1.3 1.4 2.9 1.9 10.5 7.9 11.1 12.3.6 4.5-.2 5.8-.6 6.1-.2.2-.5.4-1.3.2s-1.6-2.1-2.2-3.7c-.8-1.8-1.5-3.8-2.8-4.7-2.3-1.7-5.3-2.8-11.5.6-5.4 2.9-21.4 9.9-21.6 10-.5.2-.7.8-.5 1.3.1.4.5.6.9.6.1 0 .2 0 .5-.1.6-.3 16.2-7.1 21.7-10.1s7.6-2 9.4-.7ZM55.5 258.7c0-.6-5.1-56.4-.9-73.1C59 168.4 68.7 160 112 158.5c.6 0 1-.4 1-1s-.4-1-1-1c-44.6 1.5-54.6 10.4-59.2 28.6-4.3 17 .7 71.4.9 73.7.1.5.5.9 1 .9.7-.1 1.1-.6.8-1Z\" fill=\"currentColor\" /><path d=\"m84.6 243 .9-44.8c0-.5-.4-1-1-1-.5 0-1 .4-1 1l-.9 44.8c0 .5.4 1 1 1 .5 0 1-.4 1-1Z\" fill=\"currentColor\" /><path d=\"M83.801 207.201c.6-.2.9-.8.7-1.3-.2-.6-.8-.9-1.3-.7-15.5 4.8-29.8-4.4-29.9-4.5-.5-.3-1.1-.2-1.4.3-.3.5-.2 1.1.3 1.4.5.3 9.6 6.2 21.5 6.2 3.2 0 6.6-.4 10.1-1.4ZM188.004 226.802c0-.3-1.4-28.9-7.3-52.8-6.1-24.8-41.7-18.8-42.1-18.7-.5.1-.9.7-.8 1.2.1.5.7.9 1.2.8.3 0 34.1-5.7 39.8 17.2 5.9 23.8 7.2 52.1 7.2 52.4 0 .6.5 1 1 1 .6 0 1-.5 1-1.1Z\" fill=\"currentColor\" /><path d=\"M167.104 234.804c.5 0 .9-.6.8-1.1l-7.2-46.7c0-.5-.6-.9-1.1-.8-.5 0-.9.6-.8 1.1l7.2 46.7c.1.4.5.8 1 .8h.1ZM168.497 245.701c.5.2 1.1-.2 1.2-.7.2-.8 5.4-20.6 31.8-18.1 14.7 1.4 20.8 7.7 23.3 12.7 2.1 4.2 1.9 7.9 1.5 8.7-1 .4-3.3.8-9-9.6-.3-.5-.9-.7-1.4-.4-.5.3-.7.9-.4 1.4 4.7 8.6 7.6 10.8 9.9 10.8.7 0 1.3-.2 2-.5 1.5-.8 1.3-4.5.9-6.4-.9-5-5.4-16.7-26.6-18.7-28.2-2.7-33.8 19.4-33.9 19.6-.2.5.2 1.1.7 1.2Z\" fill=\"currentColor\" /><path d=\"M186.504 258.995c1.2.1 2.2-.2 3-.9 2.2-2.1 1.9-7.2 1.7-11.2 0-1.3-.1-3 0-3.4 0-.2.4-.4 1.1-.4 2.3-.1 6 2.1 9.5 8.3 3.1 5.5 5.4 8 7.5 8 1.7-.1 2.5-1.7 3.1-2.2 1.2-2.5-2.7-14.6-8.5-19.3-.4-.4-1-.3-1.4.1-.4.4-.3 1.1.1 1.4 5.2 4.3 8.6 15.3 7.9 16.9-.4.7-.7 1.1-1 1.1-.4 0-2.1-.4-5.8-7-5-8.9-9.9-9.5-11.3-9.4-1.4 0-2.4.6-2.9 1.5-.4.7-.3 1.9-.2 4.4.2 3.2.5 8.1-1.1 9.6-.2.2-.6.5-1.4.4-.6 0-1.1-.3-1.5-.9-1.9-2.8-.4-10.6.3-13.4.2-.5-.2-1.1-.7-1.2-.5-.2-1.1.2-1.2.7-.3 1.1-2.9 11-.1 15.1.7 1 1.7 1.7 2.9 1.8Z\" fill=\"currentColor\" /><path d=\"M211.996 255.996c-.5-.2-1.1.2-1.2.7-.1.5.2 1.1.7 1.2 0 0 .5.1 1.1.1.7 0 1.7-.1 2.5-.9 1.3-.9 1.9-2.5 2-4.7.2-5.9-7.3-16.5-7.6-16.9-.3-.4-1-.5-1.4-.2-.4.3-.5 1-.2 1.4.1.1 7.5 10.5 7.3 15.7-.1 1.6-.5 2.7-1.2 3.2-.8.7-2 .4-2 .4Z\" fill=\"currentColor\" /><path d=\"M214.999 234.799c-.3-.5-.9-.7-1.4-.4-.5.3-.7.9-.4 1.4 1.7 3 6.3 11.5 6.4 15 .1 1.4-.5 2.5-1.9 3.1-1.1.5-2.3.6-2.3.6-.6 0-1 .4-1 1s.5 1 1 1c.2 0 3.2-.1 5-2.1.9-.9 1.4-2.2 1.3-3.7-.2-4.7-6.4-15.4-6.7-15.9ZM184.6 195.201c.3-.5.2-1.1-.3-1.4-.5-.3-1.1-.2-1.4.3-5.4 8.5-20.5 6.7-20.7 6.7-.5 0-1 .4-1.1.9 0 .5.4 1 .9 1.1.2 0 1.7.2 3.9.2 5.2 0 14.4-1.1 18.7-7.8Z\" fill=\"currentColor\" /><path d=\"m84.796 37.503-10.1 22.7c-.2.4-.1.8.2 1.1.2.2.4.3.7.3.1 0 .2-.1.3-.1l32.9-12.6c.3-.1.6-.5.6-.9s-.2-.7-.6-.9l-22.7-10.1c-.5-.2-1.1 0-1.3.5ZM77.5 58.8l28.3-10.9-19.6-8.7-8.7 19.6Z\" fill=\"#03D5B7\" /></g></svg>\n  </div>\n</template>\n"
  },
  {
    "path": "src/icons/500.vue",
    "content": "<template>\n  <div class=\"text-[currentColor] dark:text-[#3a71ff]\">\n    <svg viewBox=\"0 0 400 300\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><mask id=\"a\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"31\" y=\"32\" width=\"338\" height=\"237\"><path d=\"M368.4 32H31v236.9h337.4V32Z\" fill=\"#fff\" /></mask><g mask=\"url(#a)\" fill-rule=\"evenodd\" clip-rule=\"evenodd\"><path d=\"M79.498 122.599c-3.3-7.4-5.2-17.8-7.9-29.5-2.4-12.9-20.8-28.3-34.1-17.6-6.2 5.1-8 17.7-5.4 28.5 2.3 11 9 20.1 14 23.2 10.5 6.3 26.2.8 29.9 4.4 7.6 6.9 11.2 12.8 11.2 13 .2-.2-2.4-10.3-7.7-22Z\" fill=\"#EBEBEB\" /><path d=\"M64.9 112.503c.8-.1 1.1-1.4.6-2.9-.5-1.5-1.5-2.6-2.4-2.5-.9.1-1.2 1.5-.7 3s1.6 2.6 2.5 2.4ZM56.103 110.604c.8-.2 1.2-1.5.7-3.1s-1.6-2.8-2.5-2.7c-.9.1-1.1 1.6-.7 3.2.5 1.6 1.7 2.8 2.5 2.6ZM47.202 108.504c.9-.2 1.2-1.6.7-3.2s-1.6-2.9-2.6-2.8c-1 .1-1.3 1.7-.8 3.3.5 1.7 1.7 2.9 2.7 2.7Z\" fill=\"#fff\" /><path d=\"M76.002 69.395c1.3-7.3 11.4-9.2 14.7-15.1 3.2-5.9 4.5-20.4-.5-22.1-5.1-1.7-17 7-18.3 14.9-1.3 6.9-1.1 16.4-.3 21.8 1.3 8.7 5.1 14.1 5.1 14.1s-1.9-7.1-.7-13.6Z\" fill=\"#EBEBEB\" /><path d=\"M88.099 47.302c.7-.9 1-2 .9-3.2-.1-1.1-.8-1.5-1.4-.8-.7 1-1.1 2.1-.9 3.2.1 1.1.8 1.5 1.4.8ZM82.399 50.702c.7-.9 1-2.1.8-3.2-.1-1.1-.8-1.5-1.4-.8-.7 1-1 2.1-.8 3.2.2 1.1.8 1.5 1.4.8ZM76.796 54.202c.7-.9.9-2.1.8-3.2-.2-1.1-.8-1.5-1.4-.8-.7.9-.9 2.1-.8 3.2.2 1.1.8 1.5 1.4.8Z\" fill=\"#fff\" /><path d=\"M159.502 190.201c69.4-1.4 71.8-64.6 71.6-77.3-.2-12.8-8-39.3-27.7-56.5-15.6-13.6-35.6-18.9-59.5-16-35.4 4.4-50.8 26.1-57.5 43.6-4.4 11.9-6.5 24.5-6.1 37.1.1 4.9 3.2 22.4 14.9 38.8 9.9 13.9 28.6 30.3 62.1 30.3h2.2Zm-.002-.901c68.601-1.4 71.001-64 70.801-76.5-.2-12.5-7.9-38.8-27.4-55.8-12.7-11-28.301-16.5-46.601-16.5-4.1 0-8.2.3-12.2.8-35 4.3-50.2 25.8-56.8 43-4.4 11.8-6.4 24.3-6.1 36.8.2 6 4.1 23.2 14.8 38.3 9.8 13.8 28.3 29.9 61.4 29.9h2.1Z\" fill=\"#EBEBEB\" /><path d=\"M101.804 66.303c-44.2 46-9.1 89 3.9 101.6 12.7 12.2 67.9 42.4 108.8-10.1 40.9-52.5-11.7-98.5-11.7-98.5-7-6.6-56.8-39-101 7Z\" fill=\"#EBEBEB\" /><path d=\"M159.499 191.898c22.1-.1 39.7-7 52.2-20.6 22.3-24.2 20.9-60.8 20.9-61.1-.1-1.7-3.2-42-30.7-62.5-15.2-11.2-34.8-14.2-58.3-8.9-24.6 5.6-42.3 17.2-52.5 34.4-17 28.8-7.2 63.9-7 64.5 3.3 9.9 8.4 19.1 15.1 27.1 10.3 12.4 29.1 27 60.1 27l.2.1ZM165.098 37.1c-7.1.1-14.3.9-21.2 2.6-24.4 5.5-41.9 17-52 34.1-16.9 28.6-7 63.4-6.9 63.8 3.2 9.8 8.3 18.9 15 26.8 10 12.1 28.6 26.6 59.3 26.6h.3c21.4-.1 38.5-6.6 50.8-19.5 22.7-23.7 21.4-60.9 21.4-61.2-.1-1.7-3.2-41.6-30.4-61.9-10.1-7.6-22.3-11.3-36.3-11.3Z\" fill=\"#EBEBEB\" /><path d=\"M232.696 107.798c.7-24.8-8.4-43.4-27.1-55.3-25.9-16.5-60-13.8-60.1-13.7l-.5.1c-9.3 1.5-41 8.2-57.2 33.5-11 17.1-12.8 39.2-5.4 65.7 6.5 23.4 18.7 39.3 36.2 47.2 9.3 4.3 19.4 5.8 29.1 5.8 25.6 0 48.5-10.8 49.1-11 .4-.2 8.9-4 17.4-14.5 8-9.9 17.6-27.9 18.5-57.8Zm-19.094 57.101c7.9-9.8 17.5-27.6 18.3-57.2.6-21.2-6.1-37.9-19.9-49.6-25.5-21.4-65.301-18.6-66.201-18.5-.2.1-.4.1-.6.1-9.2 1.5-40.6 8.2-56.7 33.1-10.8 16.9-12.6 38.8-5.3 65.1 6.4 23.1 18.5 38.8 35.7 46.6 9.3 4.2 19.2 5.7 28.8 5.7 25.5 0 48.501-10.8 48.801-11 .1 0 8.6-3.7 17.1-14.3Z\" fill=\"#EBEBEB\" /><path d=\"M157.198 192.605c3.4 0 6.8-.2 10.2-.6 53.4-6.6 60.1-50.4 65.1-82.3l.3-1.8c2.5-16.3-8.2-38.1-26.2-52.9-13-10.7-40.6-26.6-79-12.7-33 11.9-43.2 36.7-46 55.4-1.8 12.7-1.1 25.6 1.9 38l.9-.2c-3-12.3-3.7-25.1-1.9-37.7 2.7-18.5 12.8-42.9 45.4-54.7 38-13.8 65.3 1.9 78.1 12.5 17.8 14.7 28.4 36.1 25.9 52.2l-.3 1.8c-4.9 31.7-11.7 75.1-64.4 81.6-27.4 3.4-47-7.6-58.6-17.4-15-12.8-23.4-29.2-23.7-36.1h-.9c.4 7.1 8.9 23.8 24.1 36.7 13.7 11.7 31.1 18.2 49.1 18.2Z\" fill=\"#EBEBEB\" /><path d=\"M203.097 123.1c.6-.3.4-1-.1-.8-5.9 2.1-13.2 2.4-18.4-1.6-4.3-3.3-5.9-9.1-5.1-14.3.4-2.7 1.4-5.4 2.9-7.7 1.9-2.9 4.3-5.2 6.7-7.6 4.5-4.5 9.7-9.9 9.5-16.8-.2-6-5.1-10.7-10.6-12.4-3.9-1.1-8.1-.9-11.9.5-.2-.3-.4-.6-.6-.8-3.3-4.1-8.7-6-13.8-6-5.9.1-11.6 2.1-16.2 5.9-1.1.9-2.1 1.9-3.1 3.1-.3.4.2.9.5.5 3.7-4.4 8.9-7.3 14.5-8.3 5.2-.9 10.8-.2 15 3 1.1.8 2.1 1.8 2.8 2.9-1.3.6-2.5 1.3-3.7 2.1-2.1 1.5-5.1 4.2-3.9 7.1 1 2.1 3.3 3.2 5.6 2.7 2.6-.7 4.1-3.5 4.3-6 .1-1.9-.3-3.8-1.2-5.5 3.6-1.3 7.6-1.5 11.3-.5 5.5 1.6 10.3 6.4 10.1 12.4-.1 3.2-1.5 6.3-3.3 8.9-1.8 2.6-4.2 5-6.5 7.3-2.4 2.2-4.5 4.7-6.4 7.4-1.4 2.2-2.4 4.7-2.8 7.3-.8 4.9.3 10.2 3.7 14 4.1 4.5 10.7 5.5 16.4 4.4 1.5-.3 2.9-.6 4.3-1.2Zm-27.299-59.9c-1.4.6-2.7 1.3-3.9 2.2-1.9 1.5-5 4.4-2.9 6.9.7.9 1.7 1.4 2.8 1.5 1.2.1 2.4-.3 3.3-1.2 1.9-1.8 2.3-4.7 1.6-7.2-.2-.8-.5-1.5-.9-2.2ZM269.1 153.3c-3.2-1.6-6.8-2.1-10.4-2.3-.9 0-1.9-.1-2.9-.1-.2 0-.4.2-.4.4s.2.4.4.4c3.7.1 7.6.2 11.1 1.5 3 1.1 5.7 3 7.3 5.8 1.7 3.1 1.6 6.7 1.1 10.1-.5 3.3-1.4 6.5-1.7 9.8-.3 2.9-.1 6.1 1.3 8.7 1.4 2.6 3.8 4.4 6.7 5.1 3 .7 6 .3 8.8-1 2.9-1.3 5.4-3.4 7.7-5.6 2.4-2.3 4.7-4.7 7.5-6.5 2.8-1.9 5.9-3.3 9.3-3.1.8 0 1.6.2 2.4.5.2 0 .4-.7 0-.9-6.7-2.1-12.9 2.7-17.4 7-4.5 4.3-9.4 9.4-16.1 9.1-3.1-.1-5.9-1.5-7.7-4-1.7-2.5-2-5.7-1.8-8.7.4-6.5 3.7-13.4 1.1-19.8-1.3-2.8-3.5-5.1-6.3-6.4ZM91.7 156c.2-.5.4-1 .5-1.5.4-1.3.4-2.7 0-4-.2-.7-.6-1.2-1.1-1.6-.6-.4-1.3-.3-1.7.3-.8 1.2-.1 3.1.5 4.3.5.9 1.1 1.7 1.8 2.5Zm1.004.804c-.2-.1-.3-.3-.5-.4.3-.6.5-1.2.7-1.9.4-1.4.4-2.9 0-4.3-.4-1.2-1.4-2.5-2.8-2.4-1.7.2-2 2.2-1.8 3.6.3 1.6 1.1 3.1 2.2 4.3.2.3.5.5.8.8-1 1.7-2.5 3.1-4.2 4-2.7 1.2-5.8 1.2-8.6.2-6.5-2.3-10.1-9.2-11.2-15.6-1-6-.1-12.2 2.7-17.7.3-.7.7-1.3 1.1-2 .2-.4-.3-.8-.6-.4-3.5 5.7-5 12.5-4.1 19.1.9 7 4.7 14.6 11.7 17.2 3 1.2 6.3 1.1 9.3-.1 1.9-.9 3.5-2.3 4.5-4.1 2 1.7 4.5 2.7 7.1 2.7 3.3-.1 6.4-1.6 8.5-4.2.5-.6.9-1.3 1.3-2 .2-.5-.5-.7-.7-.3-1.4 2.7-3.9 4.7-6.9 5.4-3 .7-6.1 0-8.5-1.9Zm-28.206-27.7c-.3.3 0 .9.4.6 2-1.6 4.1-3.2 6.2-4.6-.6 2.3-.9 4.7-1 7.2 0 .4.7.4.7 0 0-2.7.4-5.3 1.1-7.8.1-.2 0-.4-.2-.4-.1-.2-.2-.2-.3-.1-2.4 1.5-4.7 3.2-6.9 5.1ZM293.403 83.996c-.4-.3-.9-.5-1.4-.7-1.3-.4-2.7-.5-4-.2-.6.2-1.2.5-1.6 1-.4.5-.3 1.3.2 1.7 1.2.9 3.1.4 4.3-.2.9-.4 1.8-1 2.5-1.6Zm-7.9.903c.1 1.7 2.1 2.2 3.5 2 1.6-.2 3.1-.9 4.4-1.9.3-.2.6-.5.9-.7 1.7 1.1 2.9 2.7 3.7 4.5 1 2.8.8 5.9-.4 8.6-2.7 6.4-9.8 9.5-16.3 10.2-6.1.6-12.2-.7-17.5-3.8-.7-.4-1.3-.8-1.9-1.2-.4-.3-.9.3-.5.6 5.5 3.9 12.1 5.8 18.8 5.3 7.1-.5 14.9-3.7 17.9-10.5 1.4-2.9 1.5-6.2.5-9.3-.8-1.9-2.1-3.6-3.8-4.8 1.8-1.9 2.9-4.3 3.1-6.9.1-3.3-1.2-6.5-3.6-8.7-.6-.5-1.3-1-2-1.4-.5-.4-.8.3-.4.5 2.6 1.6 4.5 4.2 5 7.2s-.4 6.1-2.4 8.3c-.1.2-.3.3-.4.5-.6-.3-1.2-.6-1.8-.8-1.4-.5-2.9-.6-4.3-.3-1.2.3-2.6 1.2-2.5 2.6ZM264.9 109.5c.3.4.9 0 .6-.3-1.5-2.1-2.9-4.3-4.2-6.5 2.3.8 4.7 1.2 7.1 1.4.4 0 .5-.7 0-.7-2.6-.2-5.2-.8-7.7-1.7-.2 0-.4.1-.4.3v.2c1.4 2.5 2.9 5 4.6 7.3ZM275.098 222.3c-.3-.5-.6-.9-.9-1.3-.8-1-2-1.8-3.3-2.2-.6-.2-1.3-.2-1.9 0-.6.3-.9 1-.7 1.6.5 1.4 2.5 1.8 3.8 2 1.1.1 2.1.1 3-.1Zm-22.594 14.095c-5.6-2.5-10.2-6.8-13.1-12.1-.4-.7-.7-1.3-1-2-.2-.4-.9-.2-.7.2 2.8 6.1 7.6 11.1 13.6 14.1 6.3 3.2 14.7 4.3 20.8-.1 2.6-1.8 4.5-4.6 5.1-7.8.3-2.1 0-4.2-.9-6.1 2.5-.7 4.7-2.2 6.2-4.4 1.8-2.8 2.2-6.2 1.3-9.3-.2-.8-.6-1.5-1-2.2-.3-.3-.9.1-.7.5 1.5 2.7 1.7 5.9.7 8.8-1.1 2.8-3.4 5-6.3 5.9-.2.1-.4.1-.6.2-.3-.6-.7-1.1-1.2-1.6-.9-1.1-2.2-1.9-3.6-2.4-1.2-.4-2.9-.3-3.5 1-.8 1.5.7 2.9 2 3.5 1.5.6 3.1.8 4.8.6.4 0 .7-.1 1.1-.2.9 1.8 1.2 3.8.9 5.7-.6 2.9-2.2 5.5-4.7 7.2-5.6 4.1-13.2 3.3-19.2.5Zm-14.902-6.491c0 .4.7.5.7 0-.3-2.6-.4-5.2-.3-7.7 1.6 1.8 3.4 3.4 5.4 4.8.4.3.7-.3.4-.6-2.2-1.5-4.2-3.3-5.9-5.3-.2-.1-.4-.1-.5.1 0 0-.1 0-.1.1-.1 2.9 0 5.8.3 8.6Z\" fill=\"currentColor\" /><path d=\"M210.296 131.103c-.4-.5-.8-.9-1.2-1.3-1.1-1-2.5-1.7-4-1.9-.7-.1-1.5 0-2.1.3h-.1c-.7.3-.9 1.2-.5 1.8.8 1.5 3 1.6 4.5 1.6 1.1-.1 2.2-.3 3.4-.5Zm-.9-1.998c-1.2-1.1-2.7-1.8-4.3-2.1-1.3-.2-3.2.1-3.7 1.6-.6 1.8 1.3 3.1 2.7 3.5 1.8.4 3.6.4 5.3-.1.4-.1.8-.2 1.2-.4 1.3 1.8 1.9 4 1.9 6.2-.2 3.3-1.6 6.4-4 8.7-5.5 5.4-14.1 5.7-21.1 3.7-6.5-1.9-12.3-5.9-16.4-11.3-.5-.7-1-1.3-1.4-2.1-.3-.4-1-.1-.7.4 4 6.3 10.1 11 17.2 13.4 7.5 2.5 16.9 2.4 22.9-3.4 2.6-2.4 4.2-5.8 4.4-9.4 0-2.3-.7-4.6-2-6.5 2.7-1.1 4.8-3.2 6.1-5.8 1.5-3.3 1.5-7.2-.1-10.5-.4-.8-.9-1.6-1.4-2.3-.2-.4-.8.1-.5.6 2.1 2.7 2.8 6.2 2.1 9.5-.7 3.3-3 6.1-6 7.6-.2.1-.4.2-.7.3-.5-.6-1-1.1-1.5-1.6Zm5.504-9.5c-.1.4.6.6.7.1.4-2.41.4-4.8.2-7.21 1.9 1.71 3.7 3.6 5.4 5.5.3.3.7-.2.5-.5-1.9-2.2-3.9-4.2-6.1-6.09-.1-.1-.4-.1-.5 0-.1.09-.1.19-.1.3.3 2.59.3 5.29-.1 7.9ZM238.404 119.804c1.6 3.2 2.3 6.7 2.3 10.3-.2 3.7-1.3 7.4-3.2 10.6-3.5 6.2-9.6 10.5-16.2 13.1l-2.4.9c-.2.1-.2.3-.1.5.1.1.2.2.3.2 6.6-2.2 12.8-5.9 17.1-11.4 4.3-5.9 6.3-13.6 4.3-20.6-1.9-6.7-6.7-12-9.3-18.4-5.6-13.8-.2-29.6 12.6-37.2.7-.4 1.5-.8 2.3-1.2.4-.2.2-.9-.2-.7-13.1 6.3-20 20.9-16.7 35 .9 3.4 2.2 6.7 4.1 9.8 1.7 3 3.6 5.9 5.1 9.1ZM123 189.001c-2.9.3-5.9 0-8.7-.9-5.8-2-10.7-6.1-13.6-11.4-1.8-3.3-3-6.8-3.5-10.5-.1-.5-.8-.4-.7 0 1 6.6 3.9 13 8.9 17.6 4.4 4 10.2 6.2 16.1 6.1 4.2-.2 8.2-1.6 12-3.1.6-.3.4-1-.1-.8-3.3 1.3-6.8 2.6-10.4 3ZM276.797 194.001c-.8 2.8-2.3 5.4-4.2 7.7-4.1 4.6-9.7 7.5-15.8 8.1-3.7.4-7.4.1-11-.8-.5-.1-.7.6-.3.7 6.5 1.7 13.6 1.4 19.7-1.5 5.4-2.5 9.7-7 11.8-12.5 1.5-3.9 1.6-8.2 1.8-12.3.1-.5-.6-.6-.7-.1-.1 3.6-.2 7.3-1.3 10.7Z\" fill=\"currentColor\" /><path d=\"M207.499 90.705c-1.8 1.5-3.3 3.2-4.4 5.2-1.3 2.3-2.3 5.1-1.6 7.7.3 1.2.9 2.2 1.8 3 1.1.9 2.4 1.4 3.8 1.4 2.5.2 5-.6 7-2.2 1.9-1.6 3.1-4 3.1-6.5 0-2.4-1.1-4.7-2.9-6.2-1.4-1.2-3.1-2.2-4.9-2.9 3.6-2.5 7.8-4 12.1-4.5 5.5-.6 11.1-.4 16.6.8 5.6 1.1 11 2.9 16.1 5.5 1.3.6 2.5 1.3 3.7 2 .2.1.5.1.6-.2.3-.21.2-.51 0-.61-5.2-3.1-10.9-5.39-16.7-6.89-5.7-1.51-11.6-2.11-17.5-1.8-5.6.4-11.1 1.9-15.7 5.3l-.2.1c-2.5-.8-5.1-1.3-7.7-1.5-4.9-.6-9.8-.4-14.6.5-9.6 1.7-18.6 6.1-25.8 12.7-.9.8-1.7 1.6-2.5 2.5-.4.4.2 1.1.7.7 6.3-6.7 14.4-11.6 23.3-14 4.4-1.2 9-1.8 13.6-1.8 4.1 0 8.2.5 12.1 1.7Zm1.102.295c-.4.3-.8.7-1.2 1-2 1.8-3.6 4-4.6 6.5-.8 2.4-.9 5.3.9 7.2 1.8 1.9 5 1.8 7.3.9s4.1-2.7 4.9-5.1c.7-2.3.2-4.8-1.3-6.7-1.5-1.7-3.5-3-5.7-3.7l-.3-.1ZM217.004 54.8c-2 1-3.7 2.3-5.3 3.8-1.8 1.9-3.6 4.4-3.4 7.1.1 1.3.6 2.4 1.5 3.3 1 .8 2.3 1.1 3.6.8 2.6-.6 4.1-3 4.7-5.5.6-3.2.3-6.5-1.1-9.5Zm-64.502.804c5.2-1.5 9.9-4.3 14.6-6.9 2.4-1.4 4.8-2.6 7.4-3.7 2.7-1.2 5.6-2 8.5-2.6 5.7-1.1 11.6-1.1 17.2.2 5.1 1.2 10.2 3.5 13.7 7.5 1.1 1.2 2 2.6 2.7 4.1-3.3 1.7-6.3 4.1-8.1 7.4-1.2 2.2-1.5 5 0 7.1 1.4 2 4 2.4 6.2 1.4 2.3-1.1 3.6-3.5 4.1-5.9.5-2.5.4-5.2-.4-7.6-.2-.7-.4-1.4-.7-2.1l.3-.1c5.301-2.5 11.201-2.9 17.001-3h4.6c.2-.1.3-.3.3-.5-.2-.1-.3-.2-.5-.2-6.2-.1-12.7-.2-18.601 1.8-1.2.4-2.4.8-3.5 1.4-4.5-9.1-15.5-12.8-25.3-13-6.1-.1-12.1 1-17.6 3.4-5.3 2.2-10.1 5.4-15.3 7.9-5 2.5-10.3 4-15.9 3.8-5.4-.2-10.7-1.7-15.3-4.6-1.1-.7-2.2-1.5-3.3-2.3-.4-.3-.9.2-.5.5 7.9 6.5 18.5 8.7 28.4 6ZM128.6 55.7c.3.3.9-.1.6-.4-1.8-1.9-3.5-3.8-5-5.9 2.4.4 4.8.6 7.2.4.4 0 .4-.7-.1-.7-2.6.2-5.3 0-7.9-.6-.2 0-.4.1-.4.3v.3c1.7 2.3 3.6 4.5 5.6 6.6Z\" fill=\"currentColor\" /><path d=\"M290.8 174.205c5 1.7 11.6-1.9 13.9-6.4.8-1.5 1-3.4.3-5-.7-1.7-2.3-2.7-4.1-2.5-1.8.2-3.4 1.3-4.7 2.5-1.2 1.1-2.2 2.4-3 3.8-1.2 2.3-2.1 4.9-2.4 7.6Zm-3.795-62.607c2.7 2.3 5 5.2 6.6 8.4 1.7 3.5 2.6 7.3 2.6 11.2 0 3.9-.7 7.9-2 11.6-1.4 3.8-3.1 7.4-5.2 10.8-1.9 3.3-3.8 6.7-4.2 10.5-.3 3.1.4 6.6 2.7 8.9.8.8 1.7 1.4 2.7 1.9-.2 2.3-.2 4.7.1 7 2 15.2 14.5 26.9 29.9 28 1.8.1 3.7.1 5.5-.1.3-.2.3-1-.1-.9-7.3.7-14.6-1.1-20.8-5.1-6.1-4-10.6-10.1-12.7-17-1.2-3.8-1.7-7.8-1.3-11.8 4.8 1.5 10.8-1.5 13.7-5.4 1.1-1.4 1.8-3.1 1.8-4.9-.11-1.5-.7-3-1.9-4-2.9-2.4-6.8 0-9 2.2-3 3-4.6 7-5.1 11.2-.9-.4-1.7-1-2.4-1.7-2.2-2.4-2.8-5.9-2.3-9 .6-3.8 2.6-7.1 4.5-10.4 3.8-6.5 6.6-13.6 6.7-21.3.1-3.7-.6-7.3-2-10.7-1.3-3.1-3.3-5.9-5.6-8.3-4.9-5.1-11.41-8.5-17.9-10.9a75.99 75.99 0 0 0-24.01-4.8c-1.99-.1-4 0-6 .1-.49 0-.49.8 0 .7 8.6-.4 17.2.7 25.41 3.2 7.3 2.2 14.5 5.5 20.3 10.6Zm31.593 94.7c-.4-.1-.7.5-.2.7 2.5.6 5 1.4 7.4 2.2-2.2.9-4.3 2.1-6.3 3.5-.4.3.1.8.4.5 2.2-1.6 4.5-2.8 7-3.8.2-.1.2-.3.1-.5 0 .1-.1 0-.2 0-2.7-1-5.4-1.9-8.2-2.6ZM301.404 246.904c.2 0 0-.6-.5-.5-3.8 1.1-8.8.6-11.3-2.7-2.3-2.9-1.7-6.9 0-9.9.9-1.6 2.1-3 3.5-4.1 1.7-1.3 3.5-2.4 5.3-3.6 1.6-1.2 3.1-2.5 3.9-4.4.8-1.8.7-3.8-.1-5.5-1.9-4.3-6.7-5.7-11-6.2-5-.5-10.1-.4-15.1-.8-4.6-.4-9.2-1.2-13.3-3.2-3.7-1.8-7.1-4.5-9.1-8.2-2-3.9-2.4-8.4-1.2-12.6 1.3-4.5 3.9-8.5 7.6-11.5.9-.8 1.8-1.5 2.8-2.1.4-.3 0-.8-.4-.6-4.1 2.6-7.3 6.3-9.5 10.6-1.9 4-2.4 8.5-1.3 12.8 2.2 8.7 11 13.4 19.2 14.8 5 .9 10.2.9 15.3 1.1 4.7.2 10.6.2 14 4 1.4 1.5 2.1 3.5 1.9 5.5-.3 2.1-1.8 3.7-3.4 5-1.7 1.3-3.6 2.4-5.4 3.7-1.5 1.1-2.8 2.4-3.8 4-1.9 2.9-2.8 6.8-1.2 10 1.8 3.8 6.2 5.2 10.1 4.9 1-.1 2-.3 3-.5Z\" fill=\"currentColor\" /><path d=\"M255.101 171.9c-.4.1-.4.8.1.7 2.5-.5 5.1-.9 7.7-1.2-1.6 1.8-3 3.8-4.1 5.9-.2.4.4.7.6.3 1.2-2.3 2.8-4.5 4.6-6.4.1-.2.1-.4-.1-.5-.2 0-.2-.1-.3-.1-2.9.2-5.7.7-8.5 1.3ZM99.7 69.3c4.6-.5 9.3 1.9 12.6 5 .3.3.8-.2.5-.5-.8-.8-1.7-1.5-2.6-2.1-3.6-2.5-8.4-4.1-12.8-2.7-4 1.3-6.5 5-7.2 9.1-.8 4.4.5 8.8 2.8 12.6 2.7 4.4 6.5 7.9 10 11.699 4 4.3 7.7 8.7 11.2 13.4 3.1 4.2 6.1 8.8 7.2 14.1.9 4.5.2 9.7-2.9 13.3-2.9 3.4-7.5 4.6-11.8 4.2-4.7-.4-8.9-2.8-12.3-6-3.7-3.4-6.5-7.8-9.1-12.1-.3-.5-.9-.1-.7.3.7 1.1 1.3 2.1 2 3.2 2.7 4.1 5.8 8.2 9.8 11.2 3.6 2.8 8 4.3 12.5 4.2 4.3-.1 8.5-2 11-5.6 2.6-3.8 3.1-8.9 2.1-13.5-1.2-5.1-4.2-9.7-7.3-13.9-3.4-4.6-7.2-9.1-11.1-13.3-3.6-3.7-7.4-7.3-10.1-11.8-2.3-3.8-3.5-8.4-2.4-12.8.4-2 1.4-3.8 2.8-5.3 1.6-1.5 3.6-2.5 5.8-2.7ZM269.6 89.305c5.7 4 12.6 5.8 19.3 7.4 6.9 1.7 13.9 3.2 20 6.8 5.5 3.2 10.2 8.3 11.4 14.8.6 3 .3 6-.9 8.8-1.3 3-3.5 5.4-5.9 7.6-4.7 4.4-10.4 8.3-12.3 14.8-.9 2.9-.6 6.1.9 8.7.7 1.3 1.7 2.399 2.8 3.3 1.3.9 2.5 1.7 3.9 2.4 1.4.8 2.4 2 3 3.5.5 1.3.6 2.799.3 4.1-.5 3.199-2.7 5.8-5 7.8-1.2 1-2.5 2-3.8 2.899-.4.301 0 .901.4.601 4.5-3.2 10-7.601 9.1-14-.2-1.3-.7-2.5-1.4-3.5-1-1.1-2.2-2.101-3.6-2.8-1.5-.7-2.8-1.7-3.9-2.9-1-1.1-1.7-2.5-2.1-3.9-2-6.9 3.6-12.9 8.3-17 4.6-4 9.8-8.3 10.9-14.7 1-5.801-1.5-11.801-5.4-16-4.5-4.901-11-7.7-17.3-9.5-7.1-2.1-14.5-3.3-21.4-6-5.7-2.3-11.1-5.9-14.3-11.2-7.2-11.8 1.5-25.7 11.6-32.5 1.4-.9 2.9-1.7 4.4-2.4.4-.2.2-.9-.2-.7-5.9 2.5-11.1 7.2-14.6 12.5-3.3 5.1-5.4 11.3-4.1 17.4 1.2 5.7 5.1 10.4 9.9 13.7Z\" fill=\"currentColor\" /><path d=\"M270.901 46.4c-.4.1-.4.8.1.7 2.5-.5 5.1-.9 7.7-1.1-1.6 1.8-3 3.8-4.2 5.9-.2.4.4.7.6.3 1.3-2.3 2.8-4.5 4.7-6.4.1-.2.1-.4-.1-.5-.2-.1-.3-.1-.3-.1-2.9.2-5.7.6-8.5 1.2ZM181.698 129.399c4.6 0 8.8-2.8 10.4-7.1.5-1.4.9-2.9 1.2-4.4.4-1.5 1.2-2.9 2.5-3.8 1.1-.8 2.5-1.3 3.9-1.5 3.2-.4 6.3.9 8.9 2.6 1.3.9 2.6 1.8 3.9 2.8.4.3.8-.3.5-.6-4.5-3.5-10.3-7.4-16.2-4.7-1.2.5-2.2 1.3-2.9 2.4-.8 1.3-1.4 2.7-1.6 4.2-.3 1.6-.9 3.2-1.7 4.6-.8 1.3-1.9 2.3-3.1 3.2-6 3.9-13.4.2-18.7-3.1-5.2-3.2-10.8-7-17.2-6.2-5.9.7-10.8 4.9-13.8 9.8-3.4 5.8-4.2 12.7-4.2 19.3 0 7.4 1.1 14.8.4 22.3-.6 6.1-2.4 12.3-6.6 16.9-9.2 10.3-25.1 6-34.4-1.7-1.3-1.1-2.5-2.2-3.5-3.5-.3-.4-.9.1-.6.4 4.1 5 10.1 8.5 16.2 10.4 5.8 1.8 12.4 1.9 17.8-1.1 5.2-2.8 8.5-7.9 10.3-13.4 2.1-6.7 1.9-13.7 1.6-20.6-.4-7-.9-14.2.7-21.2 1.5-6.3 5-12.2 10.8-15.2 2.6-1.4 5.7-2 8.7-1.7 3.2.4 6.2 1.8 9 3.4 5.5 3.2 11 7.6 17.7 7.5Z\" fill=\"currentColor\" /><path d=\"M96 182.598c-2.6-.6-5.1-1.4-7.5-2.7-.2-.1-.4 0-.5.1 0 .1 0 .3.1.4 1 2.7 2.3 5.3 3.6 7.8.2.4.9.1.7-.2-1.2-2.3-2.4-4.6-3.3-7 2.2 1 4.5 1.8 6.8 2.3.2 0 .3-.2.3-.4 0-.1-.1-.3-.2-.3ZM150.9 94.798c-3.8-6.4-11.9-7.7-18.2-10.1-3.3-1.3-6.7-3-8.9-5.9-2.2-2.9-2.7-6.8-1.4-10.2.6-1.7 1.7-3.1 3.1-4.2.4-.3-.2-.8-.5-.5-2.7 2.3-4.2 5.8-4 9.3.2 3.5 2.2 6.5 4.9 8.7 5.9 4.6 13.9 4.9 20.1 9 3.2 2.1 5.5 5.2 5.7 9.1.2 4-1.5 7.9-4 10.9-2.8 3.3-6.6 5.6-10.3 7.7-3.7 2.1-7.6 4.1-11.2 6.7-6.8 4.8-12.8 12-12.9 20.8 0 7.2 5.2 14.7 12.9 15 4.5.2 8.7-1.9 12.2-4.5 3.7-2.7 7.1-5.9 11.1-8.2 3.7-2.1 8-3.8 12.3-4 3.9-.2 8.1 1 9.8 4.8 1.7 3.6.7 7.9-1 11.3-1.9 3.9-4.8 7.3-6.5 11.3-1.5 3.6-2.2 8.1-.1 11.7 1.8 2.7 4.8 4.3 8.1 4.2 1.6 0 3.1-.4 4.4-1.2.3-.2-.1-.9-.5-.6-3 1.7-6.6 1.5-9.4-.5-3.3-2.4-3.9-6.7-2.9-10.5 2-8 10-13.7 9.3-22.5-.3-3.6-2.2-6.7-5.7-8-3.6-1.4-7.7-.8-11.3.3-4.1 1.3-8 3.3-11.4 6-3.6 2.7-7 5.9-11.1 7.9-3.8 1.8-8.2 2.4-12.1.4-3.2-1.8-5.6-4.7-6.7-8.3-2.7-8.4 2.4-16.9 8.5-22.3 3.4-2.8 7-5.2 10.9-7.2 3.7-2 7.4-4 10.7-6.6 3.1-2.4 5.5-5.6 6.9-9.3 1.2-3.5 1.1-7.3-.8-10.5ZM266.895 118.002c1.7-.5 3.5-.6 5.2-.3.5.1.5-.6.1-.7-3.5-.7-7.2.3-9.8 2.8-2.6 2.4-3.7 5.8-3.6 9.3.2 7.5 4.9 13.9 5.7 21.3.4 3.7-.6 7.5-3.4 10.2-2.9 2.6-7.1 3.8-11 3.8-4.3-.1-8.5-1.6-12.5-3.1-4-1.6-8-3.3-12.2-4.5-8-2.2-17.4-2.4-24.2 3.1-5.6 4.5-8.1 13.3-3.5 19.4 2.7 3.6 7 5.5 11.1 6.7 4.4 1.2 9 1.8 13.3 3.5 4 1.5 8 3.8 10.9 7 2.6 2.9 4.3 6.9 2.5 10.6-1.8 3.6-5.7 5.5-9.4 6.4-4.2 1-8.7.9-12.9 2.1-3.8 1.1-7.7 3.4-9.1 7.3-1 3.1-.3 6.5 1.8 9 1 1.2 2.3 2.1 3.7 2.7.2.1.4 0 .5-.3-.1-.6-.2-.8-.5-.9-3.2-1.2-5.3-4.2-5.5-7.6-.3-4.1 2.8-7.2 6.3-8.9 7.4-3.5 16.9-.9 23.3-6.9 2.6-2.5 3.8-5.9 2.7-9.4-1.2-3.7-4.2-6.5-7.3-8.6-3.6-2.4-7.6-4.1-11.9-5.1-4.4-1.1-9-1.7-13.2-3.7-3.8-1.8-7.1-4.8-7.9-9.1-.6-3.6.1-7.4 2.2-10.4 4.8-7.3 14.7-8.8 22.6-7.4 4.3.9 8.4 2.2 12.5 3.9 3.9 1.6 7.8 3.3 11.9 4.2 3.8.9 7.8.7 11.5-.5 3.4-1.3 6.4-3.7 7.7-7.2 2.6-6.9-1.5-14-3.6-20.5-1.1-3.4-1.9-7.1-1.1-10.7.9-3.6 3.6-6.4 7.1-7.5ZM110.604 220.504c3.8 4.1 9.2 6.5 14.7 7.2 6.9.9 13.9-.7 20.3-3.2 1.6-.6 3.2-1.3 4.7-2 .4-.2 0-.8-.4-.7-6.8 3.1-14.1 5.6-21.7 5.4-6-.2-12.1-2.4-16.4-6.6-2.2-2.1-3.8-4.7-4.7-7.6-1-3-1.4-6.2-2.4-9.3-1.6-5.8-7-9.8-13-9.5-6 .2-11.2 4.4-13.5 9.8-2.3 5.2-2 12 2.1 16.3.5.5 1 .9 1.5 1.3-.8 2.6-.9 5.3-.5 7.9 1.1 6 5.3 10.9 11 12.9 1.3.5 2.7.8 4.2.9.5 0 .5-.7 0-.7-5.8-.6-10.8-4.1-13.3-9.4-1.5-3.5-1.8-7.5-.7-11.1 3.5 2.1 8.4 2 11.5-.7 2.1-1.8 3.5-5.1 1.4-7.4-.9-1-2.2-1.6-3.5-1.7-1.5-.1-3 .3-4.2 1.1-2.6 1.6-4.4 4.4-5.5 7.2-.1.1-.1.3-.1.4-.3-.2-.5-.4-.8-.7-4.2-3.9-4.6-10.6-2.5-15.7 2.2-5.2 7.2-9.4 13-9.6 2.8-.1 5.5.7 7.8 2.3 2.5 1.7 3.9 4.4 4.7 7.2.9 2.8 1.3 5.9 2.2 8.8.8 2.7 2.2 5.1 4.1 7.2Zm-28.004.9c3.6 2.1 8.8 1.9 11.6-1.3.9-1.2 1.7-2.8 1.3-4.3-.4-1.3-1.4-2.3-2.7-2.7-2.9-1-5.8 1.1-7.6 3.3-1.1 1.5-2 3.1-2.6 5Z\" fill=\"currentColor\" /><path d=\"M91.203 237.597c-.3-.3-.8.2-.5.5 2.1 1.6 4 3.2 5.9 5-2.4-.1-4.8.2-7.2.7-.4.1-.3.8.2.7 2.6-.6 5.2-.8 7.9-.7.2 0 .3-.2.3-.4-.1-.1-.1-.1-.1-.2-2.1-2-4.2-3.9-6.5-5.6ZM239.904 176.903c6 .6 11.6-3.2 13.4-9 1.9-5.7-.3-12-4.5-16.1-4.1-4-10.6-6.1-16-3.7-.6.3-1.2.6-1.7 1-2.1-1.6-4.6-2.7-7.2-3.2-6-1-12 1.2-15.9 5.9-.9 1.1-1.7 2.3-2.3 3.6-.2.4.5.7.7.3 2.5-5.2 7.6-8.8 13.4-9.3 3.8-.2 7.6.9 10.7 3.2-3.2 2.6-4.8 7.1-3.4 11.1.9 2.6 3.6 5 6.5 3.9 1.2-.5 2.3-1.5 2.8-2.7.6-1.4.8-2.9.4-4.4-.6-3-2.6-5.7-4.9-7.7l-.3-.3c.3-.2.6-.4.9-.5 5.1-2.6 11.5-.7 15.6 3.1 4.1 3.9 6.4 10 4.5 15.5-.9 2.6-2.6 4.9-4.9 6.5-2.5 1.7-5.5 2.1-8.4 2-2.9-.2-6-.8-9-.9-2.8-.1-5.6.4-8.2 1.4-5.1 2.2-9.3 6.4-11.8 11.3-3.2 6.1-4.1 13.3-3.9 20.1 0 1.7.1 3.4.3 5.1 0 .5.8.4.7-.1-.6-7.4-.4-15.2 2.4-22.2 2.2-5.6 6.4-10.5 11.9-13.2 2.7-1.3 5.7-1.9 8.7-1.7 3.2.1 6.3.9 9.5 1Zm-8.701-26.803c-3.2 2.6-4.9 7.5-2.8 11.3.7 1.3 1.9 2.6 3.5 2.7 1.3.1 2.6-.5 3.4-1.6 1.9-2.5 1-5.9-.5-8.3-1-1.6-2.2-3-3.6-4.1Z\" fill=\"currentColor\" /><path d=\"M212.9 152.395c.4-.2.1-.9-.3-.6-2.2 1.4-4.4 2.7-6.8 3.8.9-2.2 1.5-4.6 1.8-7 .1-.4-.6-.5-.7-.1-.4 2.6-1.1 5.2-2.1 7.6-.1.2 0 .4.2.4.2.2.3.2.4.1 2.6-1.2 5.1-2.6 7.5-4.2Z\" fill=\"currentColor\" /><path d=\"M64.4 52.8c0-7-5.7-12.7-12.7-12.7-7 0-12.7 5.6-12.7 12.6s5.7 12.7 12.7 12.7c7 0 12.7-5.6 12.7-12.6Zm-22.4 0c0 5.4 4.3 9.7 9.7 9.7 5.4 0 9.7-4.3 9.7-9.7 0-5.4-4.4-9.7-9.7-9.7-5.3 0-9.7 4.3-9.7 9.7Z\" fill=\"#03D5B7\" /><path d=\"m351.898 160.898 12.6-3.9c.6-.2.9-.8.7-1.3-.2-.6-.8-.9-1.3-.7l-12.6 3.9c-.6.2-.9.8-.7 1.3.2.4.6.7 1 .7h.3ZM343.503 144.697c1.2.6 2.4.9 3.6.9.8 0 1.6-.1 2.2-.4 1.9-.7 3.6-2 4.5-3.8.9-1.8 1.2-3.9.5-5.8s-2-3.6-3.8-4.5c-1.8-.9-3.8-1.1-5.8-.5-1.9.7-3.6 2-4.5 3.8-.9 1.8-1.2 3.9-.5 5.8s2 3.5 3.8 4.5Zm-1.407-9.397c-.7 1.3-.8 2.9-.4 4.3s1.4 2.6 2.8 3.3c1.3.7 2.9.8 4.3.4s2.6-1.4 3.3-2.8c.7-1.3.8-2.9.4-4.3s-1.4-2.6-2.8-3.3c-.7-.4-1.6-.7-2.6-.7-.6 0-1.1.1-1.7.3-1.4.4-2.6 1.4-3.3 2.8ZM318.297 126.997l8.2-34.1c.2-.5-.2-1.1-.7-1.2-.5-.2-1.1.2-1.2.7l-8.2 34.1c-.2.5.2 1.1.7 1.2h.2c.4 0 .8-.3 1-.7ZM64.695 188.595l8.8-9.9c.4-.4.3-1-.1-1.4-.4-.4-1-.3-1.4.1l-8.8 9.9c-.4.4-.3 1 .1 1.4.2.2.5.3.7.3.3 0 .6-.1.7-.4ZM53.801 204.1c2.1-.2 3.9-1.1 5.3-2.6 1.3-1.5 2-3.5 1.9-5.5-.2-2.1-1.1-3.9-2.6-5.3-1.5-1.3-3.5-2-5.5-1.9-4.2.2-7.5 3.9-7.2 8.1.2 2.1 1.1 3.9 2.6 5.3 1.4 1.2 3.2 1.9 5.1 1.9h.4Zm-.703-13.3c-3.1.2-5.5 2.9-5.3 6 .1 1.5.8 2.9 1.9 3.9 1.1 1 2.6 1.5 4.1 1.4 1.5-.1 2.9-.8 3.9-1.9 1-1.1 1.5-2.6 1.4-4.1-.1-1.5-.8-2.9-1.9-3.9-1.1-.9-2.4-1.4-3.8-1.4h-.3Z\" fill=\"#FFC412\" /><path d=\"M42.005 258.701c-.1.4.1.8.5 1 .2.1.3.1.5.1s.4 0 .7-.2l26.9-22.5c.3-.3.4-.7.3-1.1-.2-.4-.5-.7-.9-.7l-24.7-2.2c-.2-.1-.5 0-.7.2-.2.2-.4.4-.4.7l-2.2 24.7ZM44.2 256.5l23.2-19.4-21.3-1.9-1.9 21.3Z\" fill=\"#03D5B7\" /><path d=\"M132.097 118.801c.3-.5.1-1.1-.4-1.4-3.2-1.7-9.1-1.2-9.4-1.2-.5.1-1 .6-.9 1.1.1.5.5 1 1.1.9 1.6-.2 6.1-.3 8.3.9.2.1.3.1.5.1.4 0 .7-.2.8-.4ZM100.504 122.2c2.8-4.9 6.9-5.2 7.1-5.2.5 0 .9-.5.9-1-.1-.5-.6-.9-1.1-.9-.2 0-5.3.4-8.7 6.2-.2.5-.1 1.1.4 1.4.2.1.3.1.5.1.3 0 .7-.2.9-.6ZM96.097 118.903c.6-2.2 2.4-5.2 2.4-5.2.2-.5.1-1.1-.4-1.4-.5-.2-1.1-.1-1.4.4-.1.2-1.9 3.3-2.6 5.8-.2.5.2 1.1.7 1.2h.3c.4 0 .8-.3 1-.8ZM368.4 263.1c0-.6-.4-1-1-1H211.6c-.6 0-1 .4-1 1s.4 1 1 1h155.8c.5 0 1-.4 1-1ZM203.1 263.1c0-.6-.4-1-1-1h-14.5c-.6 0-1 .4-1 1s.4 1 1 1h14.5c.6 0 1-.4 1-1Z\" fill=\"currentColor\" /><path d=\"M127.499 62.199c-1 2.8-1.7 5.7-2.2 8.5-2.2 2.5-3.9 5.4-4.9 8.6-1.3 4.4-1.1 12.1.1 20.2-1.6-.9-3-.7-4.5-.4-9.6 1.8-6.9 15 1.5 17.5.9.4 6.9 2.2 7.8 2.1 1.2 3.3 2.6 6 4.1 8-.3 8.1-.7 17-.5 17.3 5.3 8.7 18.2 19 25.4 17 6.9-2 4.5-21.4 4.4-22.1-.1-1.4-.1-2.8 0-4.2 4.1-1.5 16.3-5.9 18.8-10.7 3.5-7-7.3-48.2-9-52.7-2.1-5.6-4.5-9.8-6.9-11.6-9.7-7-24.6-5.3-34.1 2.5Z\" fill=\"#fff\" /><path d=\"M159.7 139.005v-3.5c4.9-1.8 16.2-6 18.7-11 3.8-7.7-7.6-49.7-9-53.5-1.5-4.2-4.1-9.7-7.2-12-9.8-7-25-5.9-35.3 2.6-.1.1-.2.2-.3.4-1 2.7-1.7 5.5-2.2 8.4-2.3 2.6-4 5.6-4.9 8.8-1.1 4.1-1.2 10.9-.1 19-1.2-.3-2.4-.1-3.5.1-4.1.8-6.7 3.7-6.9 7.7-.3 4.5 2.8 10.1 8.2 11.7.8.4 5.4 1.8 7.5 2.1 1.2 3.1 2.5 5.5 3.8 7.4l-.2 4.2c-.5 12.7-.5 12.8-.2 13.3 4.8 7.7 16.1 17.7 24.2 17.7.8 0 1.6-.1 2.2-.2 7-2.1 5.8-18.3 5.2-23.2Zm-38.001-39.302c.1.4-.1.7-.4 1-.3.2-.7.2-1 .1-1.3-.7-2.5-.6-3.9-.3-3.2.6-5.1 2.7-5.3 5.8-.2 3.7 2.3 8.4 6.8 9.7h.1c1 .4 6.5 2 7.4 2 .4 0 .9.3 1 .6 1.3 3.3 2.6 6 3.9 7.8.1.2.2.4.2.6l-.2 4.6c-.2 5.1-.4 11-.4 12.2 5.5 8.8 17.9 18.2 24.1 16.4 4.7-1.3 4.5-13.8 3.7-21v-.1c-.1-1.3-.1-2.7 0-4.3 0-.4.3-.8.7-.9l.6-.2c4.2-1.6 15.5-5.7 17.6-10 3.3-6.5-7.3-47.3-9-51.9-2.1-5.6-4.4-9.5-6.5-11.1-8.9-6.4-23.1-5.3-32.6 2.3-.9 2.6-1.6 5.3-2.1 8.1 0 .2-.1.4-.2.5-2.2 2.5-3.8 5.2-4.7 8.3-1.2 4-1.1 11.3.2 19.8Z\" fill=\"currentColor\" /><path d=\"M149.8 101.295c3.3-.5 2-7.8-1.1-7.3-3.6.6-2.2 7.8 1.1 7.3ZM167.598 97.405c3.3-.9 1.7-8.1-1.9-7.1-3 .8-1.3 8 1.9 7.1ZM157.9 119.7c.6-.1.9-.7.7-1.2 0-.2-1.1-3.6-6.9-4.3-.5 0-1 .4-1.1.9 0 .5.4 1 .9 1.1 4.4.6 5.3 2.8 5.3 2.9.2.4.6.7 1 .7.1 0 .2-.1.1-.1Z\" fill=\"currentColor\" /><path d=\"M162.1 109.8s5.1-.7 4.9-3.3c-.2-2.6-5.3-2.1-5.3-2.1l-2.4-15.3 2.8 20.7Z\" fill=\"#fff\" /><path d=\"M167.804 106.504c-.1-.8-.4-1.4-1-1.9-1.2-1.1-3.3-1.2-4.5-1.2l-2.2-14.4c0-.5-.6-.9-1.1-.8-.5 0-.9.6-.8 1.1l2.4 15.3c.1.5.6.9 1.1.8 1.1-.1 3.2 0 4 .7.2.1.3.3.3.5.1 1.2-2.8 2-4.1 2.2-.5 0-.9.6-.8 1.1.1.5.5.9 1 .9 0 0 .1 0-.1.1.6-.1 6.1-1 5.8-4.4ZM142.003 92.1c2.8-4 7.8-4.1 7.9-4.1.6 0 1-.4 1-1s-.5-1-1-1c-.2 0-6.1.1-9.5 4.9-.4.5-.3 1.1.2 1.4.2.1.4.2.6.2.3 0 .6-.1.8-.4ZM169.9 85.1c0-.5-.4-1-1-1 0 0-3.5-.1-6-2.5-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4 3.1 2.9 7.1 3 7.3 3 .6 0 1-.4 1.1-.9Z\" fill=\"currentColor\" /><path d=\"M151.998 108.698c5.4-2.4 7.7-8.7 5.3-14-1.2-2.5-3.3-4.5-5.9-5.5-2.7-1-5.5-.9-8.1.3-2.5 1.2-4.5 3.3-5.5 5.9-1 2.7-.9 5.5.3 8.1 1.7 3.9 5.6 6.2 9.6 6.2 1.5 0 3-.3 4.3-1ZM144.204 91.4c-4.3 2-6.2 7-4.3 11.3 2 4.3 7 6.2 11.3 4.3 4.3-2 6.2-7 4.3-11.3-.9-2.1-2.6-3.7-4.8-4.5-.9-.4-2-.6-3-.6-1.2 0-2.4.3-3.5.8ZM171.704 104.302c4.6-.7 7.6-5.6 6.8-11-.4-2.6-1.6-4.9-3.4-6.5-1.8-1.6-4.1-2.3-6.3-2-2.2.3-4.1 1.7-5.4 3.8-1.2 2.1-1.7 4.6-1.3 7.2.7 5 4.5 8.6 8.6 8.6.4 0 .7 0 1-.1ZM169.103 86.9c-1.6.2-3.1 1.3-4 2.9-1 1.7-1.4 3.7-1.1 5.8.6 4.3 4 7.4 7.4 6.8 3.4-.5 5.7-4.4 5.1-8.7-.3-2.1-1.3-4-2.7-5.3-1.1-1.1-2.5-1.6-3.9-1.6-.3 0-.5 0-.8.1Z\" fill=\"#FFC412\" /><path d=\"M138 101.1c.6 0 1-.4 1-1s-.5-1-1-1l-13.1.4c-.6 0-1 .4-1 1s.5 1 1 1l13.1-.4ZM157.395 97.502c.1-.1 2.5-2.1 5.2-.9.5.2 1.1 0 1.3-.5.2-.5 0-1.1-.5-1.3-3.8-1.8-7.2 1.1-7.3 1.2-.4.4-.5 1-.1 1.4.2.2.5.3.8.3.3 0 .5-.1.6-.2Z\" fill=\"#FFC412\" /><path d=\"M168.601 36.9c-3-1.5-6.9.7-8.6 5.1l-.2-.2c-2.5-1.8-5.9-1.3-7.7 1.2-1.9 2.4-3.1 5.3-3.7 8.3 0 0-10.2-.7-18.3.7-1.1.2-2.3.3-3.4.4-1.1.1-2.2.4-3.3.9-4.8 2.2-7.2 7.4-5.9 12.3-.9.1-1.8.4-2.7.8-4.9 2.2-6.6 7.2-5.8 12.7 1.2 10.1 9.1 31.301 16.7 29.701 5.8-1.2 3.4-23.5 3.4-23.5 6.3-.9 11.2-5.8 12.2-12 0 0 20.6 9.4 31.4-2.3 9-9.7 1.4-31.4-4.1-34.1Z\" fill=\"currentColor\" /><path d=\"M158.803 64.096c-1.5 1.6 14.9 9.9 14.9 9.9l.7 10.6 1.7.7 2.1 1.3 39 35-47.5 28.3s16.5 32.6 17.5 33.3l54.4-44.8c4.8-4.1 7.4-10.2 7.1-16.5-.4-6.7-4.2-12.8-10.1-16.1l-51.7-28.8-10.3-9.6-2.9-7.2c.5-2.4-1.1-4.8-3.5-5.2-.1 0-.2 0-.3-.1l-8.8-.6s-4.2-.2-3.8 2.4c.1.5.4.9.9 1l-.9 1.5c-.1 2.4 3 2.7 3 2.7l7.3.7 1.5 3.9s-8.8-4-10.3-2.4Z\" fill=\"#fff\" /><path d=\"m177.495 87.398 38 34-46.3 27.6c-.5.3-.6.8-.4 1.3 6.2 12.2 16.8 32.8 17.7 33.6.1.1.4.2.6.2.2 0 .5-.1.6-.2l54.4-44.8c5.1-4.2 7.9-10.7 7.5-17.3-.4-7.1-4.4-13.4-10.6-16.9l-51.3-28.7-10.1-9.3-2.7-6.7c.4-2.8-1.5-5.5-4.3-6.1-.2-.1-.3-.1-.5-.1l-8.9-.6c-.3 0-2.9-.1-4.2 1.3-.6.6-.8 1.4-.7 2.3 0 .4.2.8.5 1.1l-.4.7c-.1.2-.1.3-.1.5-.1 2.1 1.6 3.1 3 3.5-.5.1-.9.3-1.2.6-.3.3-.4.8-.3 1.2.4 2.2 9.3 7.1 15 10l.6 10.1c0 .4.2.8.6.9l1.6.6 1.9 1.2ZM175.6 67.8l-2.9-7.2c-.1-.2-.1-.4-.1-.6.4-1.9-.8-3.7-2.7-4.1h-.2l-8.8-.6c-.6 0-2.1.1-2.6.6-.1.1-.2.3-.2.7 0 .1.1.2.2.2.3.1.5.3.6.6.1.3.1.6-.1.9l-.7 1.3c.1 1.2 1.9 1.4 2.1 1.4l7.4.7c.4 0 .7.3.8.6l1.5 3.9c.1.4 0 .8-.3 1.1-.3.3-.7.3-1.1.2-3.5-1.6-7.1-2.7-8.6-2.8 1.7 1.7 8.2 5.4 14.1 8.4.3.2.5.5.5.8l.6 10 1.1.4c.1 0 .1.1.2.1l2.1 1.3.1.1 39 35c.2.2.4.5.3.8 0 .3-.2.6-.5.8L171 150.2c5.8 11.4 14.1 27.6 16.4 31.5l53.5-44.1c4.6-3.8 7.2-9.6 6.8-15.6-.4-6.4-4-12.2-9.6-15.3l-51.7-28.8c-.1 0-.1-.1-.2-.1l-10.3-9.6c-.1-.1-.2-.2-.3-.4Zm-8.3-3.1-.4-1.1-3.7-.3c1.3.4 2.8.9 4.1 1.4Z\" fill=\"currentColor\" /><path d=\"m113.702 65.5-1.1.7-8.9 6.8s-43.9 33.2-52.7 42.5c-4.1 4.3-5.6 15.7-.6 20.8 13 13.3 39.3 37.2 39.3 37.2l22-25.1-30.8-27.3 25.9-26 .1.1 16.7-17.2 2.7.8c1.4.2 2.9-.2 4-1.2 1-.9 2-1.9 2.8-2.9.6-.8 1.9-2.9 2.1-3.2.6-.6 1.4-1.1 2.2-1.5 0 0 13.6-.2 14.7-.8 1-.6 2.3-2.6-1-3.2l-12.9-2 7.5-3.8 3.6-.1c-.5-2.3-2.4-3.9-4.7-4-4-.3-4.7.6-4.7.6s-2-4.2-3-4.5c-1.5-.5-3.1-.7-4.7-.8-1.3.5-2.4 1.2-3.4 2.2 0 0-4.8-2.6-5.9-1-1.1 2.1-2 4.3-2.6 6.5l-6.6 6.4Z\" fill=\"#fff\" /><path d=\"m82.398 121 24.7-24.8c.2-.1.4-.2.5-.3l16.3-16.8 2.1.6h.1c1.8.3 3.6-.2 4.8-1.4 1-.9 2-2 2.9-3.1.4-.4.9-1.2 1.3-1.9.2-.4.6-1 .7-1.1.5-.5 1.1-.9 1.7-1.2 6.3-.1 14-.4 15-1 .9-.6 1.8-1.7 1.6-2.9-.2-.8-.8-1.7-3-2.1l-9.8-1.6 4.5-2.3 3.4-.1c.3 0 .6-.2.8-.4.2-.2.3-.5.2-.8-.5-2.7-2.9-4.7-5.6-4.8-2.1-.2-3.5 0-4.3.2-1-1.9-2.2-3.8-3.2-4.1-1.6-.5-3.3-.8-5-.8-.2 0-.3.1-.4.1-1.2.4-2.2 1.1-3.2 1.9-1.8-.8-5.3-2.2-6.6-.3-.1 0-.1.1-.1.1-1.1 2.1-1.9 4.3-2.6 6.5l-6.3 6.1-1 .6c0 .1-.1.1-.1.1l-8.6 6.7c-.1 0-.1.1-.2.1-1.8 1.3-44 33.3-52.9 42.5-4.3 4.5-6.3 16.5-.6 22.2 12.9 13.2 39.1 37.1 39.4 37.3.2.2.5.3.7.3.4 0 .6-.2.8-.4l22-25.1c.3-.4.3-1-.1-1.4l-29.9-26.6Zm55.001-52c6.3-.1 13.4-.4 14.3-.7.3-.2.6-.7.6-.8 0 0-.2-.3-1.3-.5l-13-2.1c-.4-.1-.8-.4-.8-.8-.1-.4.2-.9.5-1l7.5-3.8c.1-.1.3-.1.4-.1l2.2-.1c-.7-1.2-1.9-2-3.3-2.1-2.9-.2-3.8.2-4 .3-.2.2-.5.3-.8.3-.3 0-.6-.3-.8-.6-.9-1.9-2-3.7-2.5-4-1.4-.4-2.8-.7-4.2-.7-1.1.4-2.1 1.1-2.9 1.9-.3.3-.8.4-1.2.2-2.1-1.1-4.2-1.6-4.6-1.3-1 2-1.9 4.1-2.5 6.2 0 .2-.1.3-.3.4l-6.6 6.4c-.1.1-.1.1-.2.1l-.9.8-8.7 6.8c-.1 0-.2.1-.3.1-3.2 2.4-44 33.4-52.4 42.2-3.6 3.9-5.3 14.7-.6 19.5 11.6 11.9 34.1 32.5 38.5 36.5l20.7-23.5-30-26.7c-.2-.2-.3-.4-.3-.7 0-.3.1-.5.3-.7l25.9-26c.1-.1.3-.2.4-.3l16.4-16.8c.3-.3.6-.4 1-.3l2.7.8c1.1.2 2.2-.2 3.1-1 1-.9 1.9-1.8 2.7-2.8.3-.4.8-1.1 1.2-1.8.6-1 .8-1.3 1-1.5.7-.7 1.5-1.2 2.4-1.7.1-.1.3-.1.4-.1Z\" fill=\"currentColor\" /><path d=\"M192.1 206c1.2 16.7 6.5 20.9 6.5 20.9l-97.2 23.7-3.2-55.3L93 190l-24.6-26.4c11.6-8.9 18-21.2 18.4-38.5l13.5 13c2.3 2.2 5.2 3.7 8.3 4.4 3.8.8 7.8 1 11.8.7l6.2-.5c11.1 13.3 31.7 15.5 35-.8l4.7.6c2.3.3 4.7-.5 6.4-2.1l1-.9h4.2l24.9-9.8s16.3 21.1 17.6 31.4L191.2 184l.9 22Z\" fill=\"#fff\" /><path d=\"M67.4 163.196c0 .3.1.6.3.8l24.6 26.5 5.2 5.3c.4.4 1 .4 1.4 0 .4-.4.4-1 0-1.4l-5.2-5.2-23.8-25.6c11.1-8.9 17-20.8 17.8-36.3l11.8 11.6c2.4 2.4 5.5 4 8.8 4.7 4 .8 8 1.1 12.1.7l5.6-.5c7 8.1 17.5 12.2 25.8 10.1 5.3-1.4 9-5.2 10.4-10.9l3.8.5c2.6.3 5.3-.5 7.2-2.4l.7-.7h3.8c.2 0 .3-.1.4-.1l24.2-9.5c2.6 3.4 15.3 20.6 16.9 29.8l-28.7 22.6c-.3.2-.4.5-.4.8l.9 22c.9 12.2 4 18 5.7 20.3l-95.6 23.3c-.5.1-.8.7-.7 1.2.1.5.5.8 1 .8h.2l97.2-23.7c.3-.1.6-.4.7-.8.1-.4 0-.8-.3-1 0-.1-5-4.3-6.1-20.2l-.8-21.5 28.8-22.6c.3-.2.4-.6.4-.9-1.3-10.5-17.1-31-17.8-31.9-.3-.3-.8-.5-1.2-.3l-24.7 9.7h-4c-.3 0-.5.1-.7.3l-1 .9c-1.5 1.4-3.5 2.1-5.6 1.8l-4.7-.6c-.5-.1-1 .3-1.1.8-1 5.4-4.2 9-9.1 10.2-7.6 1.9-17.7-2.3-24.1-9.9-.3-.3-.6-.4-.9-.4l-6.2.5c-3.8.3-7.7.1-11.5-.7-3-.7-5.7-2.1-7.9-4.2l-13.5-13c-.3-.3-.7-.4-1.1-.2-.3.1-.6.5-.6.9-.4 16.3-6.3 28.7-18 37.7-.2.2-.4.4-.4.7Z\" fill=\"currentColor\" /><path d=\"M103.905 268.198c.2.4.6.7 1 .7h.2c.1 0 15.4-4.5 17.9-23.3 0-.5-.4-1-.9-1.1-.5 0-1 .4-1.1.9-1.9 15-12.3 20.1-15.5 21.3-12.9-45.2-3.9-83-3.8-83.4.2-.5-.2-1.1-.7-1.2-.5-.2-1.1.2-1.2.7-.1.4-9.4 39.2 4.1 85.4ZM143.104 250.405c.6 0 1-.6.9-1.1l-2.3-16.1c0-.6-.6-1-1.1-.9-.6 0-1 .6-.9 1.1l2.3 16.1c.1.5.5.9 1 .9h.1ZM152.005 249.205c.6 0 1-.6.9-1.1l-2.3-16.7c0-.6-.6-1-1.1-.9-.6 0-1 .6-.9 1.1l2.3 16.7c.1.5.5.9 1 .9h.1Z\" fill=\"currentColor\" /><path d=\"m99.6 243.801 94.401-23.9c.5-.1.8-.7.7-1.2-.1-.5-.7-.8-1.2-.7l-94.4 23.9c-.5.1-.8.7-.7 1.2.1.5.6.8 1 .8.1 0 .2 0 .2-.1Z\" fill=\"currentColor\" /><path d=\"M368.198 43.5c.6-3.2-.6-6.4-3.1-8.5-2.5-2.1-5.9-2.7-9-1.6l-49.2 17.9c-1.5.5-2.8 1.5-3.8 2.7-3.2 3.8-2.8 9.6 1.1 12.8l40.1 33.599c1.2 1 2.7 1.7 4.2 2 5 .9 9.8-2.3 10.6-7.3l9.1-51.6Zm-2.603-.404c.4-2.3-.4-4.5-2.2-6-1.8-1.5-4.2-1.9-6.3-1.1l-49.2 17.9c-3.3 1.2-5 4.9-3.8 8.2.4 1.1 1.1 2 1.9 2.7l40.1 33.7c2.7 2.2 6.7 1.9 9-.8.7-.9 1.2-1.9 1.4-3l9.1-51.6Z\" fill=\"#E0E0E0\" /><path d=\"m348.5 49.3-12.2 16.3 3.3 2.7 13.8-14.9-4.9-4.1ZM335.602 69.902l-.1-.1c-1.4-1.2-3.5-1-4.7.4l-.1.1c-1.1 1.5-.9 3.6.6 4.8l.1.1c1.4 1.2 3.6 1 4.7-.5 0-.2.1-.2.1-.2 1.1-1.4.8-3.5-.6-4.6Z\" fill=\"#E0E0E0\" /><path d=\"M261.3 248s3.2 9.9-6.8 15.1h47.3s-11.3-3.9-8.4-15.1h49.1c2.3 0 4.1-1.8 4.1-4.1v-93.1c.1-2.3-1.8-4.1-4.1-4.1H210.7c-2.3 0-4.1 1.8-4.1 4.1v93.1c0 2.3 1.8 4.1 4.1 4.1h50.6Z\" fill=\"currentColor\" /><path d=\"M278.203 238c-1-.8-2.4-.8-3.3 0-1.1.9-1.2 2.5-.3 3.6 0 .1.1.1.2.2 1 .8 2.4.8 3.3 0 1.1-.9 1.2-2.5.3-3.6-.1 0-.2-.1-.2-.2Z\" fill=\"#455A64\" /><path d=\"M208.8 231v-79.7c0-1.6 1.4-2.9 3-2.9h129.6c1.6 0 3 1.3 3 3V231H208.8Z\" fill=\"#03D5B7\" /><path d=\"M208.8 151.6v3.7h135.6V151c0-1.5-1.2-2.6-2.6-2.6H211.9c-1.7 0-3.1 1.4-3.1 3.2Z\" fill=\"#EBEBEB\" /><path d=\"M213.1 151c-.6 0-1 .4-1 1s.5 1 1 1c.6 0 1-.5 1-1 0-.6-.4-1-1-1ZM215.9 151c-.6 0-1 .4-1 1s.5 1 1 1c.6 0 1-.5 1-1 0-.6-.4-1-1-1Z\" fill=\"#E0E0E0\" /><path d=\"M218.6 151c-.6 0-1 .4-1 1s.5 1 1 1c.6 0 1-.5 1-1 0-.6-.4-1-1-1Z\" fill=\"#03D5B7\" /><path d=\"M277.1 248c-23.1 0-41.9 0-41.9.1s18.7.1 41.9.1c23.1 0 41.9-.1 41.9-.1 0-.1-18.8-.1-41.9-.1Z\" fill=\"#455A64\" /><path d=\"M245.4 182.8c-.8 0-1.4.1-2 .1l1-7.3h10.8v-3.9h-14.1l-1.9 14.9c1-.1 2.1-.2 3.7-.2 5.5 0 8.2 2.4 8.2 6.4s-3.1 6.4-6.6 6.4c-2.5 0-4.8-.9-6-1.6l-1.1 3.6c1.4.9 4.2 1.7 7.2 1.7 6.7 0 11.2-4.6 11.2-10.5 0-6.3-4.8-9.6-10.4-9.6ZM268.5 175.1c3.9 0 5.3 2.6 5.3 5.6 0 4.6-3.6 8.8-10.1 15.5l-3.2 3.4v2.9h18.8v-4h-12.4v-.1l2.5-2.6c5.4-5.4 9.2-10.1 9.2-15.7 0-4.6-2.8-8.9-9.1-8.9-3.4 0-6.4 1.3-8.3 2.9l1.4 3.4c1.4-1.1 3.5-2.4 5.9-2.4ZM293 203c6.3 0 10.1-5.7 10.1-16.1 0-9.3-3.3-15.6-9.8-15.6-6.4 0-10.2 5.9-10.2 15.9 0 9.4 3.4 15.7 9.9 15.8Zm.2-28c-3.1 0-5.2 4.3-5.2 12 0 7.6 1.9 12.1 5.1 12.1 3.9 0 5.2-5.7 5.2-12.1 0-7.3-1.6-12-5.1-12ZM231.995 202.4c.9 0 1.7-.5 2.2-1.2.5-.7.5-1.7 0-2.5l-7.2-12.6c-.4-.8-1.3-1.3-2.19-1.3-.91 0-1.7.5-2.2 1.2l-7.3 12.5c-.51.8-.51 1.7 0 2.5.4.8 1.3 1.3 2.19 1.3l14.5.1Zm-7.1-16.8c-.6 0-1.2.4-1.5.9l-7.3 12.5c-.5.8-.2 1.9.6 2.4.3.1.6.2.9.2l14.5.1c1 0 1.7-.8 1.7-1.8 0-.3 0-.6-.2-.9l-7.2-12.6c-.3-.5-.9-.8-1.5-.8Z\" fill=\"#fff\" /><path d=\"M225.7 190.8h-1.8l.3 5.6h1.2l.3-5.6ZM223.8 198.404c0 .5.4.9 1 .9.5 0 .9-.4.9-.9v-.1c0-.5-.4-.9-.9-.8-.6 0-1 .4-1 .9ZM338.795 198.7l-7.2-12.6c-.39-.8-1.3-1.3-2.19-1.3-.9 0-1.7.5-2.2 1.2l-7.3 12.5c-.51.8-.51 1.7 0 2.5.39.8 1.3 1.3 2.19 1.3l14.5.1c.9 0 1.7-.5 2.2-1.2.5-.7.5-1.7 0-2.5Zm-10.799-12.2-7.3 12.5c-.5.8-.2 1.9.6 2.4.3.1.6.2.9.2l14.5.1c1 0 1.7-.8 1.7-1.8 0-.3 0-.6-.2-.9l-7.2-12.6c-.3-.5-.9-.8-1.5-.8s-1.2.4-1.5.9Z\" fill=\"#fff\" /><path d=\"M330.3 190.8h-1.8l.3 5.6h1.2l.3-5.6ZM328.4 198.404c0 .5.4.9 1 .9.5 0 .9-.4.9-.9v-.1c0-.5-.4-.9-.9-.8-.6 0-1 .4-1 .9ZM240.7 215c1.9 0 3.2-1.5 3.2-3.9s-1.3-3.9-3.2-3.9c-1.9 0-3.2 1.5-3.2 3.9s1.4 3.9 3.2 3.9Zm0-7c-1.4 0-2.3 1.2-2.3 3.1 0 1.9.9 3.2 2.3 3.2 1.4-.1 2.3-1.3 2.3-3.2 0-1.9-.9-3.1-2.3-3.1ZM252 214.8v-4.4c0-.6.1-1.5.1-2.2l-.6 1.7-1.5 4.1h-.6l-1.5-4.1-.6-1.7c0 .7.1 1.5.1 2.2v4.4h-.8v-7.5h1l1.5 4.1c.2.5.4 1.1.5 1.6h.1c.2-.5.3-1.1.5-1.6l1.5-4.1h1v7.5h-.7ZM258.8 208c.8 0 1.3.3 1.7.7l.5-.6c-.4-.4-1.1-.9-2.1-.9-2 0-3.4 1.5-3.4 3.9s1.3 3.9 3.2 3.9c1 0 1.8-.4 2.3-.9V211h-2.4v.7h1.6v2.1c-.3.3-.8.5-1.4.5-1.7 0-2.6-1.3-2.6-3.2 0-1.9 1-3.1 2.6-3.1ZM266.4 214.7c0 .1-.1.2-.2.2h-1.1c.1.2.2.5.2.7.7 0 1.1 0 1.4-.1.2-.1.3-.3.3-.7v-8.2h-2.9v3.7c0 1.5-.1 3.5-.8 5 .2 0 .5.2.6.3.5-1 .7-2.3.8-3.5h1.7v2.6Zm0-5h-1.7V211.5h1.7v-1.8Zm-1.7-.6h1.7v-1.8h-1.7v1.8Zm5.6.2c.8 0 1.3 0 1.6-.1.3-.1.4-.2.4-.6v-2H268v9h.6v-4.9h.3c.3 1 .8 2.1 1.4 2.9-.5.6-1 1.1-1.6 1.4.1.1.3.3.4.5.6-.3 1.1-.7 1.6-1.3.5.6 1.1 1.1 1.7 1.4.1-.1.2-.4.4-.5-.7-.3-1.3-.8-1.8-1.4.7-1 1.2-2.1 1.5-3.5l-.4-.2h-3.5v-2.8h3v1.3c0 .1 0 .2-.2.2h-1.3c.1.2.2.4.2.6Zm.4 3.9c.5-.7.9-1.5 1.1-2.4h-2.3c.3.9.7 1.7 1.2 2.4ZM278.9 206.3l-.7-.1c-.5.9-1.6 1.9-3 2.7.1.1.3.3.4.5.6-.3 1.1-.7 1.5-1 .4.5 1 1 1.6 1.3-1.3.4-2.7.7-4 .8.1.1.3.4.3.6 1.5-.1 3.1-.5 4.5-1 1.2.5 2.6.8 4.2.9.1-.2.3-.4.4-.6-1.4 0-2.7-.2-3.8-.6 1.1-.6 2.1-1.3 2.7-2.2l-.5-.4h-4.3c.3-.3.5-.6.7-.9Zm-3.8 9.4c2.1-.5 3.4-1.3 4-3h3.2c-.1 1.5-.4 2.1-.6 2.3-.1.1-.2.1-.4.1s-.9 0-1.5-.1c.1.2.2.4.2.6h1.5c.4 0 .6-.1.8-.3.3-.3.6-1.1.8-3v-.3.1h-3.9c.1-.3.1-.7.2-1l-.7-.1c0 .3-.1.7-.2 1h-3.1v.7h2.9c-.6 1.3-1.7 2.1-3.6 2.4.2.2.3.4.4.6Zm4.4-6.2c1-.4 1.9-.9 2.5-1.6h-4.2l-.2.2c.4.6 1.1 1 1.9 1.4ZM292.4 211.1c.12.1.25.2.38.3h2.32v-.6h-1.8l.2-.3c-.3-.3-1-.6-1.5-.8l-.4.4c.4.1 1 .4 1.3.6h-3c.3-.4.5-.8.7-1.1l-.7-.1c-.2.4-.4.8-.7 1.1H286v.6h2.6c-.7.6-1.6 1.2-2.8 1.6.2.1.3.3.4.5.3-.1.6-.2.8-.3v2.5h.6v-.3h1.8v.3h.7v-3.1h-2.2c.7-.4 1.2-.8 1.7-1.3h2c.5.5 1.1.9 1.8 1.3h-2.2v3.1h.6v-.3h1.9v.3h.7v-2.6c.2.1.4.1.6.2.1-.1.2-.4.4-.5-.94-.26-1.87-.66-2.62-1.2h-.38v-.3Zm.38.3c-.13-.1-.26-.2-.38-.3v.3h.38Zm-6.08-4.6v2.7h3.2v-2.7h-3.2Zm.8.5v1.5h1.9v-1.5h-1.9Zm.2 5.8v1.6h1.8v-1.6h-1.8Zm6.8-6.3h-3.3v2.7h3.3v-2.7Zm-.8 6.3h-1.9v1.6h1.9v-1.6Zm-1.8-5.8v1.5h2v-1.5h-2ZM298.7 213.2h2.1v1.5c0 .1-.1.2-.2.2h-1c.1.2.2.4.2.6.6 0 1.1 0 1.3-.1.2-.1.3-.3.3-.6h.1v-5.5h-3.3v2.2c0 1.1-.1 2.6-.9 3.7.2 0 .4.3.5.4.5-.7.8-1.6.9-2.4Zm-.6-6.6v2h8v-2h-.7v1.4h-3v-1.8h-.7v1.8h-2.9v-1.4h-.7Zm2.7 5h-2c0 .3 0 .7-.1 1.1h2.1v-1.1Zm-2-.6h2v-1.1h-2v1.1Zm2.9 4.3c.2 0 .4.3.5.4.5-.7.8-1.6.9-2.4h2.3v1.5c0 .2-.1.2-.2.2h-1.1c.1.2.2.4.2.6.7 0 1.1 0 1.4-.1.2-.1.3-.3.3-.7h.1v-5.4h-3.5v2.5c0 1.1-.1 2.4-.9 3.4Zm3.7-3.8h-2.2v1.2h2.2v-1.2Zm-2.2-.5h2.2v-1.1h-2.2v1.1ZM312.7 214.8h-1.9c.1.2.3.5.3.7 1.1 0 1.7 0 2.1-.1.4-.1.5-.3.5-.8v-4.5c1.3-.6 2.7-1.7 3.6-2.7l-.4-.5H309.3v.7h6.7c-.8.8-2 1.6-3 2.1v4.9c0 .1-.1.2-.3.2Z\" fill=\"#fff\" /><path d=\"M356.5 234.3h-22.2l3.6 29.9c4.9 2.6 10.1 2.3 15.4 0l3.2-29.9Z\" fill=\"#FDFEFF\" /><path d=\"M357.4 234.4c0-.3-.2-.6-.3-.8-.1-.2-.4-.3-.7-.3h-22.2c-.2 0-.5.1-.7.3-.1.2-.2.5-.2.8l3.6 29.9c0 .4.2.6.5.8 2.5 1.3 5.1 1.9 7.8 1.9s5.6-.6 8.4-1.9c.3-.1.6-.4.6-.8l3.2-29.9Zm-5.1 29.2 3.1-28.3h-20l3.4 28.3c4.1 2 8.6 2 13.5 0Z\" fill=\"currentColor\" /><path d=\"M333.4 232.401v3.9c8.4 1.5 16.4 1.6 24.1 0v-3.9l-2.4.1-.6-2.1-16.8-2.1c-.5-.1-.9.2-1 .6l-1.2 3.5h-2.1Z\" fill=\"#FDFEFF\" /><path d=\"M358.3 232.397c0-.3-.1-.5-.3-.7-.2-.2-.4-.3-.7-.3h-1.5l-.4-1.4c-.1-.4-.4-.7-.8-.7l-16.8-2.1c-.9-.1-1.8.4-2.1 1.3l-1 2.9h-1.4c-.6 0-1 .4-1 1v3.9c0 .5.3.9.8 1 4.4.8 8.6 1.2 12.7 1.2s8-.4 11.7-1.2c.5-.1.8-.5.8-1v-3.9Zm-24 3.103c7.9 1.3 15.3 1.3 22.1 0v-2h-1.3c-.4 0-.8-.3-1-.7l-.5-1.5-16.1-2-1.2 3.5c-.1.4-.5.7-.9.7h-1.1v2Z\" fill=\"currentColor\" /><path d=\"M356 245.2c-7 .8-14 .8-21 0l.9 9.1c6.8.8 13.2.9 19 0l1.1-9.1Z\" fill=\"#FDFEFF\" /><path d=\"M335 244.1c-.3 0-.6.1-.8.3-.2.2-.3.5-.3.8l.9 9.1c.1.5.4.8.9.9 3.8.5 7.2.7 10.4.7s6.2-.2 8.9-.7c.4-.1.7-.5.8-.9l1.1-9.1c0-.3-.1-.6-.3-.8-.2-.2-.5-.3-.8-.3-6.9.8-13.9.8-20.8 0Zm19 9.3.9-7.1c-6.2.6-12.5.6-18.8 0l.7 7.1c6.6.7 12.2.7 17.2 0Z\" fill=\"currentColor\" /><path d=\"m343.396 250.7.6 1.3c.4.9 1.5 1.4 2.5 1.1l-2.3-5c-.9.5-1.2 1.6-.8 2.6ZM346.9 252.802c.9-.5 1.2-1.6.8-2.6l-.6-1.3c-.5-.8-1.5-1.3-2.5-1l2.3 4.9Z\" fill=\"#03D5B7\" /></g></svg>\n  </div>\n</template>\n"
  },
  {
    "path": "src/lib/wavtools/index.js",
    "content": "import { WavPacker } from './lib/wav_packer.js';\nimport { AudioAnalysis } from './lib/analysis/audio_analysis.js';\nimport { WavStreamPlayer } from './lib/wav_stream_player.js';\nimport { WavRecorder } from './lib/wav_recorder.js';\n\nexport { AudioAnalysis, WavPacker, WavStreamPlayer, WavRecorder };\n"
  },
  {
    "path": "src/lib/wavtools/lib/analysis/audio_analysis.js",
    "content": "import {\n  noteFrequencies,\n  noteFrequencyLabels,\n  voiceFrequencies,\n  voiceFrequencyLabels,\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n  /**\n   * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n   * returns human-readable formatting and labels\n   * @param {AnalyserNode} analyser\n   * @param {number} sampleRate\n   * @param {Float32Array} [fftResult]\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {AudioAnalysisOutputType}\n   */\n  static getFrequencies(\n    analyser,\n    sampleRate,\n    fftResult,\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30,\n  ) {\n    if (!fftResult) {\n      fftResult = new Float32Array(analyser.frequencyBinCount);\n      analyser.getFloatFrequencyData(fftResult);\n    }\n    const nyquistFrequency = sampleRate / 2;\n    const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n    let outputValues;\n    let frequencies;\n    let labels;\n    if (analysisType === 'music' || analysisType === 'voice') {\n      const useFrequencies =\n        analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n      const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n      for (let i = 0; i < fftResult.length; i++) {\n        const frequency = i * frequencyStep;\n        const amplitude = fftResult[i];\n        for (let n = useFrequencies.length - 1; n >= 0; n--) {\n          if (frequency > useFrequencies[n]) {\n            aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n            break;\n          }\n        }\n      }\n      outputValues = aggregateOutput;\n      frequencies =\n        analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n      labels =\n        analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n    } else {\n      outputValues = Array.from(fftResult);\n      frequencies = outputValues.map((_, i) => frequencyStep * i);\n      labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n    }\n    // We normalize to {0, 1}\n    const normalizedOutput = outputValues.map((v) => {\n      return Math.max(\n        0,\n        Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1),\n      );\n    });\n    const values = new Float32Array(normalizedOutput);\n    return {\n      values,\n      frequencies,\n      labels,\n    };\n  }\n\n  /**\n   * Creates a new AudioAnalysis instance for an HTMLAudioElement\n   * @param {HTMLAudioElement} audioElement\n   * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n   * @returns {AudioAnalysis}\n   */\n  constructor(audioElement, audioBuffer = null) {\n    this.fftResults = [];\n    if (audioBuffer) {\n      /**\n       * Modified from\n       * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n       *\n       * We do this to populate FFT values for the audio if provided an `audioBuffer`\n       * The reason to do this is that Safari fails when using `createMediaElementSource`\n       * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n       */\n      const { length, sampleRate } = audioBuffer;\n      const offlineAudioContext = new OfflineAudioContext({\n        length,\n        sampleRate,\n      });\n      const source = offlineAudioContext.createBufferSource();\n      source.buffer = audioBuffer;\n      const analyser = offlineAudioContext.createAnalyser();\n      analyser.fftSize = 8192;\n      analyser.smoothingTimeConstant = 0.1;\n      source.connect(analyser);\n      // limit is :: 128 / sampleRate;\n      // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n      const renderQuantumInSeconds = 1 / 60;\n      const durationInSeconds = length / sampleRate;\n      const analyze = (index) => {\n        const suspendTime = renderQuantumInSeconds * index;\n        if (suspendTime < durationInSeconds) {\n          offlineAudioContext.suspend(suspendTime).then(() => {\n            const fftResult = new Float32Array(analyser.frequencyBinCount);\n            analyser.getFloatFrequencyData(fftResult);\n            this.fftResults.push(fftResult);\n            analyze(index + 1);\n          });\n        }\n        if (index === 1) {\n          offlineAudioContext.startRendering();\n        } else {\n          offlineAudioContext.resume();\n        }\n      };\n      source.start(0);\n      analyze(1);\n      this.audio = audioElement;\n      this.context = offlineAudioContext;\n      this.analyser = analyser;\n      this.sampleRate = sampleRate;\n      this.audioBuffer = audioBuffer;\n    } else {\n      const audioContext = new AudioContext();\n      const track = audioContext.createMediaElementSource(audioElement);\n      const analyser = audioContext.createAnalyser();\n      analyser.fftSize = 8192;\n      analyser.smoothingTimeConstant = 0.1;\n      track.connect(analyser);\n      analyser.connect(audioContext.destination);\n      this.audio = audioElement;\n      this.context = audioContext;\n      this.analyser = analyser;\n      this.sampleRate = this.context.sampleRate;\n      this.audioBuffer = null;\n    }\n  }\n\n  /**\n   * Gets the current frequency domain data from the playing audio track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30,\n  ) {\n    let fftResult = null;\n    if (this.audioBuffer && this.fftResults.length) {\n      const pct = this.audio.currentTime / this.audio.duration;\n      const index = Math.min(\n        (pct * this.fftResults.length) | 0,\n        this.fftResults.length - 1,\n      );\n      fftResult = this.fftResults[index];\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      fftResult,\n      analysisType,\n      minDecibels,\n      maxDecibels,\n    );\n  }\n\n  /**\n   * Resume the internal AudioContext if it was suspended due to the lack of\n   * user interaction when the AudioAnalysis was instantiated.\n   * @returns {Promise<true>}\n   */\n  async resumeIfSuspended() {\n    if (this.context.state === 'suspended') {\n      await this.context.resume();\n    }\n    return true;\n  }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n"
  },
  {
    "path": "src/lib/wavtools/lib/analysis/constants.js",
    "content": "/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n  4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n  6644.88, 7040.0, 7458.62, 7902.13,\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n  'C',\n  'C#',\n  'D',\n  'D#',\n  'E',\n  'F',\n  'F#',\n  'G',\n  'G#',\n  'A',\n  'A#',\n  'B',\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n  for (let f = 0; f < octave8Frequencies.length; f++) {\n    const freq = octave8Frequencies[f];\n    noteFrequencies.push(freq / Math.pow(2, 8 - i));\n    noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n  }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n  return (\n    noteFrequencies[i] > voiceFrequencyRange[0] &&\n    noteFrequencies[i] < voiceFrequencyRange[1]\n  );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n  return (\n    noteFrequencies[i] > voiceFrequencyRange[0] &&\n    noteFrequencies[i] < voiceFrequencyRange[1]\n  );\n});\n"
  },
  {
    "path": "src/lib/wavtools/lib/wav_packer.js",
    "content": "/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n  /**\n   * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n   * @param {Float32Array} float32Array\n   * @returns {ArrayBuffer}\n   */\n  static floatTo16BitPCM(float32Array) {\n    const buffer = new ArrayBuffer(float32Array.length * 2);\n    const view = new DataView(buffer);\n    let offset = 0;\n    for (let i = 0; i < float32Array.length; i++, offset += 2) {\n      let s = Math.max(-1, Math.min(1, float32Array[i]));\n      view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n    }\n    return buffer;\n  }\n\n  /**\n   * Concatenates two ArrayBuffers\n   * @param {ArrayBuffer} leftBuffer\n   * @param {ArrayBuffer} rightBuffer\n   * @returns {ArrayBuffer}\n   */\n  static mergeBuffers(leftBuffer, rightBuffer) {\n    const tmpArray = new Uint8Array(\n      leftBuffer.byteLength + rightBuffer.byteLength\n    );\n    tmpArray.set(new Uint8Array(leftBuffer), 0);\n    tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n    return tmpArray.buffer;\n  }\n\n  /**\n   * Packs data into an Int16 format\n   * @private\n   * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n   * @param {number} arg value to pack\n   * @returns\n   */\n  _packData(size, arg) {\n    return [\n      new Uint8Array([arg, arg >> 8]),\n      new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24]),\n    ][size];\n  }\n\n  /**\n   * Packs audio into \"audio/wav\" Blob\n   * @param {number} sampleRate\n   * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n   * @returns {WavPackerAudioType}\n   */\n  pack(sampleRate, audio) {\n    if (!audio?.bitsPerSample) {\n      throw new Error(`Missing \"bitsPerSample\"`);\n    } else if (!audio?.channels) {\n      throw new Error(`Missing \"channels\"`);\n    } else if (!audio?.data) {\n      throw new Error(`Missing \"data\"`);\n    }\n    const { bitsPerSample, channels, data } = audio;\n    const output = [\n      // Header\n      'RIFF',\n      this._packData(\n        1,\n        4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n      ), // Length\n      'WAVE',\n      // chunk 1\n      'fmt ', // Sub-chunk identifier\n      this._packData(1, 16), // Chunk length\n      this._packData(0, 1), // Audio format (1 is linear quantization)\n      this._packData(0, channels.length),\n      this._packData(1, sampleRate),\n      this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n      this._packData(0, (channels.length * bitsPerSample) / 8),\n      this._packData(0, bitsPerSample),\n      // chunk 2\n      'data', // Sub-chunk identifier\n      this._packData(\n        1,\n        (channels[0].length * channels.length * bitsPerSample) / 8\n      ), // Chunk length\n      data,\n    ];\n    const blob = new Blob(output, { type: 'audio/mpeg' });\n    const url = URL.createObjectURL(blob);\n    return {\n      blob,\n      url,\n      channelCount: channels.length,\n      sampleRate,\n      duration: data.byteLength / (channels.length * sampleRate * 2),\n    };\n  }\n}\n\nglobalThis.WavPacker = WavPacker;\n"
  },
  {
    "path": "src/lib/wavtools/lib/wav_recorder.js",
    "content": "import { AudioProcessorSrc } from './worklets/audio_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n  /**\n   * Create a new WavRecorder instance\n   * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n   * @returns {WavRecorder}\n   */\n  constructor({\n    sampleRate = 44100,\n    outputToSpeakers = false,\n    debug = false,\n  } = {}) {\n    // Script source\n    this.scriptSrc = AudioProcessorSrc;\n    // Config\n    this.sampleRate = sampleRate;\n    this.outputToSpeakers = outputToSpeakers;\n    this.debug = !!debug;\n    this._deviceChangeCallback = null;\n    this._devices = [];\n    // State variables\n    this.stream = null;\n    this.processor = null;\n    this.source = null;\n    this.node = null;\n    this.recording = false;\n    // Event handling with AudioWorklet\n    this._lastEventId = 0;\n    this.eventReceipts = {};\n    this.eventTimeout = 5000;\n    // Process chunks of audio\n    this._chunkProcessor = () => {};\n    this._chunkProcessorSize = void 0;\n    this._chunkProcessorBuffer = {\n      raw: new ArrayBuffer(0),\n      mono: new ArrayBuffer(0),\n    };\n  }\n\n  /**\n   * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n   * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n   * @param {number} sampleRate\n   * @param {number} fromSampleRate\n   * @returns {Promise<DecodedAudioType>}\n   */\n  static async decode(audioData, sampleRate = 44100, fromSampleRate = -1) {\n    const context = new AudioContext({ sampleRate });\n    let arrayBuffer;\n    let blob;\n    if (audioData instanceof Blob) {\n      if (fromSampleRate !== -1) {\n        throw new Error(\n          `Can not specify \"fromSampleRate\" when reading from Blob`,\n        );\n      }\n      blob = audioData;\n      arrayBuffer = await blob.arrayBuffer();\n    } else if (audioData instanceof ArrayBuffer) {\n      if (fromSampleRate !== -1) {\n        throw new Error(\n          `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`,\n        );\n      }\n      arrayBuffer = audioData;\n      blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n    } else {\n      let float32Array;\n      let data;\n      if (audioData instanceof Int16Array) {\n        data = audioData;\n        float32Array = new Float32Array(audioData.length);\n        for (let i = 0; i < audioData.length; i++) {\n          float32Array[i] = audioData[i] / 0x8000;\n        }\n      } else if (audioData instanceof Float32Array) {\n        float32Array = audioData;\n      } else if (audioData instanceof Array) {\n        float32Array = new Float32Array(audioData);\n      } else {\n        throw new Error(\n          `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`,\n        );\n      }\n      if (fromSampleRate === -1) {\n        throw new Error(\n          `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`,\n        );\n      } else if (fromSampleRate < 3000) {\n        throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n      }\n      if (!data) {\n        data = WavPacker.floatTo16BitPCM(float32Array);\n      }\n      const audio = {\n        bitsPerSample: 16,\n        channels: [float32Array],\n        data,\n      };\n      const packer = new WavPacker();\n      const result = packer.pack(fromSampleRate, audio);\n      blob = result.blob;\n      arrayBuffer = await blob.arrayBuffer();\n    }\n    const audioBuffer = await context.decodeAudioData(arrayBuffer);\n    const values = audioBuffer.getChannelData(0);\n    const url = URL.createObjectURL(blob);\n    return {\n      blob,\n      url,\n      values,\n      audioBuffer,\n    };\n  }\n\n  /**\n   * Logs data in debug mode\n   * @param {...any} arguments\n   * @returns {true}\n   */\n  log() {\n    if (this.debug) {\n      this.log(...arguments);\n    }\n    return true;\n  }\n\n  /**\n   * Retrieves the current sampleRate for the recorder\n   * @returns {number}\n   */\n  getSampleRate() {\n    return this.sampleRate;\n  }\n\n  /**\n   * Retrieves the current status of the recording\n   * @returns {\"ended\"|\"paused\"|\"recording\"}\n   */\n  getStatus() {\n    if (!this.processor) {\n      return 'ended';\n    } else if (!this.recording) {\n      return 'paused';\n    } else {\n      return 'recording';\n    }\n  }\n\n  /**\n   * Sends an event to the AudioWorklet\n   * @private\n   * @param {string} name\n   * @param {{[key: string]: any}} data\n   * @param {AudioWorkletNode} [_processor]\n   * @returns {Promise<{[key: string]: any}>}\n   */\n  async _event(name, data = {}, _processor = null) {\n    _processor = _processor || this.processor;\n    if (!_processor) {\n      throw new Error('Can not send events without recording first');\n    }\n    const message = {\n      event: name,\n      id: this._lastEventId++,\n      data,\n    };\n    _processor.port.postMessage(message);\n    const t0 = new Date().valueOf();\n    while (!this.eventReceipts[message.id]) {\n      if (new Date().valueOf() - t0 > this.eventTimeout) {\n        throw new Error(`Timeout waiting for \"${name}\" event`);\n      }\n      await new Promise((res) => setTimeout(() => res(true), 1));\n    }\n    const payload = this.eventReceipts[message.id];\n    delete this.eventReceipts[message.id];\n    return payload;\n  }\n\n  /**\n   * Sets device change callback, remove if callback provided is `null`\n   * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n   * @returns {true}\n   */\n  listenForDeviceChange(callback) {\n    if (callback === null && this._deviceChangeCallback) {\n      navigator.mediaDevices.removeEventListener(\n        'devicechange',\n        this._deviceChangeCallback,\n      );\n      this._deviceChangeCallback = null;\n    } else if (callback !== null) {\n      // Basically a debounce; we only want this called once when devices change\n      // And we only want the most recent callback() to be executed\n      // if a few are operating at the same time\n      let lastId = 0;\n      let lastDevices = [];\n      const serializeDevices = (devices) =>\n        devices\n          .map((d) => d.deviceId)\n          .sort()\n          .join(',');\n      const cb = async () => {\n        let id = ++lastId;\n        const devices = await this.listDevices();\n        if (id === lastId) {\n          if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n            lastDevices = devices;\n            callback(devices.slice());\n          }\n        }\n      };\n      navigator.mediaDevices.addEventListener('devicechange', cb);\n      cb();\n      this._deviceChangeCallback = cb;\n    }\n    return true;\n  }\n\n  /**\n   * Manually request permission to use the microphone\n   * @returns {Promise<true>}\n   */\n  async requestPermission() {\n    const permissionStatus = await navigator.permissions.query({\n      name: 'microphone',\n    });\n    if (permissionStatus.state === 'denied') {\n      window.alert('You must grant microphone access to use this feature.');\n    } else if (permissionStatus.state === 'prompt') {\n      try {\n        const stream = await navigator.mediaDevices.getUserMedia({\n          audio: true,\n        });\n        const tracks = stream.getTracks();\n        tracks.forEach((track) => track.stop());\n      } catch (e) {\n        window.alert('You must grant microphone access to use this feature.');\n      }\n    }\n    return true;\n  }\n\n  /**\n   * List all eligible devices for recording, will request permission to use microphone\n   * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n   */\n  async listDevices() {\n    if (\n      !navigator.mediaDevices ||\n      !('enumerateDevices' in navigator.mediaDevices)\n    ) {\n      throw new Error('Could not request user devices');\n    }\n    await this.requestPermission();\n    const devices = await navigator.mediaDevices.enumerateDevices();\n    const audioDevices = devices.filter(\n      (device) => device.kind === 'audioinput',\n    );\n    const defaultDeviceIndex = audioDevices.findIndex(\n      (device) => device.deviceId === 'default',\n    );\n    const deviceList = [];\n    if (defaultDeviceIndex !== -1) {\n      let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n      let existingIndex = audioDevices.findIndex(\n        (device) => device.groupId === defaultDevice.groupId,\n      );\n      if (existingIndex !== -1) {\n        defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n      }\n      defaultDevice.default = true;\n      deviceList.push(defaultDevice);\n    }\n    return deviceList.concat(audioDevices);\n  }\n\n  /**\n   * Begins a recording session and requests microphone permissions if not already granted\n   * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n   * @param {string} [deviceId] if no device provided, default device will be used\n   * @returns {Promise<true>}\n   */\n  async begin(deviceId) {\n    if (this.processor) {\n      throw new Error(\n        `Already connected: please call .end() to start a new session`,\n      );\n    }\n\n    if (\n      !navigator.mediaDevices ||\n      !('getUserMedia' in navigator.mediaDevices)\n    ) {\n      throw new Error('Could not request user media');\n    }\n    try {\n      const config = { audio: true };\n      if (deviceId) {\n        config.audio = { deviceId: { exact: deviceId } };\n      }\n      this.stream = await navigator.mediaDevices.getUserMedia(config);\n    } catch (err) {\n      throw new Error('Could not start media stream');\n    }\n\n    const context = new AudioContext({ sampleRate: this.sampleRate });\n    const source = context.createMediaStreamSource(this.stream);\n    // Load and execute the module script.\n    try {\n      await context.audioWorklet.addModule(this.scriptSrc);\n    } catch (e) {\n      console.error(e);\n      throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n    }\n    const processor = new AudioWorkletNode(context, 'audio_processor');\n    processor.port.onmessage = (e) => {\n      const { event, id, data } = e.data;\n      if (event === 'receipt') {\n        this.eventReceipts[id] = data;\n      } else if (event === 'chunk') {\n        if (this._chunkProcessorSize) {\n          const buffer = this._chunkProcessorBuffer;\n          this._chunkProcessorBuffer = {\n            raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n            mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n          };\n          if (\n            this._chunkProcessorBuffer.mono.byteLength >=\n            this._chunkProcessorSize\n          ) {\n            this._chunkProcessor(this._chunkProcessorBuffer);\n            this._chunkProcessorBuffer = {\n              raw: new ArrayBuffer(0),\n              mono: new ArrayBuffer(0),\n            };\n          }\n        } else {\n          this._chunkProcessor(data);\n        }\n      }\n    };\n\n    const node = source.connect(processor);\n    const analyser = context.createAnalyser();\n    analyser.fftSize = 8192;\n    analyser.smoothingTimeConstant = 0.1;\n    node.connect(analyser);\n    if (this.outputToSpeakers) {\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Warning: Output to speakers may affect sound quality,\\n' +\n          'especially due to system audio feedback preventative measures.\\n' +\n          'use only for debugging',\n      );\n      analyser.connect(context.destination);\n    }\n\n    this.source = source;\n    this.node = node;\n    this.analyser = analyser;\n    this.processor = processor;\n    return true;\n  }\n\n  /**\n   * Gets the current frequency domain data from the recording track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30,\n  ) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      null,\n      analysisType,\n      minDecibels,\n      maxDecibels,\n    );\n  }\n\n  /**\n   * Pauses the recording\n   * Keeps microphone stream open but halts storage of audio\n   * @returns {Promise<true>}\n   */\n  async pause() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    } else if (!this.recording) {\n      throw new Error('Already paused: please call .record() first');\n    }\n    if (this._chunkProcessorBuffer.raw.byteLength) {\n      this._chunkProcessor(this._chunkProcessorBuffer);\n    }\n    this.log('Pausing ...');\n    await this._event('stop');\n    this.recording = false;\n    return true;\n  }\n\n  /**\n   * Start recording stream and storing to memory from the connected audio source\n   * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n   * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n   * @returns {Promise<true>}\n   */\n  async record(chunkProcessor = () => {}, chunkSize = 8192) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    } else if (this.recording) {\n      throw new Error('Already recording: please call .pause() first');\n    } else if (typeof chunkProcessor !== 'function') {\n      throw new Error(`chunkProcessor must be a function`);\n    }\n    this._chunkProcessor = chunkProcessor;\n    this._chunkProcessorSize = chunkSize;\n    this._chunkProcessorBuffer = {\n      raw: new ArrayBuffer(0),\n      mono: new ArrayBuffer(0),\n    };\n    this.log('Recording ...');\n    await this._event('start');\n    this.recording = true;\n    return true;\n  }\n\n  /**\n   * Clears the audio buffer, empties stored recording\n   * @returns {Promise<true>}\n   */\n  async clear() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    await this._event('clear');\n    return true;\n  }\n\n  /**\n   * Reads the current audio stream data\n   * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n   */\n  async read() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    this.log('Reading ...');\n    const result = await this._event('read');\n    return result;\n  }\n\n  /**\n   * Saves the current audio stream to a file\n   * @param {boolean} [force] Force saving while still recording\n   * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n   */\n  async save(force = false) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    if (!force && this.recording) {\n      throw new Error(\n        'Currently recording: please call .pause() first, or call .save(true) to force',\n      );\n    }\n    this.log('Exporting ...');\n    const exportData = await this._event('export');\n    const packer = new WavPacker();\n    const result = packer.pack(this.sampleRate, exportData.audio);\n    return result;\n  }\n\n  /**\n   * Ends the current recording session and saves the result\n   * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n   */\n  async end() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n\n    const _processor = this.processor;\n\n    this.log('Stopping ...');\n    await this._event('stop');\n    this.recording = false;\n    const tracks = this.stream.getTracks();\n    tracks.forEach((track) => track.stop());\n\n    this.log('Exporting ...');\n    const exportData = await this._event('export', {}, _processor);\n\n    this.processor.disconnect();\n    this.source.disconnect();\n    this.node.disconnect();\n    this.analyser.disconnect();\n    this.stream = null;\n    this.processor = null;\n    this.source = null;\n    this.node = null;\n\n    const packer = new WavPacker();\n    const result = packer.pack(this.sampleRate, exportData.audio);\n    return result;\n  }\n\n  /**\n   * Performs a full cleanup of WavRecorder instance\n   * Stops actively listening via microphone and removes existing listeners\n   * @returns {Promise<true>}\n   */\n  async quit() {\n    this.listenForDeviceChange(null);\n    if (this.processor) {\n      await this.end();\n    }\n    return true;\n  }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n"
  },
  {
    "path": "src/lib/wavtools/lib/wav_stream_player.js",
    "content": "import { StreamProcessorSrc } from './worklets/stream_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n  /**\n   * Creates a new WavStreamPlayer instance\n   * @param {{sampleRate?: number}} options\n   * @returns {WavStreamPlayer}\n   */\n  constructor({ sampleRate = 44100 } = {}) {\n    this.scriptSrc = StreamProcessorSrc;\n    this.sampleRate = sampleRate;\n    this.context = null;\n    this.stream = null;\n    this.analyser = null;\n    this.trackSampleOffsets = {};\n    this.interruptedTrackIds = {};\n  }\n\n  /**\n   * Connects the audio context and enables output to speakers\n   * @returns {Promise<true>}\n   */\n  async connect() {\n    this.context = new AudioContext({ sampleRate: this.sampleRate });\n    if (this.context.state === 'suspended') {\n      await this.context.resume();\n    }\n    try {\n      await this.context.audioWorklet.addModule(this.scriptSrc);\n    } catch (e) {\n      console.error(e);\n      throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n    }\n    const analyser = this.context.createAnalyser();\n    analyser.fftSize = 8192;\n    analyser.smoothingTimeConstant = 0.1;\n    this.analyser = analyser;\n    return true;\n  }\n\n  /**\n   * Gets the current frequency domain data from the playing track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30\n  ) {\n    if (!this.analyser) {\n      throw new Error('Not connected, please call .connect() first');\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      null,\n      analysisType,\n      minDecibels,\n      maxDecibels\n    );\n  }\n\n  /**\n   * Starts audio streaming\n   * @private\n   * @returns {Promise<true>}\n   */\n  _start() {\n    const streamNode = new AudioWorkletNode(this.context, 'stream_processor');\n    streamNode.connect(this.context.destination);\n    streamNode.port.onmessage = (e) => {\n      const { event } = e.data;\n      if (event === 'stop') {\n        streamNode.disconnect();\n        this.stream = null;\n      } else if (event === 'offset') {\n        const { requestId, trackId, offset } = e.data;\n        const currentTime = offset / this.sampleRate;\n        this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n      }\n    };\n    this.analyser.disconnect();\n    streamNode.connect(this.analyser);\n    this.stream = streamNode;\n    return true;\n  }\n\n  /**\n   * Adds 16BitPCM data to the currently playing audio stream\n   * You can add chunks beyond the current play point and they will be queued for play\n   * @param {ArrayBuffer|Int16Array} arrayBuffer\n   * @param {string} [trackId]\n   * @returns {Int16Array}\n   */\n  add16BitPCM(arrayBuffer, trackId = 'default') {\n    if (typeof trackId !== 'string') {\n      throw new Error(`trackId must be a string`);\n    } else if (this.interruptedTrackIds[trackId]) {\n      return;\n    }\n    if (!this.stream) {\n      this._start();\n    }\n    let buffer;\n    if (arrayBuffer instanceof Int16Array) {\n      buffer = arrayBuffer;\n    } else if (arrayBuffer instanceof ArrayBuffer) {\n      buffer = new Int16Array(arrayBuffer);\n    } else {\n      throw new Error(`argument must be Int16Array or ArrayBuffer`);\n    }\n    this.stream.port.postMessage({ event: 'write', buffer, trackId });\n    return buffer;\n  }\n\n  /**\n   * Gets the offset (sample count) of the currently playing stream\n   * @param {boolean} [interrupt]\n   * @returns {{trackId: string|null, offset: number, currentTime: number}}\n   */\n  async getTrackSampleOffset(interrupt = false) {\n    if (!this.stream) {\n      return null;\n    }\n    const requestId = crypto.randomUUID();\n    this.stream.port.postMessage({\n      event: interrupt ? 'interrupt' : 'offset',\n      requestId,\n    });\n    let trackSampleOffset;\n    while (!trackSampleOffset) {\n      trackSampleOffset = this.trackSampleOffsets[requestId];\n      await new Promise((r) => setTimeout(() => r(), 1));\n    }\n    const { trackId } = trackSampleOffset;\n    if (interrupt && trackId) {\n      this.interruptedTrackIds[trackId] = true;\n    }\n    return trackSampleOffset;\n  }\n\n  /**\n   * Strips the current stream and returns the sample offset of the audio\n   * @param {boolean} [interrupt]\n   * @returns {{trackId: string|null, offset: number, currentTime: number}}\n   */\n  async interrupt() {\n    return this.getTrackSampleOffset(true);\n  }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n"
  },
  {
    "path": "src/lib/wavtools/lib/worklets/audio_processor.js",
    "content": "const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n  constructor() {\n    super();\n    this.port.onmessage = this.receive.bind(this);\n    this.initialize();\n  }\n\n  initialize() {\n    this.foundAudio = false;\n    this.recording = false;\n    this.chunks = [];\n  }\n\n  /**\n   * Concatenates sampled chunks into channels\n   * Format is chunk[Left[], Right[]]\n   */\n  readChannelData(chunks, channel = -1, maxChannels = 9) {\n    let channelLimit;\n    if (channel !== -1) {\n      if (chunks[0] && chunks[0].length - 1 < channel) {\n        throw new Error(\n          \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n        );\n      }\n      channelLimit = channel + 1;\n    } else {\n      channel = 0;\n      channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n    }\n    const channels = [];\n    for (let n = channel; n < channelLimit; n++) {\n      const length = chunks.reduce((sum, chunk) => {\n        return sum + chunk[n].length;\n      }, 0);\n      const buffers = chunks.map((chunk) => chunk[n]);\n      const result = new Float32Array(length);\n      let offset = 0;\n      for (let i = 0; i < buffers.length; i++) {\n        result.set(buffers[i], offset);\n        offset += buffers[i].length;\n      }\n      channels[n] = result;\n    }\n    return channels;\n  }\n\n  /**\n   * Combines parallel audio data into correct format,\n   * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n   */\n  formatAudioData(channels) {\n    if (channels.length === 1) {\n      // Simple case is only one channel\n      const float32Array = channels[0].slice();\n      const meanValues = channels[0].slice();\n      return { float32Array, meanValues };\n    } else {\n      const float32Array = new Float32Array(\n        channels[0].length * channels.length\n      );\n      const meanValues = new Float32Array(channels[0].length);\n      for (let i = 0; i < channels[0].length; i++) {\n        const offset = i * channels.length;\n        let meanValue = 0;\n        for (let n = 0; n < channels.length; n++) {\n          float32Array[offset + n] = channels[n][i];\n          meanValue += channels[n][i];\n        }\n        meanValues[i] = meanValue / channels.length;\n      }\n      return { float32Array, meanValues };\n    }\n  }\n\n  /**\n   * Converts 32-bit float data to 16-bit integers\n   */\n  floatTo16BitPCM(float32Array) {\n    const buffer = new ArrayBuffer(float32Array.length * 2);\n    const view = new DataView(buffer);\n    let offset = 0;\n    for (let i = 0; i < float32Array.length; i++, offset += 2) {\n      let s = Math.max(-1, Math.min(1, float32Array[i]));\n      view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n    }\n    return buffer;\n  }\n\n  /**\n   * Retrieves the most recent amplitude values from the audio stream\n   * @param {number} channel\n   */\n  getValues(channel = -1) {\n    const channels = this.readChannelData(this.chunks, channel);\n    const { meanValues } = this.formatAudioData(channels);\n    return { meanValues, channels };\n  }\n\n  /**\n   * Exports chunks as an audio/wav file\n   */\n  export() {\n    const channels = this.readChannelData(this.chunks);\n    const { float32Array, meanValues } = this.formatAudioData(channels);\n    const audioData = this.floatTo16BitPCM(float32Array);\n    return {\n      meanValues: meanValues,\n      audio: {\n        bitsPerSample: 16,\n        channels: channels,\n        data: audioData,\n      },\n    };\n  }\n\n  receive(e) {\n    const { event, id } = e.data;\n    let receiptData = {};\n    switch (event) {\n      case 'start':\n        this.recording = true;\n        break;\n      case 'stop':\n        this.recording = false;\n        break;\n      case 'clear':\n        this.initialize();\n        break;\n      case 'export':\n        receiptData = this.export();\n        break;\n      case 'read':\n        receiptData = this.getValues();\n        break;\n      default:\n        break;\n    }\n    // Always send back receipt\n    this.port.postMessage({ event: 'receipt', id, data: receiptData });\n  }\n\n  sendChunk(chunk) {\n    const channels = this.readChannelData([chunk]);\n    const { float32Array, meanValues } = this.formatAudioData(channels);\n    const rawAudioData = this.floatTo16BitPCM(float32Array);\n    const monoAudioData = this.floatTo16BitPCM(meanValues);\n    this.port.postMessage({\n      event: 'chunk',\n      data: {\n        mono: monoAudioData,\n        raw: rawAudioData,\n      },\n    });\n  }\n\n  process(inputList, outputList, parameters) {\n    // Copy input to output (e.g. speakers)\n    // Note that this creates choppy sounds with Mac products\n    const sourceLimit = Math.min(inputList.length, outputList.length);\n    for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n      const input = inputList[inputNum];\n      const output = outputList[inputNum];\n      const channelCount = Math.min(input.length, output.length);\n      for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n        input[channelNum].forEach((sample, i) => {\n          output[channelNum][i] = sample;\n        });\n      }\n    }\n    const inputs = inputList[0];\n    // There's latency at the beginning of a stream before recording starts\n    // Make sure we actually receive audio data before we start storing chunks\n    let sliceIndex = 0;\n    if (!this.foundAudio) {\n      for (const channel of inputs) {\n        sliceIndex = 0; // reset for each channel\n        if (this.foundAudio) {\n          break;\n        }\n        if (channel) {\n          for (const value of channel) {\n            if (value !== 0) {\n              // find only one non-zero entry in any channel\n              this.foundAudio = true;\n              break;\n            } else {\n              sliceIndex++;\n            }\n          }\n        }\n      }\n    }\n    if (inputs && inputs[0] && this.foundAudio && this.recording) {\n      // We need to copy the TypedArray, because the \\`process\\`\n      // internals will reuse the same buffer to hold each input\n      const chunk = inputs.map((input) => input.slice(sliceIndex));\n      this.chunks.push(chunk);\n      this.sendChunk(chunk);\n    }\n    return true;\n  }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n  type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n"
  },
  {
    "path": "src/lib/wavtools/lib/worklets/stream_processor.js",
    "content": "export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n  constructor() {\n    super();\n    this.hasStarted = false;\n    this.hasInterrupted = false;\n    this.outputBuffers = [];\n    this.bufferLength = 128;\n    this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n    this.writeOffset = 0;\n    this.trackSampleOffsets = {};\n    this.port.onmessage = (event) => {\n      if (event.data) {\n        const payload = event.data;\n        if (payload.event === 'write') {\n          const int16Array = payload.buffer;\n          const float32Array = new Float32Array(int16Array.length);\n          for (let i = 0; i < int16Array.length; i++) {\n            float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n          }\n          this.writeData(float32Array, payload.trackId);\n        } else if (\n          payload.event === 'offset' ||\n          payload.event === 'interrupt'\n        ) {\n          const requestId = payload.requestId;\n          const trackId = this.write.trackId;\n          const offset = this.trackSampleOffsets[trackId] || 0;\n          this.port.postMessage({\n            event: 'offset',\n            requestId,\n            trackId,\n            offset,\n          });\n          if (payload.event === 'interrupt') {\n            this.hasInterrupted = true;\n          }\n        } else {\n          throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n        }\n      }\n    };\n  }\n\n  writeData(float32Array, trackId = null) {\n    let { buffer } = this.write;\n    let offset = this.writeOffset;\n    for (let i = 0; i < float32Array.length; i++) {\n      buffer[offset++] = float32Array[i];\n      if (offset >= buffer.length) {\n        this.outputBuffers.push(this.write);\n        this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n        buffer = this.write.buffer;\n        offset = 0;\n      }\n    }\n    this.writeOffset = offset;\n    return true;\n  }\n\n  process(inputs, outputs, parameters) {\n    const output = outputs[0];\n    const outputChannelData = output[0];\n    const outputBuffers = this.outputBuffers;\n    if (this.hasInterrupted) {\n      this.port.postMessage({ event: 'stop' });\n      return false;\n    } else if (outputBuffers.length) {\n      this.hasStarted = true;\n      const { buffer, trackId } = outputBuffers.shift();\n      for (let i = 0; i < outputChannelData.length; i++) {\n        outputChannelData[i] = buffer[i] || 0;\n      }\n      if (trackId) {\n        this.trackSampleOffsets[trackId] =\n          this.trackSampleOffsets[trackId] || 0;\n        this.trackSampleOffsets[trackId] += buffer.length;\n      }\n      return true;\n    } else if (this.hasStarted) {\n      this.port.postMessage({ event: 'stop' });\n      return false;\n    } else {\n      return true;\n    }\n  }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n  type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n"
  },
  {
    "path": "src/locales/en-US.ts",
    "content": "export default {\n  common: {\n    add: 'Add',\n    addSuccess: 'Add Success',\n    edit: 'Edit',\n    editSuccess: 'Edit Success',\n    delete: 'Delete',\n    deleteSuccess: 'Delete Success',\n    save: 'Save',\n    saveSuccess: 'Save Success',\n    reset: 'Reset',\n    action: 'Action',\n    export: 'Export',\n    exportSuccess: 'Export Success',\n    import: 'Import',\n    importSuccess: 'Import Success',\n    clear: 'Clear',\n    clearSuccess: 'Clear Success',\n    yes: 'Yes',\n    no: 'No',\n    confirm: 'Confirm',\n    download: 'Download',\n    noData: 'No Data',\n    wrong: 'Something went wrong, please try again later.',\n    success: 'Success',\n    failed: 'Failed',\n    verify: 'Verify',\n    unauthorizedTips: 'Unauthorized, please verify first.',\n    stopResponding: 'Stop Responding',\n  },\n  chat: {\n    newChatButton: 'New Chat',\n    //placeholder: 'Ask me anything...(Shift + Enter = line break, \"/\" to trigger prompts)',\n    placeholder: 'Ask me anything, or paste screenshots or drag the file .(Shift + Enter = line break, \"/\" to trigger prompts)',\n    placeholderMobile: 'Ask me anything...',\n    copy: 'Copy',\n    copied: 'Copied',\n    copyCode: 'Copy Code',\n    clearChat: 'Clear Chat',\n    clearChatConfirm: 'Are you sure to clear this chat?',\n    exportImage: 'Export Image',\n    exportImageConfirm: 'Are you sure to export this chat to png?',\n    exportSuccess: 'Export Success',\n    exportFailed: 'Export Failed',\n    usingContext: 'Context Mode',\n    turnOnContext: 'In the current mode, sending messages will carry previous chat records.',\n    turnOffContext: 'In the current mode, sending messages will not carry previous chat records.',\n    deleteMessage: 'Delete Message',\n    deleteMessageConfirm: 'Are you sure to delete this message?',\n    deleteHistoryConfirm: 'Are you sure to clear this history?',\n    clearHistoryConfirm: 'Are you sure to clear chat history?',\n    preview: 'Preview',\n    showRawText: 'Show as raw text',\n  },\n  setting: {\n    setting: 'Setting',\n    general: 'General',\n    advanced: 'Advanced',\n    config: 'Config',\n    avatarLink: 'Avatar Link',\n    name: 'Name',\n    description: 'Description',\n    role: 'Role',\n    temperature: 'Temperature',\n    top_p: 'Top_p',\n    resetUserInfo: 'Reset UserInfo',\n    chatHistory: 'ChatHistory',\n    theme: 'Theme',\n    language: 'Language',\n    webdavSync: 'WebDAV Sync',\n    webdavConfig: 'Configuration',\n    webdavUrl: 'WebDAV URL',\n    webdavUsername: 'Username',\n    webdavPassword: 'Password',\n    webdavConfigError: 'Please fill in the complete WebDAV configuration',\n    webdavNotConfigured: 'Please configure WebDAV first',\n    webdavSyncSuccess: 'Sync successful',\n    webdavSyncError: 'Sync failed',\n    webdavTest: 'Test Connection',\n    webdavUpload: 'Upload',\n    webdavDownload: 'Download',\n    api: 'API',\n    reverseProxy: 'Reverse Proxy',\n    timeout: 'Timeout',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS Proxy',\n    balance: 'API Balance',\n    monthlyUsage: 'Monthly Usage',\n  },\n  store: {\n    siderButton: 'Prompt Store',\n    local: 'Local',\n    online: 'Online',\n    title: 'Title',\n    description: 'Description',\n    clearStoreConfirm: 'Whether to clear the data?',\n    importPlaceholder: 'Please paste the JSON data here',\n    addRepeatTitleTips: 'Title duplicate, please re-enter',\n    addRepeatContentTips: 'Content duplicate: {msg}, please re-enter',\n    editRepeatTitleTips: 'Title conflict, please revise',\n    editRepeatContentTips: 'Content conflict {msg} , please re-modify',\n    importError: 'Key value mismatch',\n    importRepeatTitle: 'Title repeatedly skipped: {msg}',\n    importRepeatContent: 'Content is repeatedly skipped: {msg}',\n    onlineImportWarning: 'Note: Please check the JSON file source!',\n    downloadError: 'Please check the network status and JSON file validity',\n  },\n\n\n  \"mj\": {\n    \"setOpen\": \"OpenAI Related\",\n    \"setOpenPlaceholder\": \"Must include http(s)://\",\n    \"setOpenUrl\": \"OpenAI API Address\",\n    \"setOpenKeyPlaceholder\": \"Use custom OpenAI Key to bypass password access restrictions\",\n    \"setMj\": \"Midjourney Related\",\n    \"setMjUrl\": \"Midjourney API Address:\",\n    \"setMjKeyPlaceholder\": \"Use custom Api Secret to bypass password access restrictions\",\n    \"setUploader\": \"Upload Related\",\n    \"setUploaderUrl\": \"Upload Address:\",\n    \"setBtSave\": \"Save\",\n    \"setBtBack\": \"Restore Default\",\n\n    \"redraw\": \"Redraw\",\n  \"fail1\": \"Please be patient, it's loading.\",\n  \"success1\": \"Image refreshed successfully!\",\n  \"high_variation\": \"Strong Variation\",\n  \"low_variation\": \"Weak Variation\",\n  \"p15\": \"Zoom 1.5x\",\n  \"p20\": \"Zoom 2x\",\n  \"p100\": \"Normal\",\n  \"retry\": \"Retry\",\n  \"pan_left\": \"Left\",\n  \"pan_right\": \"Right\",\n  \"pan_up\": \"Up\",\n  \"pan_down\": \"Down\",\n  \"up2\": \"HD 2x\",\n  \"up4\": \"HD 4x\" ,\n\n  \"thinking\": \"Thinking...\",\n  \"noReUpload\": \"Cannot re-upload\",\n  \"uploading\": \"Uploading...\",\n  \"uploadSuccess\": \"Upload successful\",\n  \"uploadFail\": \"Upload failed:\",\n  \"upPdf\": \"<span>Upload image or attachment<br/>You can upload images, PDFs, EXCEL, and other documents</span><p>Supports drag and drop</p>\",\n  \"upImg\": \"<span><b>Upload image</b><br/>Will automatically invoke the gpt-4-vision-preview model<br>Note: Additional image fees may apply<br/>Formats: jpeg, jpg, png, gif</span><p>Supports drag and drop</p> <p class=\\\"pt-2\\\"><b>Upload MP3 MP4</b> <br>Will automatically invoke the whisper-1 model<br>Formats: mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n  \"clearAll\": \"Clear parameters\",\n  \"czoom\": \"Custom\",\n  \"customTitle\": \"Custom zoom\",\n  \"zoominfo\": \"Modify zoom value, range from 1.0 to 2.0, default is set to 1.8\",\n\n  \"modleSuccess\": \"Model loaded successfully\",\n  \"setingSuccess\": \"Settings successful\",\n\n  \"tokenInfo1\": \"Remaining Tokens = Model Length - Role Setting - Context (Conversation History) - Replies Count - Current Input\",\n    \"tokenInfo2\": \"Leave the role setting blank, and the system will provide a default one.\",\n    \"noSuppertModel\": \"Refresh, this model is not currently supported!\",\n    \"failOcr\": \"Recognition failed\",\n    \"remain\": \"Remain:\",\n\n  \"totalUsage\": \"Total subscription amount\",\n  \"disableGpt4\": \"GPT4 disabled\",\n  \"setTextInfo\": \"OpenAI API Key error, click here to retry\",\n\n  \"attr1\": \"Attr\",\n  \"ulink\": \"Image Link\",\n  \"copyFail\": \"Copy Failed\",\n  \"tts\": \"Text to Speech\",\n  \"fail\": \"Error\",\n  \"noSupperChrom\": \"Browser not supported!\",\n  \"lang\": \"Voice\",\n  \"ttsLoading\": \"Converting to Speech...\",\n  \"ttsSuccess\": \"Conversion successful\",\n  \"micIng\": \"Recording, say something...\",\n  \"mStart\": \"Start\",\n  \"mPause\": \"Pause\",\n  \"mGoon\": \"Continue\",\n  \"mRecord\": \"Re-record\",\n  \"mPlay\": \"Play\",\n  \"mCanel\": \"Cancel\",\n  \"mSent\": \"Send\",\n\n  \"findVersion\": \"Discover updated version\",\n  \"yesLastVersion\": \"Already on the latest version\",\n  \"infoStar\": 'This project is open source on <a class=\"text-blue-600 dark:text-blue-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\"_blank\">GitHub</a>, free, and based on the MIT license with no form of payment! </p><p>If you find this project helpful, please give it a Star on GitHub, thank you!',\n  \"setBtSaveChat\": \"Save chat only\",\n  \"setBtSaveSys\": \"Save to system\",\n  \"wsrvClose\": \"Close wsrv\",\n  \"wsrvOpen\": \"Open wsrv\",\n\n  \"temperature\": \"Temperature\",\n  \"temperatureInfo\": \"As the (temperature) value increases, the responses become more random\",\n  \"top_p\": \"Top\",\n  \"top_pInfo\": \"(top_p) is similar to randomness but should not be changed together with temperature\",\n  \"presence_penalty\": \"Presence\",\n  \"presence_penaltyInfo\": \"As the (presence_penalty) value increases, there is a higher chance of expanding to new topics\",\n  \"frequency_penalty\": \"Frequency\",\n  \"frequency_penaltyInfo\": \"As the (frequency_penalty) value increases, there is a higher likelihood of reducing repeated words\",\n  \"tts_voice\": \"Voice Role\",\n  \"typing\": \"Typing\",\n  \"authErro\": \"Authorization failed\",\n  \"authBt\": \"Please enter the authorization access password again\" ,\n  \"micWhisper\": \"Whisper speech recognition\",\n  \"micAsr\": \"Instant recognition\",\n  \"micRec\": \"Start recording, please speak! It will automatically stop if there is no sound for 2 seconds.\",\n  \"micRecEnd\": \"Recording has ended\"\n\n  ,subtle: 'High definition 2x'\n  ,creative: 'High definition 2x. Creative'\n  ,gpt_gx: 'GPTs use g-*',\n\n  \"ideoabout\": \"About Ideogram\",\n  \"ideoserver\": \"Ideogram Server\",\n  \"ideokeyPlaceholder\": \"API Key for Ideogram (optional)\",\n  \"ideopls\": \"Image description prompts\",\n  \"nohead\": \"Excludes\",\n\n  klingabout: 'Kling About',\n  klingserver: 'Kling API Address',\n  klingkeyPlaceholder: 'Kling API Key (optional)',\n  klingkey: 'Kling Key',\n  mode: 'Mode',\n  duration: 'Duration',\n  negative_prompt: 'Place text without objects here',\n  std: 'High Performance',\n  pro: 'High Quality',\n  needImg: 'Please upload a reference image for it to take effect!',\n  seed: 'Seed number 1~2147483647',\n  klingInfo: 'Description: <li>1. High Quality is 3.5 times the price</li> <li>2. 10s is 2 times the price</li> <li>3. The last frame must have a reference image to take effect</li>'\n  \n  ,\"camera_type\": \"Lens\",\n  \"cnull\": \"Smart Matching\",\n  \"down_back\": \"Move Down and Zoom Out\",\n  \"forward_up\": \"Push Forward and Move Up\",\n  \"right_turn_forward\": \"Turn Right and Push Forward\",\n  \"left_turn_forward\": \"Turn Left and Push Forward\"\n  ,kling:'Kling'\n\n  ,rttab: 'RealTime',\n  rtinfo: 'Realtime voice conversation service',\n  rtsetting: 'Please set the server. Currently, Realtime only supports remote services; for local services, please contact the author.',\n  rjcloded: 'Connection has been disconnected',\n  checkkey: 'Please check if the API key is correct',\n  rtsuccess: 'Connection is normal, maintaining the call',\n  rtservererror: 'WebSocket connection server error!',\n  rtservererror2: 'Recording is not supported, it may be due to device reasons!',\n  rtconecting: 'Connecting to the server'\n  ,confirmDelete:'Are you sure?',\n  pikaabout: 'About Pika',\n  pikaserver: 'Pika API Address',\n  pikakeyPlaceholder: 'Pika API Key (optional)',\n  createFail: 'Creation failed',\n  selecteff: 'Reference Effect',\n\n  \n  \"udioabout\": \"About Udio\",\n  \"udiokeyPlaceholder\": \"Udio API Key (optional)\",\n  \"udioserver\": \"Udio API Address\",\n  \"ud_prompt\": \"Prompt\",\n  \"ud_prompt_pls\": \"Prompt: Description, Style\",\n  \"ud_ly_write\": \"Write-Lyrics\",\n  \"ud_ly_auto\": \"Auto\",\n  \"ud_ly_null\": \"Instrumental\",\n  \"ud_v32\": \"Affordable\",\n  \"ud_v130\": \"Long Duration\",\n  \"ud_info\": \"Note: <ul><li>1. Udio-32 has a short duration</li><li>2. Udio-130 is twice the price of Udio-32</li><li>3. The prompt can include style, description, etc.</li></ul>\",\n  \"ud_fail\": \"Failed to generate this song!\",\n  \"ud_doing\": \"Cannot play while generating\",\n  \"ud_continuation\": \"Continuation\",\n  \"ud_precede\": \"Preced\",\n  \"upImg2\": '<span><b>Upload Image</b><br/>This model supports image recognition<br>Note: There will be additional image fees<br/>Formats: jpeg jpg png gif</span><p>Supports drag and drop</p> <p class=\"pt-2\"><b>Upload MP3 MP4</b> <br>Will automatically call the whisper-1 model<br>Formats include: mp3 mp4 mpeg mpga m4a wav webm</p>',\n  \"rml_info\": \"Note:<ul><li>1. Must include an image</li><li>2. The model only has one gen3a_turbo</li><li>3. The price for 10s is double that of 5s</li></ul>\",\n  \"rml_heng\": \"Landscape\",\n  \"rml_shu\": \"Portrait\", \n  \"pixabout\": \"Pixverse related\",\n  \"pixkeyPlaceholder\": \"Pixverse API Key can be left blank\",\n  \"pixserver\": \"Pixverse API address\",\n  \"pixinfo\": \" Description:<br> <ul> <li>1. Based on v3.5 360p duration 5s mode Normal</li><li>2. v2.5 is 0.5 times</li> <li>3. Duration 10s is 2 times</li> <li>4. 540P is 1.5 times, 720P is 2 times, 1080P is 4 times</li> <li>5. Mode performance is 2 times</li> <li>6. The multiples are multiplied, for example, 720P duration 10s is 2*2 which is 4 times, and if performance is added, it becomes 8 times</li></ul>\"\n   ,server_load:'Server Pull'\n   ,model_select:'Model Selecte'\n\n   ,riffabout:'About Riffusion'\n   ,riffkeyPlaceholder:'Riffusion API Key can be left blank'\n   ,riffserver:'Riffusion API address'\n   ,riffinfo:'Riffusion Description'\n\n   ,editImage:'Image Edit'\n   ,editVideo:'Image2Video'\n   ,moreset:'More Parameters'\n  },\n  \"mjset\": {\n    \"server\": \"Server\",\n    \"about\": \"About\",\n    \"model\": \"Model\",\n    \"sysname\": \"AI Drawing\"\n  },\n  \"mjtab\": {\n    \"chat\": \"Chat\",\n    \"draw\": \"Drawing\",\n    \"drawinfo\": \"AI Drawing with Midjourney Engine\",\n    \"gallery\": \"Gallery\",\n    \"galleryInfo\": \"My Gallery\"\n  },\n  \"mjchat\": {\n    \"loading\": \"Loading Image\",\n    \"openurl\": \"Open Link Directly\",\n    \"failReason\": \"Failure Reason:\",\n    \"reload\": \"Reload\",\n    \"progress\": \"Progress:\",\n    \"wait\": \"Task has been submitted, please wait...\",\n    \"reroll\": \"Redraw\",\n    \"wait2\": \"Task {id} has been submitted, please wait\",\n    \"redrawEditing\": \"Partial Redraw Editing\",\n    \"face\": \"Change Face\",\n    \"blend\": \"Blend Images\",\n    \"draw\": \"Drawing\",\n    \"submiting\": \"Submitting\",\n    \"submit\": \"Submit\",\n    \"wait3\": \"Please do not close! Image is being generated...\",\n    \"success\": \"Save Successful\",\n    \"successTitle\": \"Success\",\n    \"modlePlaceholder\": \"Custom models, separated by spaces (optional)\",\n    \"myModle\": \"Custom Models\",\n    \"historyCnt\": \"Context Count\",\n    \"historyToken\": \"More context improves accuracy but consumes more credits\",\n    \"historyTCnt\": \"Reply Count\",\n    \"historyTCntInfo\": \"Higher reply count may consume more credits\",\n    \"role\": \"Role Setting\",\n    \"rolePlaceholder\": \"Set an exclusive role for your conversation (optional)\",\n    \"loading2\": \"Loading...\",\n    \"loadmore\": \"Load More\",\n    \"nofind\": \"Unable to find\",\n    \"nofind2\": \"related content. You can try the following:\",\n    \"success2\": \"Switch Successful!\",\n    \"modelChange\": \"Model Change\",\n    \"search\": \"Search\",\n    \"searchPlaceholder\": \"GPT names, descriptions\",\n    \"attr\": \"Attachments\",\n    \"noproduct\": \"Gallery has no entries yet\",\n    \"myGallery\": \"My Gallery\",\n    \"yourHead\": \"Your Avatar\",\n    \"your2Head\": \"Celebrity Image\",\n    \"tipInfo\": \"Note:<li>1. Images must include faces for proper rendering</li><li>2. 'Celebrity Image' can be created using MJ drawing</li><li>3. 'Celebrity Image' can also include anime characters</li><li>4. 'Your Avatar' is recommended to be a passport-sized personal photo</li>\",\n    \"placeInput\": \"Please fill in the prompt!\",\n    \"more5sb\": \"Upload up to 5 images at most\",\n    \"exSuccess\": \"Export successful... Please check the download folder\",\n    \"downloadSave\": \"ai_drawing.txt\",\n    \"noproducet\": \"No mature works for now\",\n    \"imgBili\": \"Image Ratio\",\n    \"imagEx\": \"Export Artwork Image Links\",\n    \"prompt\": \"Prompts\",\n    \"imgCYes\": \"Contains Base Image\",\n    \"imgCUpload\": \"Upload Base Image\",\n    \"imgCInfo\": \"Base Image Info:<br/>1. Use your own images as a base for MJ drawing<br/>2. You can use multiple base images, up to 5, each not exceeding 1M in size\",\n    \"imgCadd\": \"+Add\",\n    \"del\": \"Delete\",\n    \"img2text\": \"Image-to-Text\",\n    \"img2textinfo\": \"Not sure what prompts to use? Try Image-to-Text! Submit an image to get prompts\",\n    \"traning\": \"Translating...\",\n    \"imgcreate\": \"Generate Image\",\n    \"imginfo\": \"Other parameters:<li>1 --no: Ignore --no car to exclude cars from the image</li><li>2 --seed: Obtain a seed first with --seed 123456</li><li>3 --chaos 10: Mix (range: 0-100)</li><li>4 --tile: Fragmentation</li>\",\n    \"tStyle\": \"Style\",\n    \"tView\": \"View\",\n    \"tShot\": \"Character Shot\",\n    \"tLight\": \"Lighting\",\n    \"tQuality\": \"Image Quality\",\n    \"tStyles\": \"Artistic Level\",\n    \"tVersion\": \"Model Version\",\n    \"dalleInfo\": \"Note:<li>1. DALL-E is an image generation model provided by OpenAI</li><li>2. OpenAI images have an expiration date, so make backups</li><li>3. Note: The price of 1790px images is double</li>\",\n    \"version\": \"Version\",\n    \"size\": \"Size\",\n    \"blendInfo\": \"Note:<li>1. Blend at least 2 images</li><li>2. Up to 6 images can be used for blending</li>\",\n    \"blendStart\": \"Start Blending\",\n    \"no2add\": \"Do not add duplicate images\",\n    \"add2more\": \"Please add two or more images\",\n    \"no1m\": \"Image size cannot exceed 1M\",\n    \"imgExt\": \"Images support only jpg, gif, png, jpeg formats\"\n    ,\"setSync\": \"Synchronize Midjourney and Suno\"\n\n    ,\"addGPTS\": \"Add GPTs\",\n    \"addPlaceholder\": \"Paste the GID of the GPTs here or directly paste the link of the GPTs\",\n    \"gidError\": \"Valid GID not found, please fill in again\",\n    \"success3\": \"GPTs added successfully!\"\n  },\n\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n\n  ,suno:{\n    \"description\": \"Description\",\n    \"custom\": \"Custom\",\n    \"style\": \"Song Style\",\n    \"stylepls\": \"Song Name, e.g., Pop Music\",\n    \"emputy\": \"No content available\",\n    \"noly\": \"No lyrics available\",\n    \"inputly\": \"Please enter the song name or lyrics\",\n    \"doingly\": \"In progress, please wait.\",\n    \"doingly2\": \"Fetching lyrics...\",\n    \"title\": \"Song Name\",\n    \"titlepls\": \"Song Name, e.g., Vacation\",\n    \"desc\": \"Song Description\",\n    \"descpls\": \"Song description, e.g., Original pop music about vacation\",\n    \"noneedly\": \"No lyrics needed\",\n    \"rank\": \"Random selection\",\n    \"ly\": \"Lyrics\",\n    \"lypls\": \"Lyrics: with a certain format\",\n    \"generate\": \"Compose Song\",\n    \"generately\": \"Generate Lyrics\",\n    \"nodata\": \"Please compose first to have a list of songs\",\n\n    \"menu\": \"Music\",\n    \"menuinfo\": \"Suno Music Creation\",\n    \"server\": \"Suno API Endpoint\",\n    \"serverabout\": \"Suno Related\",\n    \"setOpenKeyPlaceholder\": \"Related KEY for Suno API; optional\"\n\n    ,upMps:'Upload'\n    ,extend:'Extend'\n    ,extendFrom:'Extend From'\n    ,extendAt:'Extend at'\n    ,fail:'Fail'\n    ,info:'Note: <br> Uploaded audio must be between 6 seconds and 60 seconds in duration.'\n  }\n   ,video: {\n    menu: \"Videos\",\n    menuinfo: \"Luma and other video generate\",\n    descpls: \"Video generate description\",\n    lumaabout: \"About Luma\",\n    lumaserver: \"Luma API endpoint\",\n    setOpenKeyPlaceholder: \"Key for Luma API, optional\",\n    generate: \"Generate video\",\n    nodata: \"No available videos, please generate first!\",\n    selectimg: \"Select image\",\n    clear: \"Clear\",\n    plsInput: \"Please input content!\",\n    submitSuccess: \"Submitted successfully!\",\n    process: \"Video generating...\",\n    repeat: \"Get again\",\n    pending: 'Status: Queued',\n    processing: 'Status: Processing',\n    download: 'Download',\n    extend: 'Extend',\n\n    \"lumainfo\": \"Explanation: <ul><li>1. Pro and relax demo videos have watermarked links.</li><li>2. Pro without watermark requires obtaining the download link through the 'Download' button.</li><li>3. The links for Pro versions are time-limited; please save the MP4 file locally promptly.</li><li>4. For Pro versions, save the MP4 file locally within 30 minutes after generation, as the channel may be blocked or discontinued.</li><li>5. If the download link for Pro versions is invalid, a watermarked video link will be provided.</li></ul>\",\n    \"runwayabout\": \"Runway Related\",\n    \"runwayserver\": \"Runway API Endpoint\",\n    \"setOpenKeyPlaceholder2\": \"Runway API key, optional\",\n    \"endImg\": \"End Frame Image\",\n    \"runwayinfo\": \"Explanation: <ul><li>1. Runway images and videos have expiration times.</li><li>2. Please save the MP4 file locally within 30 minutes after generating the video.</li></ul>\",\n    \"nosup\": \"Not supported temporarily\",\n    \"rwgen2\": \"Version: Gen-2, cost-effective\",\n    \"rwgen3\": \"Version: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\",\n\n    rwgen3turbo:'Version: Gen-3 Alpha Turbo',\n    gen3a_turbo_img:'Gen-3 Alpha Turbo must image',\n\n  },\n  dance:{\n    menu: \"Dance\",\n    menuinfo: \"Create dance videos with Viggle and others.\",\n    character: \"Character\",\n    viggleabout: \"About Viggle\",\n    viggleserver: \"Viggle API Endpoint\",\n    setOpenKeyPlaceholder: \"Viggle API key, optional\",\n    info: \"Instructions:<br>1. Character images should preferably be full-body photos.<br>2. Dance template videos should be personal videos, not group dances.\",\n    model: \"Model\",\n    bgw: \"White Background\",\n    bgg: \"Green Background\",\n    bgmoban: \"Original Background\",\n    bgrole: \"Character Background\",\n    gring: \"Generating...\",\n    uprolefirst: \"Please upload character image first\",\n    uprolefail: \"Upload failed\",\n    upvideo: \"+ Upload Template Dance Video\",\n    usevideo: \"+ Use Official Template\",\n    moban: \"Dance Template\",\n    moban2: \"Template Name\",\n    use: \"Use\"\n  }\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/locales/fr-FR.ts",
    "content": "export default {\n    common: {\n        add: 'Ajouter',\n        addSuccess: 'Ajout réussi',\n        edit: 'Éditer',\n        editSuccess: 'Édition réussie',\n        delete: 'Supprimer',\n        deleteSuccess: 'Suppression réussie',\n        save: 'Enregistrer',\n        saveSuccess: 'Enregistrement réussi',\n        reset: 'Réinitialiser',\n        action: 'Action',\n        export: 'Exporter',\n        exportSuccess: 'Exportation réussie',\n        import: 'Importer',\n        importSuccess: 'Importation réussie',\n        clear: 'Effacer',\n        clearSuccess: 'Effacement réussi',\n        yes: 'Oui',\n        no: 'Non',\n        confirm: 'Confirmer',\n        download: 'Télécharger',\n        noData: 'Pas de données',\n        wrong: 'Quelque chose s\\'est mal passé, veuillez réessayer plus tard.',\n        success: 'Succès',\n        failed: 'Échec',\n        verify: 'Vérifier',\n        unauthorizedTips: 'Non autorisé, veuillez vérifier d\\'abord.',\n        stopResponding: 'Arrêter de répondre',\n    },\n    chat: {\n        newChatButton: 'Nouveau Chat',\n        //placeholder: 'Ask me anything...(Shift + Enter = line break, \"/\" to trigger prompts)',\n        placeholder: 'Posez-moi n\\'importe quoi, ou collez des captures d\\'écran ou faites glisser le fichier. (Shift + Enter = saut de ligne, \"/\" pour déclencher des prompts)',\n        placeholderMobile: 'Posez-moi n\\'importe quoi...',\n        copy: 'Copier',\n        copied: 'Copié',\n        copyCode: 'Copier le Code',\n        clearChat: 'Effacer le Chat',\n        clearChatConfirm: 'Êtes-vous sûr de vouloir effacer ce chat ?',\n        exportImage: 'Exporter l\\'Image',\n        exportImageConfirm: 'Êtes-vous sûr de vouloir exporter ce chat en PNG ?',\n        exportSuccess: 'Exportation réussie',\n        exportFailed: 'Échec de l\\'exportation',\n        usingContext: 'Mode Contexte',\n        turnOnContext: 'Dans le mode actuel, l\\'envoi de messages conservera les enregistrements de chat précédents.',\n        turnOffContext: 'Dans le mode actuel, l\\'envoi de messages ne conservera pas les enregistrements de chat précédents.',\n        deleteMessage: 'Supprimer le Message',\n        deleteMessageConfirm: 'Êtes-vous sûr de vouloir supprimer ce message ?',\n        deleteHistoryConfirm: 'Êtes-vous sûr de vouloir effacer cet historique ?',\n        clearHistoryConfirm: 'Êtes-vous sûr de vouloir effacer l\\'historique du chat ?',\n        preview: 'Aperçu',\n        showRawText: 'Afficher en texte brut',\n    },\n    setting: {\n        setting: 'Paramètres',\n        general: 'Général',\n        advanced: 'Avancé',\n        config: 'Configuration',\n        avatarLink: 'Lien de l\\'Avatar',\n        name: 'Nom',\n        description: 'Description',\n        backgroundImage: 'Image de Fond',\n        role: 'Rôle',\n        temperature: 'Température',\n        top_p: 'Top_p',\n        resetUserInfo: 'Réinitialiser les Infos Utilisateur',\n        chatHistory: 'Historique du Chat',\n        theme: 'Thème',\n        language: 'Langue',\n        webdavSync: 'Synchronisation WebDAV',\n        webdavConfig: 'Configuration',\n        webdavUrl: 'URL WebDAV',\n        webdavUsername: 'Nom d\\'utilisateur',\n        webdavPassword: 'Mot de passe',\n        webdavConfigError: 'Veuillez remplir la configuration WebDAV complète',\n        webdavNotConfigured: 'Veuillez d\\'abord configurer WebDAV',\n        webdavSyncSuccess: 'Synchronisation réussie',\n        webdavSyncError: 'Échec de la synchronisation',\n        webdavTest: 'Tester la connexion',\n        webdavUpload: 'Télécharger',\n        webdavDownload: 'Télécharger',\n        api: 'API',\n        reverseProxy: 'Proxy Inverse',\n        timeout: 'Délai d\\'Attente',\n        socks: 'Socks',\n        httpsProxy: 'Proxy HTTPS',\n        balance: 'Solde de l\\'API',\n        monthlyUsage: 'Utilisation Mensuelle',\n    },\n    store: {\n        siderButton: 'Prompt Boutique',\n        local: 'Local',\n        online: 'En ligne',\n        title: 'Titre',\n        description: 'Description',\n        clearStoreConfirm: 'Voulez-vous vraiment effacer les données ?',\n        importPlaceholder: 'Veuillez coller les données JSON ici',\n        addRepeatTitleTips: 'Titre en double, veuillez le saisir à nouveau',\n        addRepeatContentTips: 'Contenu en double : {msg}, veuillez le saisir à nouveau',\n        editRepeatTitleTips: 'Conflit de titre, veuillez le réviser',\n        editRepeatContentTips: 'Conflit de contenu {msg}, veuillez le modifier à nouveau',\n        importError: 'Incompatibilité de valeur clé',\n        importRepeatTitle: 'Titre ignoré de manière répétée : {msg}',\n        importRepeatContent: 'Contenu ignoré de manière répétée : {msg}',\n        onlineImportWarning: 'Remarque : Veuillez vérifier la source du fichier JSON !',\n        downloadError: 'Veuillez vérifier l\\'état du réseau et la validité du fichier JSON',\n    },\n    \"mj\": {\n        \"setOpen\": \"Lié à OpenAI\",\n        \"setOpenPlaceholder\": \"Doit inclure http(s)://\",\n        \"setOpenUrl\": \"Adresse de l'API OpenAI\",\n        \"setOpenKeyPlaceholder\": \"Utilisez une clé OpenAI personnalisée pour contourner les restrictions d'accès par mot de passe\",\n        \"setMj\": \"Lié à Midjourney\",\n        \"setMjUrl\": \"Adresse de l'API Midjourney:\",\n        \"setMjKeyPlaceholder\": \"Utilisez une clé d'API Midjourney personnalisée pour contourner les restrictions d'accès par mot de passe\",\n        \"setUploader\": \"Lié au Téléchargement\",\n        \"setUploaderUrl\": \"Adresse de Téléchargement:\",\n        \"setBtSave\": \"Enregistrer\",\n        \"setBtBack\": \"Restaurer les Paramètres par Défaut\",\n\n        \"redraw\": \"Redessiner\",\n        \"fail1\": \"S'il vous plaît soyez patient, ça charge.\",\n        \"success1\": \"Image rafraîchie avec succès !\",\n        \"high_variation\": \"Variation Forte\",\n        \"low_variation\": \"Variation Faible\",\n        \"p15\": \"Zoom 1.5x\",\n        \"p20\": \"Zoom 2x\",\n        \"p100\": \"Normal\",\n        \"retry\": \"Réessayer\",\n        \"pan_left\": \"Gauche\",\n        \"pan_right\": \"Droite\",\n        \"pan_up\": \"Haut\",\n        \"pan_down\": \"Bas\",\n        \"up2\": \"HD 2x\",\n        \"up4\": \"HD 4x\" ,\n\n        \"thinking\": \"Réflexion...\",\n        \"noReUpload\": \"Impossible de réimporter\",\n        \"uploading\": \"Téléchargement...\",\n        \"uploadSuccess\": \"Téléchargement réussi\",\n        \"uploadFail\": \"Échec du téléchargement:\",\n        \"upPdf\": \"<span>Téléchargez une image ou une pièce jointe<br/>Vous pouvez télécharger des images, des PDF, des EXCEL et d'autres documents</span><p>Prise en charge du glisser-déposer</p>\",\n        \"upImg\": \"<span><b>Téléchargez une image</b><br/>Il invoquera automatiquement le modèle de prévisualisation gpt-4-vision<br>Remarque : Des frais supplémentaires peuvent s'appliquer pour les images supplémentaires<br/>Formats : jpeg, jpg, png, gif</span><p>Prise en charge du glisser-déposer</p> <p class=\\\"pt-2\\\"><b>Téléchargez MP3 MP4</b> <br>Il invoquera automatiquement le modèle whisper-1<br>Formats : mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n        \"clearAll\": \"Effacer les paramètres\",\n        \"czoom\": \"Personnalisé\",\n        \"customTitle\": \"Zoom personnalisé\",\n        \"zoominfo\": \"Modifier la valeur du zoom, de 1.0 à 2.0, la valeur par défaut est réglée sur 1.8\",\n\n        \"modleSuccess\": \"Modèle chargé avec succès\",\n        \"setingSuccess\": \"Paramètres réussis\",\n\n        \"tokenInfo1\": \"Jetons restants = Longueur du modèle - Réglage du rôle - Contexte (historique des conversations) - Nombre de réponses - Entrée actuelle\",\n        \"tokenInfo2\": \"Laissez le réglage du rôle vide et le système fournira un réglage par défaut.\",\n        \"noSuppertModel\": \"Actualiser, ce modèle n'est actuellement pas pris en charge !\",\n        \"failOcr\": \"Échec de la reconnaissance\",\n        \"remain\": \"Reste :\",\n\n        \"totalUsage\": \"Montant total de l'abonnement\",\n        \"disableGpt4\": \"GPT4 désactivé\",\n        \"setTextInfo\": \"Erreur de clé API OpenAI, cliquez ici pour réessayer\",\n\n        \"attr1\": \"Attribut\",\n        \"ulink\": \"Lien de l'image\",\n        \"copyFail\": \"Copie échouée\",\n        \"tts\": \"Texte vers Parole\",\n        \"fail\": \"Erreur\",\n        \"noSupperChrom\": \"Navigateur non pris en charge !\",\n        \"lang\": \"Voix\",\n        \"ttsLoading\": \"Conversion en discours...\",\n        \"ttsSuccess\": \"Conversion réussie\",\n        \"micIng\": \"Enregistrement, dites quelque chose...\",\n        \"mStart\": \"Démarrer\",\n        \"mPause\": \"Pause\",\n        \"mGoon\": \"Continuer\",\n        \"mRecord\": \"Réenregistrer\",\n        \"mPlay\": \"Lire\",\n        \"mCanel\": \"Annuler\",\n        \"mSent\": \"Envoyer\",\n\n        \"findVersion\": \"Découvrir la version mise à jour\",\n        \"yesLastVersion\": \"Déjà sur la dernière version\",\n        \"infoStar\": 'Ce projet est open source sur <a class=\"text-blue-600 dark:text-blue-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\"_blank\">GitHub</a>, gratuit et basé sur la licence MIT sans aucune forme de paiement ! </p><p>Si vous trouvez ce projet utile, veuillez lui donner une étoile sur GitHub, merci !',\n        \"setBtSaveChat\": \"Enregistrer le chat seulement\",\n        \"setBtSaveSys\": \"Enregistrer dans le système\",\n        \"wsrvClose\": \"Fermer wsrv\",\n        \"wsrvOpen\": \"Ouvrir wsrv\",\n\n        \"temperature\": \"Aléatoire\",\n        \"temperatureInfo\": \"À mesure que la valeur de (temperature) augmente, les réponses deviennent plus aléatoires\",\n        \"top_p\": \"Échantillonnage de probabilité supérieure\",\n        \"top_pInfo\": \"(top_p) est similaire à l'aléatoire mais ne doit pas être modifié en même temps que la température\",\n        \"presence_penalty\": \"Fraîcheur du sujet\",\n        \"presence_penaltyInfo\": \"À mesure que la valeur de (presence_penalty) augmente, il y a plus de chances de s'étendre à de nouveaux sujets\",\n        \"frequency_penalty\": \"Pénalité de fréquence\",\n        \"frequency_penaltyInfo\": \"À mesure que la valeur de (frequency_penalty) augmente, il y a plus de chances de réduire les mots répétés\"\n        ,\"tts_voice\": \"Personnage vocal TTS\",\n        \"typing\": \"En train d'écrire\",\n        \"authErro\": \"Échec de l'autorisation\",\n        \"authBt\": \"Veuillez saisir à nouveau le mot de passe d'accès à l'autorisation\",\n        \"micWhisper\": \"Reconnaissance vocale chuchotement\",\n        \"micAsr\": \"Reconnaissance instantanée\",\n        \"micRec\": \"Commencer l'enregistrement, s'il vous plaît parlez ! Il s'arrêtera automatiquement s'il n'y a pas de son pendant 2 secondes.\",\n        \"micRecEnd\": \"L'enregistrement est terminé\",\n\n        subtle: 'Haute définition 2x'\n        ,creative: 'Haute définition 2x. Créatif'\n        ,gpt_gx: 'Les GPT utilisent g-*',\n\n        \"ideoabout\": \"À propos d'Ideogram\",\n        \"ideoserver\": \"Serveur Ideogram\",\n        \"ideokeyPlaceholder\": \"Clé API pour Ideogram (optionnelle)\",\n        \"ideopls\": \"Invites de description d'image\",\n        \"nohead\": \"Exclut\",\n\n        klingabout: 'Kling À propos',\n        klingserver: 'Adresse API Kling',\n        klingkeyPlaceholder: 'Clé API Kling (facultatif)',\n        klingkey: 'Clé Kling',\n        mode: 'Mode',\n        duration: 'Durée',\n        negative_prompt: 'Mettez le texte sans objets ici',\n        std: 'Haute performance',\n        pro: 'Haute qualité',\n        needImg: 'Veuillez télécharger une image de référence pour qu’elle prenne effet !',\n        seed: 'Numéro de graine 1~2147483647',\n        klingInfo: 'Description : <li>1. Haute qualité coûte 3,5 fois le prix</li> <li>2. 10 secondes coûtent 2 fois le prix</li> <li>3. La dernière image doit avoir une image de référence pour prendre effet</li>'\n\n        ,\"camera_type\": \"Objectif\",\n        \"cnull\": \"Correspondance intelligente\",\n        \"down_back\": \"Descendre et zoomer\",\n        \"forward_up\": \"Avancer et monter\",\n        \"right_turn_forward\": \"Tourner à droite et avancer\",\n        \"left_turn_forward\": \"Tourner à gauche et avancer\"\n        ,kling:'Kling'\n        ,rttab: 'Voix',\n        rtinfo: 'Service de conversation vocale en temps réel (realtime)',\n        rtsetting: 'Veuillez configurer le serveur. Actuellement, Realtime ne prend en charge que les services à distance ; pour les services locaux, veuillez contacter l\\'auteur.',\n        rjcloded: 'La connexion a été déconnectée',\n        checkkey: 'Veuillez vérifier si la clé API est correcte',\n        rtsuccess: 'Connexion normale, maintien de l\\'appel',\n        rtservererror: 'Erreur de connexion au serveur WebSocket !',\n        rtservererror2: 'Enregistrement non pris en charge, cela peut être dû à un problème de matériel !',\n        rtconecting: 'Connexion au serveur en cours',\n        \"confirmDelete\": \"Êtes-vous sûr de vouloir supprimer ?\",\n        \"pikaabout\": \"À propos de Pika\",\n        \"pikaserver\": \"Adresse API Pika\",\n        \"pikakeyPlaceholder\": \"Clé API Pika (facultatif)\",\n        \"createFail\": \"Échec de la création\",\n        \"selecteff\": \"Effet de référence\",\n\n        \"udioabout\": \"À propos de Udio\",\n        \"udiokeyPlaceholder\": \"Clé API Udio (optionnelle)\",\n        \"udioserver\": \"Adresse API Udio\",\n        \"ud_prompt\": \"Invite\",\n        \"ud_prompt_pls\": \"Invite : Description, Style\",\n        \"ud_ly_write\": \"Paroles personnalisées\",\n        \"ud_ly_auto\": \"Paroles intelligentes\",\n        \"ud_ly_null\": \"Musique pure\",\n        \"ud_v32\": \"Abordable\",\n        \"ud_v130\": \"Longue durée\",\n        \"ud_info\": \"Remarque : <ul><li>1. Udio-32 a une durée courte</li><li>2. Udio-130 coûte le double de Udio-32</li><li>3. L'invite peut inclure style, description, etc.</li></ul>\",\n        \"ud_fail\": \"Échec de la génération de cette chanson !\",\n        \"ud_doing\": \"Impossible de lire pendant la génération\",\n        \"ud_continuation\": \"Continuation\",\n        \"ud_precede\": \"Précédent\",\n\n        \"upImg2\": \"<span><b>Télécharger une image</b><br/>Ce modèle prend en charge la reconnaissance d'images<br>Remarque : des frais supplémentaires pour les images seront appliqués<br/>Formats : jpeg jpg png gif</span><p>Prend en charge le glisser-déposer</p> <p class=\\\"pt-2\\\"><b>Télécharger MP3 MP4</b> <br>Appellera automatiquement le modèle whisper-1<br>Formats : mp3 mp4 mpeg mpga m4a wav webm</p>\",\n        \"rml_info\": \"Remarque :<ul><li>1. Doit inclure une image</li><li>2. Le modèle n'a qu'un seul gen3a_turbo</li><li>3. Le prix pour 10 secondes est le double de celui de 5 secondes</li></ul>\",\n        \"rml_heng\": \"Paysage\",\n        \"rml_shu\": \"Portrait\",\n        \"pixabout\": \"Lié à Pixverse\",\n        \"pixkeyPlaceholder\": \"La clé API de Pixverse peut être laissée vide\",\n        \"pixserver\": \"Adresse de l'API Pixverse\",\n        \"pixinfo\": \" Description :<br> <ul> <li>1. Basé sur v3.5 360p durée 5s mode Normal</li><li>2. v2.5 est 0,5 fois</li> <li>3. Durée 10s est 2 fois</li> <li>4. 540P est 1,5 fois, 720P est 2 fois, 1080P est 4 fois</li> <li>5. Mode performance est 2 fois</li> <li>6. Les multiplicateurs se multiplient, par exemple, 720P durée 10s est 2*2 ce qui fait 4 fois, et si vous ajoutez performance, cela devient 8 fois</li></ul>\",\n\n        \"riffabout\": \"À propos de Riffusion\",\n        \"riffkeyPlaceholder\": \"Clé API Riffusion (facultative)\",\n        \"riffserver\": \"URL de l'API Riffusion\",\n        \"riffinfo\": \"Description\",\n        \n        \"editImage\": \"Édition d'image\",\n        \"editVideo\": \"Image vers vidéo\",\n        \"moreset\": \"Paramètres supplémentaires\",\n\n    },\n    \"mjset\": {\n        \"server\": \"Serveur\",\n        \"about\": \"À Propos\",\n        \"model\": \"Modèle\",\n        \"sysname\": \"Dessin AI\"\n    },\n    \"mjtab\": {\n        \"chat\": \"Chat\",\n        \"draw\": \"Dessin\",\n        \"drawinfo\": \"Dessin AI avec le Moteur Midjourney\",\n        \"gallery\": \"Galerie\",\n        \"galleryInfo\": \"Ma Galerie\"\n    },\n    \"mjchat\": {\n        \"loading\": \"Chargement de l'Image\",\n        \"openurl\": \"Ouvrir le lien directement\",\n        \"failReason\": \"Raison de l'échec:\",\n        \"reload\": \"Recharger\",\n        \"progress\": \"Progression:\",\n        \"wait\": \"La tâche a été soumise, veuillez patienter...\",\n        \"reroll\": \"Refaire\",\n        \"wait2\": \"La tâche {id} a été soumise, veuillez patienter\",\n        \"redrawEditing\": \"Édition partielle du Redraw\",\n        \"face\": \"Changer de Visage\",\n        \"blend\": \"Mélanger les Images\",\n        \"draw\": \"Dessin\",\n        \"submiting\": \"Soumission\",\n        \"submit\": \"Soumettre\",\n        \"wait3\": \"Veuillez ne pas fermer! L'image est en cours de génération...\",\n        \"success\": \"Enregistrement réussi\",\n        \"successTitle\": \"Succès\",\n        \"modlePlaceholder\": \"Modèles personnalisés, séparés par des espaces (facultatif)\",\n        \"myModle\": \"Modèles Personnalisés\",\n        \"historyCnt\": \"Nombre de Contextes\",\n        \"historyToken\": \"Plus de contexte améliore la précision mais consomme plus de crédits\",\n        \"historyTCnt\": \"Nombre de Réponses\",\n        \"historyTCntInfo\": \"Un nombre plus élevé de réponses peut consommer plus de crédits\",\n        \"role\": \"Paramètre de Rôle\",\n        \"rolePlaceholder\": \"Définissez un rôle exclusif pour votre conversation (facultatif)\",\n        \"loading2\": \"Chargement...\",\n        \"loadmore\": \"Charger Plus\",\n        \"nofind\": \"Impossible de trouver\",\n        \"nofind2\": \"contenu connexe. Vous pouvez essayer ce qui suit:\",\n        \"success2\": \"Changement réussi!\",\n        \"modelChange\": \"Changement de Modèle\",\n        \"search\": \"Rechercher\",\n        \"searchPlaceholder\": \"Noms GPT, descriptions\",\n        \"attr\": \"Pièces Jointes\",\n        \"noproduct\": \"La galerie n'a pas encore d'entrées\",\n        \"myGallery\": \"Ma Galerie\",\n        \"yourHead\": \"Votre Avatar\",\n        \"your2Head\": \"Image de Célébrité\",\n        \"tipInfo\": \"Note:<li>1. Les images doivent inclure des visages pour un rendu correct</li><li>2. L'«Image de Célébrité» peut être créée en utilisant le dessin MJ</li><li>3. L'«Image de Célébrité» peut également inclure des personnages d'anime</li><li>4. «Votre Avatar» est recommandé d'être une photo personnelle de la taille d'un passeport</li>\",\n        \"placeInput\": \"Veuillez remplir la demande!\",\n        \"more5sb\": \"Téléchargez jusqu'à 5 images au maximum\",\n        \"exSuccess\": \"Exportation réussie... Veuillez vérifier le dossier de téléchargement\",\n        \"downloadSave\": \"ai_drawing.txt\",\n        \"noproducet\": \"Pas encore d'œuvres matures pour le moment\",\n        \"imgBili\": \"Ratio d'Image\",\n        \"imagEx\": \"Exporter les Liens d'Œuvres d'Art\",\n        \"prompt\": \"Prompts\",\n        \"imgCYes\": \"Contient une Image de Base\",\n        \"imgCUpload\": \"Télécharger une Image de Base\",\n        \"imgCInfo\": \"Informations sur l'Image de Base:<br/>1. Utilisez vos propres images comme base pour le dessin MJ<br/>2. Vous pouvez utiliser plusieurs images de base, jusqu'à 5, chacune ne dépassant pas 1 Mo\",\n        \"imgCadd\": \"+Ajouter\",\n        \"del\": \"Supprimer\",\n        \"img2text\": \"Image-to-Text\",\n        \"img2textinfo\": \"Vous ne savez pas quels prompts utiliser? Essayez Image-to-Text! Soumettez une image pour obtenir des prompts\",\n        \"traning\": \"Traduction...\",\n        \"imgcreate\": \"Générer une Image\",\n        \"imginfo\": \"Autres paramètres:<li>1 --no: Ignorer --no car pour exclure les voitures de l'image</li><li>2 --seed: Obtenir d'abord une graine avec --seed 123456</li><li>3 --chaos 10: Mélanger (plage: 0-100)</li><li>4 --tile: Fragmentation</li>\",\n        \"tStyle\": \"Style\",\n        \"tView\": \"Vue\",\n        \"tShot\": \"Prise de Personnage\",\n        \"tLight\": \"Éclairage\",\n        \"tQuality\": \"Qualité de l'Image\",\n        \"tStyles\": \"Niveau Artistique\",\n        \"tVersion\": \"Version du Modèle\",\n        \"dalleInfo\": \"Note:<li>1. DALL-E est un modèle de génération d'images fourni par OpenAI</li><li>2. Les images OpenAI ont une date d'expiration, alors faites des sauvegardes</li><li>3. Remarque: Le prix des images de 1790 px est doublé</li>\",\n        \"version\": \"Version\",\n        \"size\": \"Taille\",\n        \"blendInfo\": \"Note:<li>1. Mélanger au moins 2 images</li><li>2. Jusqu'à 6 images peuvent être utilisées pour le mélange</li>\",\n        \"blendStart\": \"Commencer à Mélanger\",\n        \"no2add\": \"Ne pas ajouter d'images en double\",\n        \"add2more\": \"Veuillez ajouter deux images ou plus\",\n        \"no1m\": \"La taille de l'image ne peut pas dépasser 1 Mo\",\n        \"imgExt\": \"Les images ne supportent que les formats jpg, gif, png, jpeg\",\n        \"setSync\": \"Synchroniser Midjourney et Suno\",\n        \"addGPTS\": \"Ajouter des GPTs\",\n        \"addPlaceholder\": \"Collez le GID des GPTs ici ou collez directement le lien des GPTs\",\n        \"gidError\": \"GID valide introuvable, veuillez remplir à nouveau\",\n        \"success3\": \"GPTs ajoutés avec succès !\"\n    },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n  ,suno:{\n    \"description\": \"Mode de description\",\n    \"custom\": \"Mode professionnel\",\n    \"style\": \"Style de chanson\",\n    \"stylepls\": \"Nom de la chanson, par exemple : Musique pop\",\n    \"emputy\": \"Aucun contenu disponible\",\n    \"noly\": \"Pas de paroles disponibles\",\n    \"inputly\": \"Veuillez saisir le nom de la chanson ou les paroles\",\n    \"doingly\": \"En cours, veuillez patienter.\",\n    \"doingly2\": \"Récupération des paroles...\",\n    \"title\": \"Nom de la chanson\",\n    \"titlepls\": \"Nom de la chanson, par exemple : Vacances\",\n    \"desc\": \"Description de la chanson\",\n    \"descpls\": \"Description de la chanson, par exemple : Musique pop originale sur les vacances\",\n    \"noneedly\": \"Pas besoin de paroles\",\n    \"rank\": \"Sélection aléatoire\",\n    \"ly\": \"Paroles\",\n    \"lypls\": \"Paroles : avec un certain format\",\n    \"generate\": \"Composer une chanson\",\n    \"generately\": \"Générer des paroles\",\n    \"nodata\": \"Veuillez composer d'abord pour obtenir une liste de chansons\",\n\n    \"menu\": \"Musique\",\n    \"menuinfo\": \"Création musicale Suno\",\n    \"server\": \"Point de terminaison de l'API Suno\",\n    \"serverabout\": \"Lié à Suno\",\n    \"setOpenKeyPlaceholder\": \"Clé associée pour l'API Suno ; facultatif\",\n\n    upMps: 'Télécharger l\\'audio',\n    extend: 'Étendre',\n    extendFrom: 'Étendre depuis',\n    extendAt: 'Commencer l\\'extension à',\n    fail: 'Échec',\n    info: 'Instructions :<br>La durée de l\\'audio téléchargé doit être comprise entre 6s et 60s'\n\n   }\n   ,video:{\n    \"menu\": \"Vidéos\",\n    \"menuinfo\": \"Création de vidéos Luma et autres\",\n    \"descpls\": \"Description de création de vidéos\",\n    \"lumaabout\": \"À propos de Luma\",\n    \"lumaserver\": \"Adresse de l'API Luma\",\n    \"setOpenKeyPlaceholder\": \"Clé API Luma, facultatif\",\n    \"generate\": \"Générer la vidéo\",\n    \"nodata\": \"Aucune vidéo disponible, veuillez d'abord générer !\",\n    \"selectimg\": \"Sélectionner une image\",\n    \"clear\": \"Effacer\",\n    \"plsInput\": \"Veuillez saisir du contenu !\",\n    \"submitSuccess\": \"Soumis avec succès !\",\n    \"process\": \"Génération de la vidéo...\",\n    \"repeat\": \"Réessayer\",\n    \"lumainfo\": \"Explication : <ul><li>1. Les vidéos de démonstration Pro et relax ont des liens avec des filigranes.</li><li>2. La version Pro sans filigrane nécessite d'obtenir le lien de téléchargement via le bouton 'Télécharger'.</li><li>3. Les liens pour les versions Pro sont limités dans le temps ; veuillez sauvegarder le fichier MP4 localement dès que possible.</li><li>4. Pour les versions Pro, sauvegardez le fichier MP4 localement dans les 30 minutes suivant la génération, car le canal peut être bloqué ou arrêté.</li><li>5. Si le lien de téléchargement pour les versions Pro est invalide, un lien vidéo avec filigrane sera fourni.</li></ul>\",\n    \"runwayabout\": \"Lié à Runway\",\n    \"runwayserver\": \"Adresse de l'API Runway\",\n    \"setOpenKeyPlaceholder2\": \"Clé API Runway, facultative\",\n    \"endImg\": \"Image de fin\",\n    \"runwayinfo\": \"Explication : <ul><li>1. Les images et vidéos de Runway ont une durée de validité.</li><li>2. Veuillez sauvegarder le fichier MP4 localement dans les 30 minutes suivant la génération de la vidéo.</li></ul>\",\n    \"nosup\": \"Non pris en charge temporairement\",\n    \"rwgen2\": \"Version : Gen-2, rentable\",\n    \"rwgen3\": \"Version : Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\"\n    },\n    dance:{\n        menu: \"Danse\",\n        menuinfo: \"Créez des vidéos de danse avec Viggle et d'autres.\",\n        character: \"Personnage\",\n        viggleabout: \"À propos de Viggle\",\n        viggleserver: \"Adresse API Viggle\",\n        setOpenKeyPlaceholder: \"Clé API Viggle, facultatif\",\n        info: \"Instructions :<br>1. Les images de personnage devraient de préférence être des photos en pied.<br>2. Les vidéos de modèles de danse devraient être des vidéos personnelles, pas des danses de groupe.\",\n        model: \"Modèle\",\n        bgw: \"Arrière-plan blanc\",\n        bgg: \"Arrière-plan vert\",\n        bgmoban: \"Arrière-plan du modèle\",\n        bgrole: \"Arrière-plan du personnage\",\n        gring: \"En cours de génération...\",\n        uprolefirst: \"Veuillez d'abord télécharger l'image du personnage\",\n        uprolefail: \"Échec du téléchargement\",\n        upvideo: \"+ Télécharger la vidéo de modèle de danse\",\n        usevideo: \"+ Utiliser le modèle officiel\",\n        moban: \"Modèle de danse\",\n        moban2: \"Nom du modèle\",\n        use: \"Utiliser\"\n    }\n\n  }\n"
  },
  {
    "path": "src/locales/index.ts",
    "content": "import type { App } from 'vue'\nimport { createI18n } from 'vue-i18n'\nimport enUS from './en-US'\nimport koKR from './ko-KR'\nimport zhCN from './zh-CN'\nimport zhTW from './zh-TW'\nimport ruRU from './ru-RU'\nimport viVn from './vi-VN'\nimport frFr from './fr-FR'\nimport trTr from './tr-TR'\nimport { useAppStoreWithOut } from '@/store/modules/app'\nimport type { Language } from '@/store/modules/app/helper'\n\nconst appStore = useAppStoreWithOut()\n\nconst defaultLocale = appStore.language || 'zh-CN'\n\nconst i18n = createI18n({\n  locale: defaultLocale,\n  fallbackLocale: 'en-US',\n  allowComposition: true,\n  messages: {\n    'en-US': enUS,\n    'ko-KR': koKR,\n    'zh-CN': zhCN,\n    'zh-TW': zhTW,\n    'ru-RU': ruRU,\n    'vi-VN': viVn,\n    'fr-FR': frFr,\n    'tr-TR': trTr,\n  },\n})\n\nexport const t = i18n.global.t\n\nexport function setLocale(locale: Language) {\n  i18n.global.locale = locale\n}\n\nexport function setupI18n(app: App) {\n  app.use(i18n)\n}\n\nexport default i18n\n"
  },
  {
    "path": "src/locales/ko-KR.ts",
    "content": "export default {\n  common: {\n    add: '추가',\n    addSuccess: '추가 성공',\n    edit: '편집',\n    editSuccess: '편집 성공',\n    delete: '삭제',\n    deleteSuccess: '삭제 성공',\n    save: '저장',\n    saveSuccess: '저장 성공',\n    reset: '초기화',\n    action: '액션',\n    export: '내보내기',\n    exportSuccess: '내보내기 성공',\n    import: '가져오기',\n    importSuccess: '가져오기 성공',\n    clear: '비우기',\n    clearSuccess: '비우기 성공',\n    yes: '예',\n    no: '아니오',\n    confirm: '확인',\n    download: '다운로드',\n    noData: '데이터 없음',\n    wrong: '문제가 발생했습니다. 나중에 다시 시도하십시오.',\n    success: '성공',\n    failed: '실패',\n    verify: '검증',\n    unauthorizedTips: '인증되지 않았습니다. 먼저 확인하십시오.',\n    stopResponding: '응답 중지',\n  },\n  chat: {\n    newChatButton: '새로운 채팅',\n    //placeholder: '무엇이든 물어보세요...(Shift + Enter = 줄바꿈, \"/\"를 눌러서 힌트를 보세요)',\n    placeholder: '할 말을 입력하거나 스크린샷을 붙여넣거나 파일을 드래그 앤 드롭할 수 있습니다.',\n    placeholderMobile: '무엇이든 물어보세요...',\n    copy: '복사',\n    copied: '복사됨',\n    copyCode: '코드 복사',\n    clearChat: '채팅 비우기',\n    clearChatConfirm: '이 채팅을 비우시겠습니까?',\n    exportImage: '이미지 내보내기',\n    exportImageConfirm: '이 채팅을 png로 내보내시겠습니까?',\n    exportSuccess: '내보내기 성공',\n    exportFailed: '내보내기 실패',\n    usingContext: '컨텍스트 모드',\n    turnOnContext: '현재 모드에서는 이전 대화 기록을 포함하여 메시지를 보낼 수 있습니다.',\n    turnOffContext: '현재 모드에서는 이전 대화 기록을 포함하지 않고 메시지를 보낼 수 있습니다.',\n    deleteMessage: '메시지 삭제',\n    deleteMessageConfirm: '이 메시지를 삭제하시겠습니까?',\n    deleteHistoryConfirm: '이 기록을 삭제하시겠습니까?',\n    clearHistoryConfirm: '채팅 기록을 삭제하시겠습니까?',\n    preview: '미리보기',\n    showRawText: '원본 텍스트로 보기',\n  },\n  setting: {\n    setting: '설정',\n    general: '일반',\n    advanced: '고급',\n    config: '설정',\n    avatarLink: '아바타 링크',\n    name: '이름',\n    description: '설명',\n    backgroundImage: '배경 이미지',\n    role: '역할',\n    temperature: '온도',\n    top_p: 'Top_p',\n    resetUserInfo: '사용자 정보 초기화',\n    chatHistory: '채팅 기록',\n    theme: '테마',\n    language: '언어',\n    webdavSync: 'WebDAV 동기화',\n    webdavConfig: '구성',\n    webdavUrl: 'WebDAV 주소',\n    webdavUsername: '사용자 이름',\n    webdavPassword: '비밀번호',\n    webdavConfigError: '완전한 WebDAV 구성을 입력하세요',\n    webdavNotConfigured: '먼저 WebDAV를 구성하세요',\n    webdavSyncSuccess: '동기화 성공',\n    webdavSyncError: '동기화 실패',\n    webdavTest: '연결 테스트',\n    webdavUpload: '업로드',\n    webdavDownload: '다운로드',\n    api: 'API',\n    reverseProxy: '리버스 프록시',\n    timeout: '타임아웃',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS 프록시',\n    balance: 'API 잔액',\n    monthlyUsage: '월 사용량',\n  },\n  store: {\n    siderButton: '프롬프트 저장소',\n    local: '로컬',\n    online: '온라인',\n    title: '제목',\n    description: '설명',\n    clearStoreConfirm: '데이터를 삭제하시겠습니까?',\n    importPlaceholder: '여기에 JSON 데이터를 붙여넣으십시오',\n    addRepeatTitleTips: '제목 중복됨, 다시 입력하십시오',\n    addRepeatContentTips: '내용 중복됨: {msg}, 다시 입력하십시오',\n    editRepeatTitleTips: '제목 충돌, 수정하십시오',\n    editRepeatContentTips: '내용 충돌 {msg} , 수정하십시오',\n    importError: '키 값 불일치',\n    importRepeatTitle: '제목이 반복되어 건너뜀: {msg}',\n    importRepeatContent: '내용이 반복되어 건너뜀: {msg}',\n    onlineImportWarning: '참고: JSON 파일 소스를 확인하십시오!',\n  },\n\n  \"mj\": {\n    \"setOpen\": \"OpenAI 관련\",\n    \"setOpenPlaceholder\": \"http(s)://를 포함해야 함\"\n    ,\"setOpenUrl\": \"OpenAI 인터페이스 주소\"\n    ,\"setOpenKeyPlaceholder\": \"비밀번호 액세스 제한을 우회하기 위해 사용자 지정 OpenAI 키 사용\"\n    ,\"setMj\": \"Midjourney 관련\"\n    ,\"setMjUrl\": \"Midjourney 인터페이스 주소:\"\n    ,\"setMjKeyPlaceholder\": \"비밀번호 액세스 제한을 우회하기 위해 사용자 지정 Api Secret 사용\"\n    ,\"setUploader\": \"업로드 관련\"\n    ,\"setUploaderUrl\": \"업로드 주소:\"\n    ,\"setBtSave\": \"저장\"\n    ,\"setBtBack\": \"기본으로 복원\",\n    \"redraw\": \"부분 재그림\",\n    \"fail1\": \"고객님은 너무 급해하지 마세요. 로딩 중입니다.\",\n    \"success1\": \"이미지가 성공적으로 새로고쳐졌습니다!\",\n    \"high_variation\": \"강한 변화\",\n    \"low_variation\": \"약한 변화\",\n    \"p15\": \"확대 1.5배\",\n    \"p20\": \"확대 2배\",\n    \"p100\": \"표준\",\n    \"retry\": \"분석 다시 시도\",\n    \"pan_left\": \"왼쪽으로 다시 분석\",\n    \"pan_right\": \"오른쪽으로 다시 분석\",\n    \"pan_up\": \"위로 다시 분석\",\n    \"pan_down\": \"아래로 다시 분석\",\n    \"up2\": \"고화질 2배\",\n    \"up4\": \"고화질 4배\" ,\n\n    \"thinking\": \"생각 중...\",\n    \"noReUpload\": \"다시 업로드할 수 없습니다\",\n    \"uploading\": \"업로딩 중...\",\n    \"uploadSuccess\": \"업로드 성공\",\n    \"uploadFail\": \"업로드 실패:\",\n    \"upPdf\": \"<span>이미지 또는 첨부 파일 업로드<br/>이미지, PDF, EXCEL 및 기타 문서를 업로드할 수 있습니다</span><p>드래그 앤 드롭 지원</p>\",\n    \"upImg\": \"<span><b>이미지 업로드</b><br/>자동으로 gpt-4-vision-preview 모델을 호출합니다<br>참고: 추가 이미지 비용이 발생할 수 있습니다<br/>포맷: jpeg, jpg, png, gif</span><p>드래그 앤 드롭 지원</p> <p class=\\\"pt-2\\\"><b>MP3 MP4 업로드</b> <br>자동으로 whisper-1 모델을 호출합니다<br>포맷: mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n    \"clearAll\": \"매개변수 지우기\",\n    \"czoom\": \"사용자 정의\",\n    \"customTitle\": \"사용자 정의 줌\",\n    \"zoominfo\": \"줌 값 수정, 범위는 1.0에서 2.0까지이며 기본 설정은 1.8로 설정됩니다\",\n\n    \"modleSuccess\": \"모델이 성공적으로 로드되었습니다\",\n    \"setingSuccess\": \"설정이 성공적으로 완료되었습니다\",\n    \"tokenInfo1\": \"남은 토큰 = 모델 길이 - 역할 설정 - 컨텍스트 (대화 기록) - 답변 수 - 현재 입력\",\n    \"tokenInfo2\": \"역할 설정을 비워두면 시스템에서 기본 값을 제공합니다.\",\n    \"noSuppertModel\": \"새로 고침, 현재 이 모델은 지원되지 않습니다!\",\n    \"failOcr\": \"인식 실패\",\n    \"remain\": \"남:\",\n\n    \"totalUsage\": \"총 구독 금액\",\n    \"disableGpt4\": \"GPT4 비활성화됨\",\n    \"setTextInfo\": \"OpenAI API 키 오류, 여기를 클릭하여 다시 시도\",\n\n    \"attr1\": \"첨부\",\n    \"ulink\": \"원본 이미지 링크\",\n    \"copyFail\": \"복사 실패\",\n    \"tts\": \"텍스트 음성 변환 (TTS)\",\n    \"fail\": \"오류가 발생했습니다\",\n    \"noSupperChrom\": \"브라우저가 지원되지 않습니다!\",\n    \"lang\": \"음성\",\n    \"ttsLoading\": \"음성으로 변환 중...\",\n    \"ttsSuccess\": \"변환 성공\",\n    \"micIng\": \"녹음 중, 무엇인가 말해보세요...\",\n    \"mStart\": \"시작\",\n    \"mPause\": \"일시 정지\",\n    \"mGoon\": \"계속\",\n    \"mRecord\": \"다시 녹음\",\n    \"mPlay\": \"재생\",\n    \"mCanel\": \"취소\",\n    \"mSent\": \"전송\",\n    \"findVersion\": \"최신 버전 찾기\",\n    \"yesLastVersion\": \"최신 버전입니다\",\n    \"infoStar\": \"이 프로젝트는 <a class=\\\"text-blue-600 dark:text-blue-500\\\" href=\\\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\\\"_blank\\\">GitHub</a>에서 오픈 소스로 제공되며 MIT 라이선스를 기반으로 하며 어떠한 유료 행위도 없습니다! </p><p>이 프로젝트가 도움이 되었다면 GitHub에서 별을 주시기 바랍니다. 감사합니다!\",\n    \"setBtSaveChat\": \"대화만 저장\",\n    \"setBtSaveSys\": \"시스템에 저장\",\n\n    \"wsrvClose\": \"닫기 wsrv\",\n    \"wsrvOpen\": \"열기 wsrv\",\n\n    \"temperature\": \"랜덤성\",\n    \"temperatureInfo\": \"(temperature) 값이 증가함에 따라 응답이 더 랜덤해집니다\",\n    \"top_p\": \"상위 확률 샘플링\",\n    \"top_pInfo\": \"(top_p)은 랜덤성과 유사하지만 온도와 함께 변경되어서는 안 됩니다\",\n    \"presence_penalty\": \"주제 신선도\",\n    \"presence_penaltyInfo\": \"(presence_penalty) 값이 증가함에 따라 새로운 주제로 확장될 가능성이 높아집니다\",\n    \"frequency_penalty\": \"빈도 패널티\",\n    \"frequency_penaltyInfo\": \"(frequency_penalty) 값이 증가함에 따라 반복된 단어를 줄이는 가능성이 높아집니다\",\n    \"tts_voice\": \"TTS 음성 캐릭터\",\n    \"typing\": \"입력 중\",\n    \"authErro\": \"인가 실패\",\n    \"authBt\": \"인가 액세스 암호를 다시 입력하십시오\",\n    \"micWhisper\": \"속삭임 음성 인식\",\n    \"micAsr\": \"즉시 인식\",\n    \"micRec\": \"녹음 시작, 말씀하세요! 2초 동안 소리가 없으면 자동으로 중지됩니다.\",\n    \"micRecEnd\": \"녹음이 종료되었습니다\",\n\n    subtle: '고화질 2배'\n    ,creative: '고화질 2배. 창의적'\n    ,gpt_gx: 'GPTs는 g-*를 사용합니다',\n\n    \"ideoabout\": \"아이디어그램에 대하여\",\n    \"ideoserver\": \"아이디어그램 서버\",\n    \"ideokeyPlaceholder\": \"아이디어그램의 API 키 (선택 사항)\",\n    \"ideopls\": \"이미지 설명 프롬프트\",\n    \"nohead\": \"포함하지 않음\",\n\n    klingabout: '클링 관련',\n    klingserver: '클링 API 주소',\n    klingkeyPlaceholder: '클링 API 키 (선택 사항)',\n    klingkey: '클링 키',\n    mode: '모드',\n    duration: '지속 시간',\n    negative_prompt: '여기에 객체가 없는 텍스트를 입력하세요',\n    std: '고성능',\n    pro: '고품질',\n    needImg: '효과를 보려면 참조 이미지를 업로드하세요!',\n    seed: '시드 번호 1~2147483647',\n    klingInfo: '설명: <li>1. 고품질은 가격의 3.5배입니다</li> <li>2. 10초는 가격의 2배입니다</li> <li>3. 마지막 프레임은 효과를 위해 참조 이미지가 필요합니다</li>'\n\n    ,\"camera_type\": \"렌즈\",\n    \"cnull\": \"스마트 매칭\",\n    \"down_back\": \"아래로 이동하고 멀리하기\",\n    \"forward_up\": \"앞으로 밀고 위로 이동하기\",\n    \"right_turn_forward\": \"오른쪽으로 돌리고 앞으로 밀기\",\n    \"left_turn_forward\": \"왼쪽으로 돌리고 앞으로 밀기\"\n    ,kling:'Kling',\n    rttab: '음성',\n    rtinfo: '실시간 음성 대화 서비스 (realtime)',\n    rtsetting: '서버를 설정하십시오. 현재 Realtime은 원격 서비스만 지원합니다. 로컬 서비스가 필요하면 저자에게 문의하십시오.',\n    rjcloded: '연결이 끊어졌습니다',\n    checkkey: 'API 키가 올바른지 확인하십시오',\n    rtsuccess: '연결이 정상이며 통화를 유지하고 있습니다',\n    rtservererror: 'WebSocket 서버 연결 오류!',\n    rtservererror2: '녹음이 지원되지 않습니다. 장치 문제일 수 있습니다!',\n    rtconecting: '서버에 연결 중',\n\n    \"confirmDelete\": \"삭제하시겠습니까?\",\n    \"pikaabout\": \"Pika 관련\",\n    \"pikaserver\": \"Pika API 주소\",\n    \"pikakeyPlaceholder\": \"Pika API 키 (선택 사항)\",\n    \"createFail\": \"생성 실패\",\n    \"selecteff\": \"참고 효과\",\n\n    \"udioabout\": \"Udio에 대하여\",\n    \"udiokeyPlaceholder\": \"Udio API 키 (선택 사항)\",\n    \"udioserver\": \"Udio API 주소\",\n    \"ud_prompt\": \"프롬프트\",\n    \"ud_prompt_pls\": \"프롬프트: 설명, 스타일\",\n    \"ud_ly_write\": \"사용자 정의 가사\",\n    \"ud_ly_auto\": \"지능형 가사\",\n    \"ud_ly_null\": \"순수 음악\",\n    \"ud_v32\": \"저렴한\",\n    \"ud_v130\": \"긴 시간\",\n    \"ud_info\": \"주의: <ul><li>1. Udio-32는 짧은 길이를 가집니다</li><li>2. Udio-130은 Udio-32의 2배 가격입니다</li><li>3. 프롬프트에는 스타일, 설명 등을 포함할 수 있습니다</li></ul>\",\n    \"ud_fail\": \"이 곡 생성에 실패했습니다!\",\n    \"ud_doing\": \"생성 중에는 재생할 수 없습니다\",\n    \"ud_continuation\": \"계속\",\n    \"ud_precede\": \"이전\",\n\n    \"upImg2\": \"<span><b>이미지 업로드</b><br/>이 모델은 이미지 인식을 지원합니다<br>주의: 추가 이미지 요금이 발생합니다<br/>형식: jpeg jpg png gif</span><p>드래그 앤 드롭 지원</p> <p class=\\\"pt-2\\\"><b>MP3 MP4 업로드</b> <br>자동으로 whisper-1 모델을 호출합니다<br>형식: mp3 mp4 mpeg mpga m4a wav webm</p>\",\n    \"rml_info\": \"주의:<ul><li>1. 반드시 이미지를 포함해야 합니다</li><li>2. 모델은 gen3a_turbo 하나만 있습니다</li><li>3. 10초 가격은 5초의 두 배입니다</li></ul>\",\n    \"rml_heng\": \"가로 모드\",\n    \"rml_shu\": \"세로 모드\",\n  \n    \"pixabout\": \"Pixverse 관련\",\n    \"pixkeyPlaceholder\": \"Pixverse API 키는 비워둘 수 있습니다\",\n    \"pixserver\": \"Pixverse API 주소\",\n    \"pixinfo\": \" 설명:<br> <ul> <li>1. v3.5 360p 지속시간 5초 모드 Normal을 기준으로 함</li><li>2. v2.5는 0.5배입니다</li> <li>3. 지속시간 10초는 2배입니다</li> <li>4. 540P는 1.5배, 720P는 2배, 1080P는 4배입니다</li> <li>5. 성능 모드는 2배입니다</li> <li>6. 배수는 곱해지며, 예를 들어 720P 지속시간 10초는 2*2로 4배가 되고, 성능을 추가하면 8배가 됩니다</li></ul>\",\n\n    \"riffabout\": \"Riffusion 관련\",\n    \"riffkeyPlaceholder\": \"Riffusion API 키 (선택 사항)\",\n    \"riffserver\": \"Riffusion API 주소\",\n    \"riffinfo\": \"설명\",\n\n    \"editImage\": \"이미지 편집\",\n    \"editVideo\": \"이미지에서 비디오 생성\",\n    \"moreset\": \"추가 설정\",\n \n  },\n  \"mjset\": {\n    \"server\": \"서버\"\n    ,\"about\": \"소개\"\n    ,\"model\": \"모델\"\n    ,\"sysname\": \"AI 그림\"\n  },\n  \"mjtab\": {\n    \"chat\": \"대화\"\n    ,\"draw\": \"그림\"\n    ,\"drawinfo\": \"AI 그림 Midjourney 엔진\"\n    ,\"gallery\": \"갤러리\"\n    ,\"galleryInfo\": \"내 갤러리\"\n  },\n  \"mjchat\": {\n    \"loading\": \"이미지 로드 중\"\n    ,\"openurl\": \"직접 링크 열기\"\n    ,\"failReason\": \"실패 이유:\"\n    ,\"reload\": \"재로드\"\n    ,\"progress\": \"진행:\"\n    ,\"wait\": \"작업이 제출되었습니다. 기다려주세요...\"\n    ,\"reroll\": \"재그림\"\n    ,\"wait2\": \"작업 {id}이(가) 제출되었습니다. 기다려주세요\"\n    ,\"redrawEditing\": \"일부 재그림 편집\"\n    ,\"face\": \"얼굴 바꾸기\"\n    ,\"blend\": \"혼합\"\n    ,\"draw\": \"그림 그리기\"\n    ,\"submiting\": \"제출 중\"\n    ,\"submit\": \"제출\"\n    ,\"wait3\": \"닫지 마세요! 이미지 생성 중...\"\n    ,\"success\": \"저장 성공\"\n    ,\"successTitle\": \"성공\"\n    ,\"modlePlaceholder\": \"여러 개의 사용자 정의 모델은 띄어쓰기로 구분됩니다. 필수 사항은 아닙니다.\"\n    ,\"myModle\": \"내 모델\"\n    ,\"historyCnt\": \"컨텍스트 수\"\n    ,\"historyToken\": \"더 많은 컨텍스트는 기억을 더 정확하게 만들지만 더 많은 크레딧을 소비할 수 있습니다.\"\n    ,\"historyTCnt\": \"답장 수\"\n    ,\"historyTCntInfo\": \"답장 수가 많을수록 더 많은 크레딧이 소비될 수 있습니다.\"\n    ,\"role\": \"역할 설정\"\n    ,\"rolePlaceholder\": \"대화에 고유한 역할을 설정하십시오. 필수는 아닙니다.\"\n    ,\"loading2\": \"로딩 중...\"\n    ,\"loadmore\": \"더 보기\"\n    ,\"nofind\": \"찾을 수 없음\"\n    ,\"nofind2\": \"관련 내용을 찾을 수 없습니다. 다음을 시도해 보십시오.\"\n    ,\"success2\": \"전환 성공!\"\n    ,\"modelChange\": \"모델 변경\"\n    ,\"search\": \"검색\"\n    ,\"searchPlaceholder\": \"GPTs 이름, 소개\"\n    ,\"attr\": \"첨부 파일\"\n    ,\"noproduct\": \"갤러리에 작품이 없습니다.\"\n    ,\"myGallery\": \"내 갤러리\"\n    ,\"yourHead\": \"당신의 프로필 사진\"\n    ,\"your2Head\": \"스타 이미지\"\n    ,\"tipInfo\": \"설명：<li>1. 이미지에는 얼굴이 반드시 포함되어야 합니다. 그렇지 않으면 이미지가 생성되지 않습니다.</li> <li>2. '스타 이미지'는 먼저 MJ 그림으로 만들 수 있습니다.</li> <li>3. '스타 이미지'는 애니메이션 이미지로도 괜찮습니다.</li> <li>4. '당신의 프로필 사진'은 1인치 개인 사진을 사용하는 것이 좋습니다.</li>\"\n    ,\"placeInput\": \"힌트를 입력하세요!\"\n    ,\"more5sb\": \"최대 5장의 이미지를 업로드할 수 있습니다.\"\n    ,\"exSuccess\": \"내보내기 성공... 다운로드 창을 확인하세요.\"\n    ,\"downloadSave\": \"ai그림.txt\"\n    ,\"noproducet\": \"아직 미완성 작품이 없습니다.\"\n    ,\"imgBili\": \"이미지 비율\"\n    ,\"imagEx\": \"작품 이미지 링크 내보내기\"\n    ,\"prompt\": \"힌트\"\n    ,\"imgCYes\": \"쿠션 이미지 포함\"\n    ,\"imgCUpload\": \"자체 쿠션 이미지 업로드\"\n    ,\"imgCInfo\": \"쿠션 이미지 안내：<br/> 1. 쿠션 이미지는 자체 이미지를 기본으로 사용하여 MJ로 그림을 그릴 수 있습니다.<br/> 2. 최대 5 장의 쿠션 이미지를 사용할 수 있으며 각 이미지의 크기는 1M를 초과하지 않아야 합니다.<br/>\"\n    ,\"imgCadd\": \"+추가\"\n    ,\"del\": \"삭제\"\n    ,\"img2text\": \"이미지에서 텍스트 생성\"\n    ,\"img2textinfo\": \"힌트가 어떻게 쓰여야 할지 모르겠나요? 이미지에서 텍스트를 생성해 보세요! <br/>이미지를 제출하면 힌트가 생성됩니다.\"\n    ,\"traning\": \"번역 중...\"\n    ,\"imgcreate\": \"이미지 생성\"\n    ,\"imginfo\": \"기타 매개변수：<li>1 --no를 무시하면 --no car가 이미지에 표시되지 않습니다.</li><li>2 --seed는 먼저 시드를 얻을 수 있습니다. --seed 123456</li> <li>3 --chaos 10은 혼합(범위: 0-100)</li> <li>4 --tile 조각화</li>\"\n    ,\"tStyle\": \"스타일\"\n    ,\"tView\": \"시점\"\n    ,\"tShot\": \"캐릭터 샷\"\n    ,\"tLight\": \"조명\"\n    ,\"tQuality\": \"화질\"\n    ,\"tStyles\": \"아트 정도\"\n    ,\"tVersion\": \"모델 버전\"\n    ,\"dalleInfo\": \"설명：<li>1. DALL-E는 OpenAI에서 제공하는 그림 모델입니다.</li>  <li>2. OpenAI의 이미지는 일시적입니다. 백업을 잘 해 두세요.</li>   <li>3. 주의: 1790px 이미지의 가격은 두 배입니다.</li> \"\n    ,\"version\": \"버전\"\n    ,\"size\": \"크기\"\n    ,\"blendInfo\": \"설명：<li>1. 최소 2 장의 이미지를 합성하십시오.</li> <li>2. 최대 6 장의 이미지를 업로드할 수 있습니다.</li> \"\n    ,\"blendStart\": \"합성 시작\"\n    ,\"no2add\": \"이미지를 중복해서 추가하지 마십시오.\"\n    ,\"add2more\": \"두 장 이상의 이미지를 추가하십시오.\"\n    ,\"no1m\": \"이미지 크기는 1M를 초과할 수 없습니다.\"\n    ,\"setSync\": \"Midjourney와 Suno를 동기화하십시오\"\n    ,\"imgExt\": \"이미지는 jpg, gif, png, jpeg 형식만 지원됩니다.\"\n    ,\"addGPTS\": \"GPTs 추가\",\n    \"addPlaceholder\": \"여기에 GPTs의 GID를 붙이거나 GPTs의 링크를 직접 붙여 넣을 수 있습니다.\",\n    \"gidError\": \"유효한 GID를 찾을 수 없습니다. 다시 작성해주세요.\",\n    \"success3\": \"GPTs 추가 성공!\"\n    \n  },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n  ,suno:{\n    \"description\": \"설명 모드\",\n    \"custom\": \"전문가 모드\",\n    \"style\": \"노래 스타일\",\n    \"stylepls\": \"노래 이름, 예: 팝 음악\",\n    \"emputy\": \"내용 없음\",\n    \"noly\": \"가사 없음\",\n    \"inputly\": \"노래 이름 또는 가사를 입력하세요\",\n    \"doingly\": \"진행 중입니다. 잠시 기다려주세요.\",\n    \"doingly2\": \"가사 가져오는 중...\",\n    \"title\": \"노래 제목\",\n    \"titlepls\": \"노래 이름, 예: 휴가\",\n    \"desc\": \"노래 설명\",\n    \"descpls\": \"노래 설명, 예: 휴가에 관한 오리지널 팝 음악\",\n    \"noneedly\": \"가사 필요 없음\",\n    \"rank\": \"랜덤 선택\",\n    \"ly\": \"가사\",\n    \"lypls\": \"가사: 일정한 형식으로\",\n    \"generate\": \"노래 만들기\",\n    \"generately\": \"가사 생성\",\n    \"nodata\": \"곡 목록을 보려면 먼저 곡을 작성하세요\",\n    \n    \"menu\": \"음악\",\n    \"menuinfo\": \"Suno 음악 생성\",\n    \"server\": \"Suno API 엔드포인트\",\n    \"serverabout\": \"Suno 관련\",\n    \"setOpenKeyPlaceholder\": \"Suno API에 대한 관련 키; 선택 사항\",\n\n    upMps: '오디오 업로드',\n    extend: '확장',\n    extendFrom: '출처',\n    extendAt: '시작',\n    fail: '실패',\n    info: '설명:<br>오디오 업로드 시간은 6초에서 60초 사이여야 합니다'\n\n   }\n   ,video:{\n    \"menu\": \"비디오\",\n    \"menuinfo\": \"Luma 및 다른 비디오 제작\",\n    \"descpls\": \"비디오 제작 설명\",\n    \"lumaabout\": \"Luma에 대해\",\n    \"lumaserver\": \"Luma API 엔드포인트\",\n    \"setOpenKeyPlaceholder\": \"Luma API 키, 선택 사항\",\n    \"generate\": \"비디오 생성\",\n    \"nodata\": \"사용할 수 있는 비디오가 없습니다. 먼저 생성하세요!\",\n    \"selectimg\": \"이미지 선택\",\n    \"clear\": \"지우기\",\n    \"plsInput\": \"내용을 입력하세요!\",\n    \"submitSuccess\": \"성공적으로 제출되었습니다!\",\n    \"process\": \"비디오 생성 중...\",\n    \"repeat\": \"재시도\",\n\n    \"lumainfo\": \"설명: <ul><li>1. Pro 및 relax 데모 비디오는 워터마크가 있는 링크입니다.</li><li>2. 워터마크 없는 Pro 버전은 '다운로드' 버튼을 통해 다운로드 링크를 받아야 합니다.</li><li>3. Pro 버전 링크는 시간 제한이 있으며, MP4 파일을 로컬에 즉시 저장해야 합니다.</li><li>4. Pro 버전은 생성 후 30분 이내에 MP4 파일을 로컬에 저장해야 하며, 채널이 차단되거나 중단될 수 있습니다.</li><li>5. Pro 버전의 다운로드 링크가 무효일 경우 워터마크가 있는 비디오 링크가 제공됩니다.</li></ul>\",\n    \"runwayabout\": \"Runway 관련\",\n    \"runwayserver\": \"Runway API 주소\",\n    \"setOpenKeyPlaceholder2\": \"Runway API 키, 선택 사항\",\n    \"endImg\": \"마지막 이미지\",\n    \"runwayinfo\": \"설명: <ul><li>1. Runway 이미지 및 비디오는 유효 기간이 있습니다.</li><li>2. 비디오 생성 후 30분 이내에 MP4 파일을 로컬에 저장해주세요.</li></ul>\",\n    \"nosup\": \"일시적으로 지원되지 않음\",\n    \"rwgen2\": \"버전: Gen-2, 비용 효율적\",\n    \"rwgen3\": \"버전: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\"\n\n  },\n  dance:{\n    menu: \"댄스\",\n    menuinfo: \"Viggle 및 기타와 함께 댄스 비디오 제작\",\n    character: \"캐릭터\",\n    viggleabout: \"Viggle 소개\",\n    viggleserver: \"Viggle API 엔드포인트\",\n    setOpenKeyPlaceholder: \"Viggle API 키, 선택 사항\",\n    info: \"지침:<br>1. 캐릭터 이미지는 전신 사진이 좋습니다.<br>2. 댄스 템플릿 비디오는 개인 비디오여야 하며, 그룹 댄스가 아니어야 합니다.\",\n    model: \"모델\",\n    bgw: \"백색 배경\",\n    bgg: \"초록색 배경\",\n    bgmoban: \"템플릿 배경\",\n    bgrole: \"캐릭터 배경\",\n    gring: \"생성 중...\",\n    uprolefirst: \"먼저 캐릭터 이미지를 업로드하세요\",\n    uprolefail: \"업로드 실패\",\n    upvideo: \"+ 템플릿 댄스 비디오 업로드\",\n    usevideo: \"+ 공식 템플릿 사용\",\n    moban: \"댄스 템플릿\",\n    moban2: \"템플릿 이름\",\n    use: \"사용\"\n}\n\n}\n"
  },
  {
    "path": "src/locales/ru-RU.ts",
    "content": "export default {\n  common: {\n    add: 'Добавить',\n    addSuccess: 'Добавлено успешно',\n    edit: 'Редактировать',\n    editSuccess: 'Изменено успешно',\n    delete: 'Удалить',\n    deleteSuccess: 'Удалено успешно',\n    save: 'Сохранить',\n    saveSuccess: 'Сохранено успешно',\n    reset: 'Сбросить',\n    action: 'Действие',\n    export: 'Экспортировать',\n    exportSuccess: 'Экспорт выполнен успешно',\n    import: 'Импортировать',\n    importSuccess: 'Импорт выполнен успешно',\n    clear: 'Очистить',\n    clearSuccess: 'Очищено успешно',\n    yes: 'Да',\n    no: 'Нет',\n    confirm: 'Подтвердить',\n    download: 'Загрузить',\n    noData: 'Нет данных',\n    wrong: 'Что-то пошло не так, пожалуйста, повторите попытку позже.',\n    success: 'Успех',\n    failed: 'Не удалось',\n    verify: 'Проверить',\n    unauthorizedTips: 'Не авторизован, сначала подтвердите свою личность.',\n    stopResponding: 'Прекращение отклика',\n  },\n  chat: {\n    newChatButton: 'Новый чат',\n    //placeholder: 'Спросите меня о чем-нибудь ... (Shift + Enter = перенос строки, \"/\" для вызова подсказок)',\n    placeholder: 'Вы можете ввести что-то сказать, или вы можете вставить скриншоты или перетащить файлы.',\n    placeholderMobile: 'Спросите меня о чем-нибудь ...',\n    copy: 'Копировать',\n    copied: 'Скопировано',\n    copyCode: 'Копировать код',\n    clearChat: 'Очистить чат',\n    clearChatConfirm: 'Вы уверены, что хотите очистить этот чат?',\n    exportImage: 'Экспорт в изображение',\n    exportImageConfirm: 'Вы уверены, что хотите экспортировать этот чат в формате PNG?',\n    exportSuccess: 'Экспортировано успешно',\n    exportFailed: 'Не удалось выполнить экспорт',\n    usingContext: 'Режим контекста',\n    turnOnContext: 'В текущем режиме отправка сообщений будет включать предыдущие записи чата.',\n    turnOffContext: 'В текущем режиме отправка сообщений не будет включать предыдущие записи чата.',\n    deleteMessage: 'Удалить сообщение',\n    deleteMessageConfirm: 'Вы уверены, что хотите удалить это сообщение?',\n    deleteHistoryConfirm: 'Вы уверены, что хотите очистить эту историю?',\n    clearHistoryConfirm: 'Вы уверены, что хотите очистить историю чата?',\n    preview: 'Предварительный просмотр',\n    showRawText: 'Показать как обычный текст',\n  },\n  setting: {\n    setting: 'Настройки',\n    general: 'Общее',\n    advanced: 'Дополнительно',\n    config: 'Конфигурация',\n    avatarLink: 'Ссылка на аватар',\n    name: 'Имя',\n    description: 'Описание',\n    backgroundImage: 'Фоновое изображение',\n    role: 'Роль',\n    temperature: 'Температура',\n    top_p: 'Top_p',\n    resetUserInfo: 'Сбросить информацию о пользователе',\n    chatHistory: 'История чата',\n    theme: 'Тема',\n    language: 'Язык',\n    webdavSync: 'Синхронизация WebDAV',\n    webdavConfig: 'Конфигурация',\n    webdavUrl: 'URL WebDAV',\n    webdavUsername: 'Имя пользователя',\n    webdavPassword: 'Пароль',\n    webdavConfigError: 'Пожалуйста, заполните полную конфигурацию WebDAV',\n    webdavNotConfigured: 'Пожалуйста, сначала настройте WebDAV',\n    webdavSyncSuccess: 'Синхронизация успешна',\n    webdavSyncError: 'Ошибка синхронизации',\n    webdavTest: 'Проверить соединение',\n    webdavUpload: 'Загрузить',\n    webdavDownload: 'Скачать',\n    api: 'API',\n    reverseProxy: 'Обратный прокси-сервер',\n    timeout: 'Время ожидания',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS-прокси',\n    balance: 'Баланс API',\n    monthlyUsage: 'Ежемесячное использование',\n  },\n  store: {\n    siderButton: 'Хранилище подсказок',\n    local: 'Локальное',\n    online: 'Онлайн',\n    title: 'Название',\n    description: 'Описание',\n    clearStoreConfirm: 'Вы действительно хотите очистить данные?',\n    importPlaceholder: 'Пожалуйста, вставьте здесь JSON-данные',\n    addRepeatTitleTips: 'Дубликат названия, пожалуйста, введите другое название',\n    addRepeatContentTips: 'Дубликат содержимого: {msg}, пожалуйста, введите другой текст',\n    editRepeatTitleTips: 'Конфликт названий, пожалуйста, измените название',\n    editRepeatContentTips: 'Конфликт содержимого {msg}, пожалуйста, измените текст',\n    importError: 'Не совпадает ключ-значение',\n    importRepeatTitle: 'Название повторяющееся, пропускается: {msg}',\n    importRepeatContent: 'Содержание повторяющееся, пропускается: {msg}',\n    onlineImportWarning: 'Внимание! Проверьте источник JSON-файла!',\n    downloadError: 'Проверьте состояние сети и правильность JSON-файла',\n  },\n  \"mj\": {\n    \"setOpen\": \"OpenAI связанный\",\n    \"setOpenPlaceholder\": \"Должен содержать http(s)://\",\n    \"setOpenUrl\": \"Адрес интерфейса OpenAI\",\n    \"setOpenKeyPlaceholder\": \"Используйте свой собственный ключ OpenAI для обхода ограничений доступа по паролю\",\n    \"setMj\": \"Midjourney связанный\",\n    \"setMjUrl\": \"Адрес интерфейса Midjourney:\",\n    \"setMjKeyPlaceholder\": \"Используйте свой собственный Api Secret для обхода ограничений доступа по паролю\",\n    \"setUploader\": \"Связанный с загрузкой\",\n    \"setUploaderUrl\": \"Адрес загрузки:\",\n    \"setBtSave\": \"Сохранить\",\n    \"setBtBack\": \"Восстановить по умолчанию\",\n\n\n  \"redraw\": \"Частичная Перерисовка\",\n  \"fail1\": \"Пожалуйста, будьте терпеливы, идет загрузка.\",\n  \"success1\": \"Изображение успешно обновлено!\",\n  \"high_variation\": \"Сильные Изменения\",\n  \"low_variation\": \"Слабые Изменения\",\n  \"p15\": \"Увеличение 1.5x\",\n  \"p20\": \"Увеличение 2x\",\n  \"p100\": \"Обычное\",\n  \"retry\": \"Повторный Анализ\",\n  \"pan_left\": \"Переанализировать влево\",\n  \"pan_right\": \"Переанализировать вправо\",\n  \"pan_up\": \"Переанализировать вверх\",\n  \"pan_down\": \"Переанализировать вниз\",\n  \"up2\": \"Высокое Разрешение 2x\",\n  \"up4\": \"Высокое Разрешение 4x\",\n\n  \"thinking\": \"В раздумьях...\",\n  \"noReUpload\": \"Нельзя повторно загружать\",\n  \"uploading\": \"Загрузка...\",\n  \"uploadSuccess\": \"Загрузка успешна\",\n  \"uploadFail\": \"Ошибка загрузки:\",\n  \"upPdf\": \"<span>Загрузите изображение или вложение<br/>Вы можете загрузить изображения, PDF, EXCEL и другие документы</span><p>Поддерживается перетаскивание</p>\",\n  \"upImg\": \"<span><b>Загрузить изображение</b><br/>Автоматически вызовет модель gpt-4-vision-preview<br>Примечание: Могут действовать дополнительные тарифы за изображения<br/>Форматы: jpeg, jpg, png, gif</span><p>Поддерживается перетаскивание</p> <p class=\\\"pt-2\\\"><b>Загрузить MP3 MP4</b> <br>Автоматически вызовет модель whisper-1<br>Форматы: mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n  \"clearAll\": \"Очистить параметры\",\n  \"czoom\": \"Настроить\",\n  \"customTitle\": \"Настроить зум\",\n  \"zoominfo\": \"Измените значение зума, диапазон от 1.0 до 2.0, по умолчанию установлено 1.8\",\n\n  \"modleSuccess\": \"Модель успешно загружена\",\n  \"setingSuccess\": \"Настройки успешно выполнены\",\n\n \"tokenInfo1\": \"Оставшиеся токены = Длина модели - Установка роли - Контекст (История разговора) - Количество ответов - Текущий ввод\",\n\"tokenInfo2\": \"Оставьте установку роли пустой, и система предоставит значение по умолчанию.\",\n\"noSuppertModel\": \"Обновите, эта модель в настоящее время не поддерживается!\",\n\"failOcr\": \"Ошибка распознавания\",\n\"remain\": \"Осталось:\",\n\n  \"totalUsage\": \"Общая сумма подписки\",\n  \"disableGpt4\": \"GPT4 отключен\",\n  \"setTextInfo\": \"Ошибка ключа OpenAI API, нажмите здесь, чтобы повторить попытку\",\n\n  \"attr1\": \"Вложение\",\n  \"ulink\": \"Ссылка на оригинальное изображение\",\n  \"copyFail\": \"Не удалось скопировать\",\n  \"tts\": \"Текст в речь\",\n  \"fail\": \"Произошла ошибка\",\n  \"noSupperChrom\": \"Браузер не поддерживается!\",\n  \"lang\": \"Голос\",\n  \"ttsLoading\": \"Преобразование в речь...\",\n  \"ttsSuccess\": \"Преобразование успешно\",\n  \"micIng\": \"Идет запись, скажите что-нибудь...\",\n  \"mStart\": \"Начать\",\n  \"mPause\": \"Пауза\",\n  \"mGoon\": \"Продолжить\",\n  \"mRecord\": \"Перезаписать\",\n  \"mPlay\": \"Воспроизвести\",\n  \"mCanel\": \"Отмена\",\n  \"mSent\": \"Отправить\",\n  \"findVersion\": \"Обнаружить обновленную версию\",\n  \"yesLastVersion\": \"Уже последняя версия\",\n  \"infoStar\": \"Этот проект с открытым исходным кодом находится на <a class=\\\"text-blue-600 dark:text-blue-500\\\" href=\\\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\\\"_blank\\\">GitHub</a>, бесплатный и основан на лицензии MIT без каких-либо форм оплаты! </p><p>Если вы находите этот проект полезным, пожалуйста, добавьте звезду на GitHub, спасибо!\",\n  \"setBtSaveChat\": \"Сохранить только чат\",\n  \"setBtSaveSys\": \"Сохранить в систему\",\n\n  \"wsrvClose\": \"Закрыть wsrv\",\n  \"wsrvOpen\": \"Открыть wsrv\",\n\n  \"temperature\": \"Случайность\",\n  \"temperatureInfo\": \"При увеличении значения (temperature) ответы становятся более случайными\",\n  \"top_p\": \"Верхняя вероятность выборки\",\n  \"top_pInfo\": \"(top_p) аналогично случайности, но не следует изменять вместе с температурой\",\n  \"presence_penalty\": \"Свежесть темы\",\n  \"presence_penaltyInfo\": \"При увеличении значения (presence_penalty) увеличивается вероятность расширения на новые темы\",\n  \"frequency_penalty\": \"Частотное наказание\",\n  \"frequency_penaltyInfo\": \"При увеличении значения (frequency_penalty) увеличивается вероятность уменьшения повторяющихся слов\"\n  ,\"tts_voice\": \"Голос TTS\",\n  \"typing\": \"Печать\",\n  \"authErro\": \"Ошибка авторизации\",\n  \"authBt\": \"Пожалуйста, введите пароль доступа к авторизации снова\",\n\n  \"micWhisper\": \"Распознавание шепота\",\n  \"micAsr\": \"Мгновенное распознавание\",\n  \"micRec\": \"Начать запись, пожалуйста, говорите! Запись автоматически остановится, если 2 секунды не будет звука.\",\n  \"micRecEnd\": \"Запись завершена\",\n  subtle: 'Высокое разрешение 2x'\n  ,creative: 'Высокое разрешение 2x. Творческий'\n  ,gpt_gx: 'GPT использует g-*',\n\n  \n  \"ideoabout\": \"О Идеограмме\",\n  \"ideoserver\": \"Сервер Идеограммы\",\n  \"ideokeyPlaceholder\": \"API-ключ для Идеограммы (необязательно)\",\n  \"ideopls\": \"Подсказки для описания изображения\",\n  \"nohead\": \"Не включает\",\n\n  klingabout: 'Клинг О',\n  klingserver: 'Адрес API Клинг',\n  klingkeyPlaceholder: 'API-ключ Клинг (необязательно)',\n  klingkey: 'Ключ Клинг',\n  mode: 'Режим',\n  duration: 'Продолжительность',\n  negative_prompt: 'Поместите текст без объектов сюда',\n  std: 'Высокая производительность',\n  pro: 'Высокое качество',\n  needImg: 'Пожалуйста, загрузите эталонное изображение, чтобы это заработало!',\n  seed: 'Число семени 1~2147483647',\n  klingInfo: 'Описание: <li>1. Высокое качество стоит в 3.5 раза дороже</li> <li>2. 10 секунд стоит в 2 раза дороже</li> <li>3. Последний кадр должен иметь эталонное изображение для действия</li>'\n  ,\"camera_type\": \"Объектив\",\n  \"cnull\": \"Умное соответствие\",\n  \"down_back\": \"Опустить и отдалить\",\n  \"forward_up\": \"Продвинуть вперед и поднять\",\n  \"right_turn_forward\": \"Повернуть вправо и продвинуться вперед\",\n  \"left_turn_forward\": \"Повернуть влево и продвинуться вперед\"\n  ,kling:'Kling',\n  rttab: 'Голос',\n  rtinfo: 'Служба голосового общения в реальном времени (realtime)',\n  rtsetting: 'Пожалуйста, настройте сервер. В настоящее время Realtime поддерживает только удаленные службы; для локальных услуг свяжитесь с автором.',\n  rjcloded: 'Соединение разорвано',\n  checkkey: 'Пожалуйста, проверьте правильность API-ключа',\n  rtsuccess: 'Соединение нормально, поддерживаем звонок',\n  rtservererror: 'Ошибка подключения к серверу WebSocket!',\n  rtservererror2: 'Запись не поддерживается, возможно, это связано с устройством!',\n  rtconecting: 'Подключение к серверу'\n\n  ,\"confirmDelete\": \"Вы уверены, что хотите удалить?\",\n  \"pikaabout\": \"О Pika\",\n  \"pikaserver\": \"Адрес API Pika\",\n  \"pikakeyPlaceholder\": \"API-ключ Pika (необязательно)\",\n  \"createFail\": \"Не удалось создать\",\n  \"selecteff\": \"Эффект справки\",\n\n   \"udioabout\": \"О Udio\",\n    \"udiokeyPlaceholder\": \"API-ключ Udio (необязательно)\",\n    \"udioserver\": \"Адрес API Udio\",\n    \"ud_prompt\": \"Подсказка\",\n    \"ud_prompt_pls\": \"Подсказка: Описание, Стиль\",\n    \"ud_ly_write\": \"Пользовательские тексты\",\n    \"ud_ly_auto\": \"Интеллектуальные тексты\",\n    \"ud_ly_null\": \"Чистая музыка\",\n    \"ud_v32\": \"Доступно\",\n    \"ud_v130\": \"Долгое время\",\n    \"ud_info\": \"Примечание: <ul><li>1. Udio-32 имеет короткую продолжительность</li><li>2. Udio-130 стоит вдвое дороже Udio-32</li><li>3. В подсказке можно указать стиль, описание и т. д.</li></ul>\",\n    \"ud_fail\": \"Не удалось сгенерировать эту песню!\",\n    \"ud_doing\": \"Нельзя воспроизводить во время генерации\",\n    \"ud_continuation\": \"Продолжение\",\n    \"ud_precede\": \"Предшествующее\",\n\n    \"upImg2\": \"<span><b>Загрузить изображение</b><br/>Эта модель поддерживает распознавание изображений<br>Примечание: будут дополнительные расходы на изображения<br/>Форматы: jpeg jpg png gif</span><p>Поддерживает перетаскивание</p> <p class=\\\"pt-2\\\"><b>Загрузить MP3 MP4</b> <br>Автоматически вызовет модель whisper-1<br>Форматы: mp3 mp4 mpeg mpga m4a wav webm</p>\",\n    \"rml_info\": \"Примечание:<ul><li>1. Должно быть изображение</li><li>2. Модель имеет только одну gen3a_turbo</li><li>3. Цена за 10 секунд вдвое выше, чем за 5 секунд</li></ul>\",\n    \"rml_heng\": \"Пейзаж\",\n    \"rml_shu\": \"Портрет\",\n    \n    \"pixabout\": \"Связано с Pixverse\",\n    \"pixkeyPlaceholder\": \"API-ключ Pixverse можно оставить пустым\",\n    \"pixserver\": \"Адрес API Pixverse\",\n    \"pixinfo\": \" Описание:<br> <ul> <li>1. Основано на v3.5 360p продолжительность 5s режим Normal</li><li>2. v2.5 это 0.5 раза</li> <li>3. Продолжительность 10s это 2 раза</li> <li>4. 540P это 1.5 раза, 720P это 2 раза, 1080P это 4 раза</li> <li>5. Режим производительности это 2 раза</li> <li>6. Множители умножаются, например, 720P продолжительность 10s это 2*2, что составляет 4 раза, и если добавить производительность, то это будет 8 раз</li></ul>\"\n    ,\n    \"riffabout\": \"О Riffusion\",\n    \"riffkeyPlaceholder\": \"API-ключ Riffusion (необязательно)\",\n    \"riffserver\": \"Адрес API Riffusion\",\n    \"riffinfo\": \"Описание\",\n    \n    \"editImage\": \"Редактирование изображения\",\n    \"editVideo\": \"Изображение в видео\",\n    \"moreset\": \"Дополнительные параметры\"\n    \n  },\n  \"mjset\": {\n    \"server\": \"Сервер\",\n    \"about\": \"О нас\",\n    \"model\": \"Модель\",\n    \"sysname\": \"Искусственный интеллект для рисования\"\n  },\n  \"mjtab\": {\n    \"chat\": \"Чат\",\n    \"draw\": \"Рисование\",\n    \"drawinfo\": \"Рисование с использованием искусственного интеллекта Midjourney\",\n    \"gallery\": \"Галерея\",\n    \"galleryInfo\": \"Моя галерея\"\n  },\n  \"mjchat\": {\n    \"loading\": \"Идет загрузка изображения\",\n    \"openurl\": \"Открыть ссылку напрямую\",\n    \"failReason\": \"Причина сбоя:\",\n    \"reload\": \"Перезагрузить\",\n    \"progress\": \"Прогресс:\",\n    \"wait\": \"Задача отправлена, подождите...\",\n    \"reroll\": \"Перерисовать\",\n    \"wait2\": \"Задача {id} отправлена, подождите\",\n    \"redrawEditing\": \"Редактирование части изображения\",\n    \"face\": \"Сменить лицо\",\n    \"blend\": \"Смешивание изображений\",\n    \"draw\": \"Рисовать\",\n    \"submiting\": \"Отправка...\",\n    \"submit\": \"Отправить\",\n    \"wait3\": \"Пожалуйста, не закрывайте! Создание изображения...\",\n    \"success\": \"Сохранено успешно\",\n    \"successTitle\": \"Успешно\",\n    \"modlePlaceholder\": \"Пользовательские модели (разделять пробелами, необязательно)\",\n    \"myModle\": \"Мои модели\",\n    \"historyCnt\": \"Количество контекста\",\n    \"historyToken\": \"Больше контекста делает память точнее, но расходует больше квоты\",\n    \"historyTCnt\": \"Количество ответов\",\n    \"historyTCntInfo\": \"Больше ответов, возможно, потребуется больше квоты\",\n    \"role\": \"Настройка роли\",\n    \"rolePlaceholder\": \"Дайте своему разговору уникальную роль, необязательно\",\n    \"loading2\": \"Загрузка...\",\n    \"loadmore\": \"Загрузить еще\",\n    \"nofind\": \"Не удалось найти\",\n    \"nofind2\": \"Связанные материалы отсутствуют. Попробуйте следующее\",\n    \"success2\": \"Переключение успешно!\",\n    \"modelChange\": \"Смена модели\",\n    \"search\": \"Поиск\",\n    \"searchPlaceholder\": \"Имя и описание GPTs\",\n    \"attr\": \"Прикрепленные файлы\",\n    \"noproduct\": \"В галерее пока нет ваших работ\",\n    \"myGallery\": \"Моя галерея\",\n    \"yourHead\": \"Ваш аватар\",\n    \"your2Head\": \"Изображение знаменитости\",\n    \"tipInfo\": \"Примечание:<li>1 Изображение должно содержать лицо, иначе не будет изображения</li> <li>2 «Изображение знаменитости» можно сначала создать с помощью mj</li> <li>3 «Изображение знаменитости» может быть аниме</li> <li>4 «Ваш аватар» рекомендуется использовать фотографию лица</li>\",\n    \"placeInput\": \"Пожалуйста, введите подсказку!\",\n    \"more5sb\": \"Максимум 5 изображений для загрузки\",\n    \"exSuccess\": \"Экспорт успешен... Проверьте загрузки\",\n    \"downloadSave\": \"aiрисование.txt\",\n    \"noproducet\": \"Пока нет готовых работ\",\n    \"imgBili\": \"Соотношение изображения\",\n    \"imagEx\": \"Экспорт ссылок изображений\",\n    \"prompt\": \"Подсказка\",\n    \"imgCYes\": \"Содержит макет\",\n    \"imgCUpload\": \"Загрузить свой макет\",\n    \"imgCInfo\": \"Информация о макете:<br/> 1. Макет позволяет использовать свои изображения для создания рисунков MJ<br/> 2. Можно использовать несколько макетов, максимум 5, размер каждого изображения не более 1 Мб<br/>\",\n    \"imgCadd\": \"+Добавить\",\n    \"del\": \"Удалить\",\n    \"img2text\": \"Изображение в текст\",\n    \"img2textinfo\": \"Не знаете, как написать подсказку? Попробуйте изображение в тексте! <br/> Передайте изображение, получите подсказку\",\n    \"traning\": \"Перевод...\",\n    \"imgcreate\": \"Создание изображения\",\n    \"imginfo\": \"Дополнительные параметры: <li>1 --no Игнорировать --no car, чтобы не рисовать машины на изображении</li><li>2 --seed Получить сначала сид --seed 123456</li><li>3 --chaos 10 Смешивание (диапазон: 0-100)</li><li>4 --tile Фрагментирование</li>\",\n    \"tStyle\": \"Стиль\",\n    \"tView\": \"Вид\",\n    \"tShot\": \"Угол обзора\",\n    \"tLight\": \"Освещение\",\n    \"tQuality\": \"Качество изображения\",\n    \"tStyles\": \"Уровень искусства\",\n    \"tVersion\": \"Версия модели\",\n    \"dalleInfo\": \"Инструкции: <li>1 DALL-E - это модель от OpenAI для создания изображений</li><li>2 Изображения от OpenAI имеют ограниченный срок годности, сделайте резервную копию</li><li>3 Внимание: изображения размером 1790 пикселей стоят вдвое дороже</li>\",\n    \"version\": \"Версия\",\n    \"size\": \"Размер\",\n    \"blendInfo\": \"Инструкции: <li>1 Смешивание как минимум двух изображений</li><li>2 Максимальное количество загружаемых изображений - 6</li>\",\n    \"blendStart\": \"Начать смешивание\",\n    \"no2add\": \"Не добавляйте одно и то же изображение повторно\",\n    \"add2more\": \"Добавьте как минимум два изображения\",\n    \"no1m\": \"Размер изображения не должен превышать 1 Мб\",\n    \"imgExt\": \"Формат изображения должен быть jpg, gif, png, jpeg\",\n    \"setSync\": \"Синхронизировать Midjourney и Suno\"\n    ,\"addGPTS\": \"Добавить GPTs\",\n    \"addPlaceholder\": \"Вставьте GID GPTs сюда или прямо вставьте ссылку на GPTs\",\n    \"gidError\": \"Не найден действительный GID, пожалуйста, заполните еще раз\",\n    \"success3\": \"GPTs успешно добавлены!\"\n  },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n   ,suno:{\n    \"description\": \"Режим описания\",\n    \"custom\": \"Профессиональный режим\",\n    \"style\": \"Стиль песни\",\n    \"stylepls\": \"Название песни, например, Поп-музыка\",\n    \"emputy\": \"Нет доступного содержимого\",\n    \"noly\": \"Текст песни недоступен\",\n    \"inputly\": \"Пожалуйста, введите название песни или текст\",\n    \"doingly\": \"В процессе, пожалуйста, подождите.\",\n    \"doingly2\": \"Получение текста...\",\n    \"title\": \"Название песни\",\n    \"titlepls\": \"Название песни, например, Каникулы\",\n    \"desc\": \"Описание песни\",\n    \"descpls\": \"Описание песни, например, Оригинальная поп-музыка о каникулах\",\n    \"noneedly\": \"Текст песни не требуется\",\n    \"rank\": \"Случайный выбор\",\n    \"ly\": \"Текст песни\",\n    \"lypls\": \"Текст песни: с определенным форматом\",\n    \"generate\": \"Создать песню\",\n    \"generately\": \"Сгенерировать текст\",\n    \"nodata\": \"Пожалуйста, сначала создайте песню, чтобы получить список песен\",\n\n    \"menu\": \"Музыка\",\n    \"menuinfo\": \"Создание музыки Suno\",\n    \"server\": \"Конечная точка API Suno\",\n    \"serverabout\": \"Связанные с Suno\",\n    \"setOpenKeyPlaceholder\": \"Связанный ключ для API Suno; необязательно\",\n\n    upMps: 'Загрузить аудио',\n    extend: 'Расширить',\n    extendFrom: 'Расширить от',\n    extendAt: 'Расширение начинается с',\n    fail: 'Неудача',\n    info: 'Инструкции:<br>Длительность загружаемого аудио должна быть от 6 до 60 секунд'\n\n    \n   }\n   ,video:{\n    \"menu\": \"Видео\",\n    \"menuinfo\": \"Создание видео Luma и других\",\n    \"descpls\": \"Описание создания видео\",\n    \"lumaabout\": \"О Luma\",\n    \"lumaserver\": \"Адрес API Luma\",\n    \"setOpenKeyPlaceholder\": \"Ключ API Luma, необязательно\",\n    \"generate\": \"Создать видео\",\n    \"nodata\": \"Нет доступных видео, сначала сгенерируйте!\",\n    \"selectimg\": \"Выберите изображение\",\n    \"clear\": \"Очистить\",\n    \"plsInput\": \"Введите содержимое!\",\n    \"submitSuccess\": \"Успешно отправлено!\",\n    \"process\": \"Создание видео...\",\n    \"repeat\": \"Повторить\",\n    \"lumainfo\": \"Объяснение: <ul><li>1. Видеоролики Pro и relax имеют водяные знаки на ссылках.</li><li>2. Версия Pro без водяных знаков требует получения ссылки на скачивание через кнопку «Скачать».</li><li>3. Ссылки на версии Pro имеют временные ограничения; пожалуйста, немедленно сохраните файл MP4 локально.</li><li>4. Для версий Pro сохраните файл MP4 локально в течение 30 минут после создания, так как канал может быть заблокирован или закрыт.</li><li>5. Если ссылка для загрузки версий Pro недействительна, будет предоставлена ссылка на видео с водяными знаками.</li></ul>\",\n    \"runwayabout\": \"Связанные с Runway\",\n    \"runwayserver\": \"Адрес API Runway\",\n    \"setOpenKeyPlaceholder2\": \"Ключ API Runway, необязательно\",\n    \"endImg\": \"Конечное изображение\",\n    \"runwayinfo\": \"Объяснение: <ul><li>1. У изображений и видеороликов Runway есть срок действия.</li><li>2. Пожалуйста, сохраните файл MP4 локально в течение 30 минут после создания видео.</li></ul>\",\n    \"nosup\": \"Временно не поддерживается\",\n    \"rwgen2\": \"Версия: Gen-2, экономичная\",\n    \"rwgen3\": \"Версия: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\"\n  }\n  ,\n  dance:{\n    menu: \"Танец\",\n    menuinfo: \"Создание танцевальных видео с Viggle и другими.\",\n    character: \"Персонаж\",\n    viggleabout: \"О Viggle\",\n    viggleserver: \"Адрес API Viggle\",\n    setOpenKeyPlaceholder: \"Ключ API Viggle, необязательно\",\n    info: \"Инструкции:<br>1. Изображения персонажей лучше всего делать полноразмерными фотографиями.<br>2. Видео танцевальных шаблонов должны быть личными, а не групповыми.\",\n    model: \"Модель\",\n    bgw: \"Белый фон\",\n    bgg: \"Зеленый фон\",\n    bgmoban: \"Фон шаблона\",\n    bgrole: \"Фон персонажа\",\n    gring: \"Генерация...\",\n    uprolefirst: \"Пожалуйста, сначала загрузите изображение персонажа\",\n    uprolefail: \"Ошибка загрузки\",\n    upvideo: \"+ Загрузить шаблонное танцевальное видео\",\n    usevideo: \"+ Использовать официальный шаблон\",\n    moban: \"Танцевальный шаблон\",\n    moban2: \"Название шаблона\",\n    use: \"Использовать\"\n}\n\n}\n"
  },
  {
    "path": "src/locales/tr-TR.ts",
    "content": "export default {\n    common: {\n        add: 'Ekle',\n        addSuccess: 'Ekleme Başarılı',\n        edit: 'Düzenle',\n        editSuccess: 'Düzenleme Başarılı',\n        delete: 'Sil',\n        deleteSuccess: 'Silme Başarılı',\n        save: 'Kaydet',\n        saveSuccess: 'Kaydetme Başarılı',\n        reset: 'Sıfırla',\n        action: 'Eylem',\n        export: 'Dışa Aktar',\n        exportSuccess: 'Dışa Aktarma Başarılı',\n        import: 'İçe Aktar',\n        importSuccess: 'İçe Aktarma Başarılı',\n        clear: 'Temizle',\n        clearSuccess: 'Temizleme Başarılı',\n        yes: 'Evet',\n        no: 'Hayır',\n        confirm: 'Onayla',\n        download: 'İndir',\n        noData: 'Veri Yok',\n        wrong: 'Bir şeyler yanlış gitti, lütfen daha sonra tekrar deneyin.',\n        success: 'Başarılı',\n        failed: 'Başarısız',\n        verify: 'Doğrula',\n        unauthorizedTips: 'Yetkisiz, lütfen önce doğrulama yapın.',\n        stopResponding: 'Cevap Vermeyi Durdur',\n    },\n    chat: {\n        newChatButton: 'Yeni Sohbet',\n        //placeholder: 'Ask me anything...(Shift + Enter = line break, \"/\" to trigger prompts)',\n        placeholder: 'Bana her şeyi sor, veya ekran görüntüleri yapıştır veya dosyayı sürükleyip bırak. (Shift + Enter = satır atla, \"/\" prompts tetiklemek için)',\n        placeholderMobile: 'Bana her şeyi sor...',\n        copy: 'Kopyala',\n        copied: 'Kopyalandı',\n        copyCode: 'Kodu Kopyala',\n        clearChat: 'Sohbeti Temizle',\n        clearChatConfirm: 'Bu sohbeti temizlemek istediğinizden emin misiniz?',\n        exportImage: 'Resmi Dışa Aktar',\n        exportImageConfirm: 'Bu sohbeti png olarak dışa aktarmak istediğinizden emin misiniz?',\n        exportSuccess: 'Dışa Aktarma Başarılı',\n        exportFailed: 'Dışa Aktarma Başarısız',\n        usingContext: 'Bağlam Modu',\n        turnOnContext: 'Mevcut modda mesaj göndermek, önceki sohbet kayıtlarını taşıyacak.',\n        turnOffContext: 'Mevcut modda mesaj göndermek, önceki sohbet kayıtlarını taşımayacak.',\n        deleteMessage: 'Mesajı Sil',\n        deleteMessageConfirm: 'Bu mesajı silmek istediğinizden emin misiniz?',\n        deleteHistoryConfirm: 'Bu geçmişi silmek istediğinizden emin misiniz?',\n        clearHistoryConfirm: 'Bu sohbet geçmişini silmek istediğinizden emin misiniz?',\n        preview: 'Önizleme',\n        showRawText: 'Ham metin olarak göster',\n    },\n    setting: {\n        setting: 'Ayarlar',\n        general: 'Genel',\n        advanced: 'Gelişmiş',\n        config: 'Yapılandırma',\n        avatarLink: 'Avatar Bağlantısı',\n        name: 'Ad',\n        description: 'Açıklama',\n        backgroundImage: 'Arka Plan',\n        role: 'Rol',\n        temperature: 'Sıcaklık',\n        top_p: 'Top_p',\n        resetUserInfo: 'Kullanıcı Bilgilerini Sıfırla',\n        chatHistory: 'Sohbet Geçmişi',\n        theme: 'Tema',\n        language: 'Dil',\n        webdavSync: 'WebDAV Senkronizasyonu',\n        webdavConfig: 'Yapılandırma',\n        webdavUrl: 'WebDAV Adresi',\n        webdavUsername: 'Kullanıcı Adı',\n        webdavPassword: 'Şifre',\n        webdavConfigError: 'Lütfen tam WebDAV yapılandırmasını doldurun',\n        webdavNotConfigured: 'Lütfen önce WebDAV\\'ı yapılandırın',\n        webdavSyncSuccess: 'Senkronizasyon başarılı',\n        webdavSyncError: 'Senkronizasyon başarısız',\n        webdavTest: 'Bağlantıyı Test Et',\n        webdavUpload: 'Yükle',\n        webdavDownload: 'İndir',\n        api: 'API',\n        reverseProxy: 'Ters Proxy',\n        timeout: 'Zaman Aşımı',\n        socks: 'Socks',\n        httpsProxy: 'HTTPS Proxy',\n        balance: 'API Bakiyesi',\n        monthlyUsage: 'Aylık Kullanım',\n    },\n    store: {\n        siderButton: 'Prompt Mağazası',\n        local: 'Yerel',\n        online: 'Çevrimiçi',\n        title: 'Başlık',\n        description: 'Açıklama',\n        clearStoreConfirm: 'Verileri silmek istediğinize emin misiniz?',\n        importPlaceholder: 'Lütfen buraya JSON verilerini yapıştırın',\n        addRepeatTitleTips: 'Başlık tekrarı, lütfen tekrar girin',\n        addRepeatContentTips: 'İçerik tekrarı: {msg}, lütfen tekrar girin',\n        editRepeatTitleTips: 'Başlık çakışması, lütfen düzeltin',\n        editRepeatContentTips: 'İçerik çakışması {msg}, lütfen tekrar düzenleyin',\n        importError: 'Anahtar değeri uyumsuzluk',\n        importRepeatTitle: 'Başlık tekrarlı olarak atlandı: {msg}',\n        importRepeatContent: 'İçerik tekrarlı olarak atlandı: {msg}',\n        onlineImportWarning: 'Not: Lütfen JSON dosyası kaynağını kontrol edin!',\n        downloadError: 'Lütfen ağ durumunu ve JSON dosyasının geçerliliğini kontrol edin',\n    },\n    \"mj\": {\n        \"setOpen\": \"OpenAI İlişkilendirilmiş\",\n        \"setOpenPlaceholder\": \"http(s):// içermelidir\",\n        \"setOpenUrl\": \"OpenAI API Adresi\",\n        \"setOpenKeyPlaceholder\": \"Parola erişim kısıtlamalarını atlamak için özel OpenAI Anahtarı kullan\",\n        \"setMj\": \"Midjourney İlişkilendirilmiş\",\n        \"setMjUrl\": \"Midjourney API Adresi:\",\n        \"setMjKeyPlaceholder\": \"Parola erişim kısıtlamalarını atlamak için özel Api Secret kullan\",\n        \"setUploader\": \"Yükleme İlişkilendirilmiş\",\n        \"setUploaderUrl\": \"Yükleme Adresi:\",\n        \"setBtSave\": \"Kaydet\",\n        \"setBtBack\": \"Varsayılanı Geri Yükle\",\n\n        \"redraw\": \"Yeniden Çiz\",\n        \"fail1\": \"Lütfen sabırlı olun, yükleniyor.\",\n        \"success1\": \"Resim başarıyla yenilendi!\",\n        \"high_variation\": \"Güçlü Varyasyon\",\n        \"low_variation\": \"Zayıf Varyasyon\",\n        \"p15\": \"Zoom 1.5x\",\n        \"p20\": \"Zoom 2x\",\n        \"p100\": \"Normal\",\n        \"retry\": \"Tekrar Dene\",\n        \"pan_left\": \"Sol\",\n        \"pan_right\": \"Sağ\",\n        \"pan_up\": \"Yukarı\",\n        \"pan_down\": \"Aşağı\",\n        \"up2\": \"HD 2x\",\n        \"up4\": \"HD 4x\" ,\n\n        \"thinking\": \"Düşünüyor...\",\n        \"noReUpload\": \"Yeniden yüklenemiyor\",\n        \"uploading\": \"Yükleniyor...\",\n        \"uploadSuccess\": \"Yükleme başarılı\",\n        \"uploadFail\": \"Yükleme başarısız:\",\n        \"upPdf\": \"<span>Resim veya ek yükleyin<br/>Resimler, PDF'ler, EXCEL ve diğer belgeleri yükleyebilirsiniz</span><p>Sürükle ve bırak desteği</p>\",\n        \"upImg\": \"<span><b>Resim yükleyin</b><br/>Otomatik olarak gpt-4-vision-preview modelini çağırır<br>Not: Ek resim ücretleri uygulanabilir<br/>Formatlar: jpeg, jpg, png, gif</span><p>Sürükle ve bırak desteği</p> <p class=\\\"pt-2\\\"><b>MP3 MP4 Yükle</b> <br>Otomatik olarak whisper-1 modelini çağırır<br>Formatlar: mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n        \"clearAll\": \"Parametreleri Temizle\",\n        \"czoom\": \"Özel\",\n        \"customTitle\": \"Özel zoom\",\n        \"zoominfo\": \"Zoom değerini değiştirin, 1.0 ile 2.0 arasında, varsayılan 1.8 olarak ayarlanmıştır\",\n\n        \"modleSuccess\": \"Model başarıyla yüklendi\",\n        \"setingSuccess\": \"Ayarlar başarılı\",\n\n        \"tokenInfo1\": \"Kalan Jetonlar = Model Uzunluğu - Rol Ayarı - Bağlam (Sohbet Geçmişi) - Yanıt Sayısı - Mevcut Giriş\",\n        \"tokenInfo2\": \"Rol ayarı boş bırakılırsa, sistem varsayılan bir tane sağlar.\",\n        \"noSuppertModel\": \"Yenile, bu model şu anda desteklenmiyor!\",\n        \"failOcr\": \"Tanıma başarısız\",\n        \"remain\": \"Kalan:\",\n\n        \"totalUsage\": \"Toplam abonelik miktarı\",\n        \"disableGpt4\": \"GPT4 devre dışı\",\n        \"setTextInfo\": \"OpenAI API Anahtarı hatası, buraya tıklayarak yeniden deneyin\",\n\n        \"attr1\": \"Attr\",\n        \"ulink\": \"Resim Bağlantısı\",\n        \"copyFail\": \"Kopyalama Başarısız\",\n        \"tts\": \"Metinden Sese\",\n        \"fail\": \"Hata\",\n        \"noSupperChrom\": \"Tarayıcı desteklenmiyor!\",\n        \"lang\": \"Ses\",\n        \"ttsLoading\": \"Sese Dönüştürülüyor...\",\n        \"ttsSuccess\": \"Dönüşüm başarılı\",\n        \"micIng\": \"Kaydediliyor, bir şey söyle...\",\n        \"mStart\": \"Başlat\",\n        \"mPause\": \"Duraklat\",\n        \"mGoon\": \"Devam\",\n        \"mRecord\": \"Yeniden kaydet\",\n        \"mPlay\": \"Oynat\",\n        \"mCanel\": \"İptal\",\n        \"mSent\": \"Gönder\",\n\n        \"findVersion\": \"Güncellenmiş sürümü keşfet\",\n        \"yesLastVersion\": \"Zaten en son sürümde\",\n        \"infoStar\": 'Bu proje <a class=\"text-blue-600 dark:text-blue-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\"_blank\">GitHub</a> üzerinde açık kaynaklı, ücretsiz ve MIT lisansına dayanmaktadır, herhangi bir ödeme şekli yoktur! </p><p>Bu projeyi yararlı bulursanız, lütfen GitHub üzerinde yıldız verin, teşekkür ederim!',\n        \"setBtSaveChat\": \"Sadece sohbeti kaydet\",\n        \"setBtSaveSys\": \"Sisteme kaydet\",\n        \"wsrvClose\": \"wsrv'yi kapat\",\n        \"wsrvOpen\": \"wsrv'yi aç\",\n\n        \"temperature\": \"Rastlantısallık\",\n        \"temperatureInfo\": \"(temperature) değeri arttıkça yanıtlar daha rastlantısal hale gelir\",\n        \"top_p\": \"Üst Olasılık Örnekleme\",\n        \"top_pInfo\": \"(top_p) rastlantısallığa benzer ancak sıcaklık ile birlikte değiştirilmemelidir\",\n        \"presence_penalty\": \"Konu Tazeliği\",\n        \"presence_penaltyInfo\": \"(presence_penalty) değeri arttıkça, yeni konulara genişleme olasılığı daha yüksektir\",\n        \"frequency_penalty\": \"Frekans Cezası\",\n        \"frequency_penaltyInfo\": \"(frequency_penalty) değeri arttıkça, tekrarlanan kelimelerin azaltılma olasılığı daha yüksektir\"\n        ,\"tts_voice\": \"TTS Ses Karakteri\",\n        \"typing\": \"Yazıyor\",\n        \"authErro\": \"Yetkilendirme başarısız\",\n        \"authBt\": \"Lütfen yetkilendirme erişim şifresini yeniden girin\",\n        \"micWhisper\": \"Fısıltı konuşma tanıma\",\n        \"micAsr\": \"Anında tanıma\",\n        \"micRec\": \"Kayıt başlat, lütfen konuşun! 2 saniye boyunca ses yoksa otomatik olarak duracaktır.\",\n        \"micRecEnd\": \"Kayıt sona erdi\",\n\n        subtle: 'Haute définition 2x'\n        ,creative: 'Haute définition 2x. Créatif'\n        ,gpt_gx: 'Les GPT utilisent g-*',\n\n        \"ideoabout\": \"Ideogram Hakkında\",\n        \"ideoserver\": \"Ideogram Sunucusu\",\n        \"ideokeyPlaceholder\": \"Ideogram için API Anahtarı (isteğe bağlı)\",\n        \"ideopls\": \"Görüntü açıklama ipuçları\",\n        \"nohead\": \"Dahil değil\",\n\n        klingabout: 'Kling Hakkında',\n        klingserver: 'Kling API Adresi',\n        klingkeyPlaceholder: 'Kling API Anahtarı (isteğe bağlı)',\n        klingkey: 'Kling Anahtarı',\n        mode: 'Mod',\n        duration: 'Süre',\n        negative_prompt: 'Nesne içermeyen metni buraya yerleştirin',\n        std: 'Yüksek Performans',\n        pro: 'Yüksek Kalite',\n        needImg: 'Etki etmesi için lütfen bir referans resmi yükleyin!',\n        seed: 'Tohum numarası 1~2147483647',\n        klingInfo: 'Açıklama: <li>1. Yüksek kalite fiyatın 3.5 katıdır</li> <li>2. 10 saniye fiyatın 2 katıdır</li> <li>3. Son kare etkili olması için bir referans resmine sahip olmalıdır</li>'\n    \n        ,\"camera_type\": \"Lens\",\n        \"cnull\": \"Akıllı eşleştirme\",\n        \"down_back\": \"Aşağı ve geri git\",\n        \"forward_up\": \"İleri it ve yukarı kaldır\",\n        \"right_turn_forward\": \"Sağa dön ve ileri git\",\n        \"left_turn_forward\": \"Sola dön ve ileri git\"\n        ,kling:'Kling',\n        rttab: 'Ses',\n        rtinfo: 'Gerçek zamanlı sesli görüşme hizmeti (realtime)',\n        rtsetting: 'Lütfen sunucuyu ayarlayın. Şu anda Realtime yalnızca uzaktan hizmetleri desteklemektedir; yerel hizmetler için lütfen yazarla iletişime geçin.',\n        rjcloded: 'Bağlantı kesildi',\n        checkkey: 'API anahtarının doğru olup olmadığını kontrol edin',\n        rtsuccess: 'Bağlantı normal, görüşmeyi sürdürüyor',\n        rtservererror: 'WebSocket sunucu bağlantı hatası!',\n        rtservererror2: 'Kaydetme desteklenmiyor, bu cihaz kaynaklı bir sorun olabilir!',\n        rtconecting: 'Sunucuya bağlanılıyor',\n        \"confirmDelete\": \"Silmek istediğinize emin misiniz?\",\n        \"pikaabout\": \"Pika Hakkında\",\n        \"pikaserver\": \"Pika API Adresi\",\n        \"pikakeyPlaceholder\": \"Pika API Anahtarı (isteğe bağlı)\",\n        \"createFail\": \"Oluşturma başarısız\",\n        \"selecteff\": \"Referans Etkisi\",\n\n        \"udioabout\": \"Udio Hakkında\",\n        \"udiokeyPlaceholder\": \"Udio API Anahtarı (isteğe bağlı)\",\n        \"udioserver\": \"Udio API Adresi\",\n        \"ud_prompt\": \"İpucu\",\n        \"ud_prompt_pls\": \"İpucu: Açıklama, Tarz\",\n        \"ud_ly_write\": \"Özel Şarkı Sözleri\",\n        \"ud_ly_auto\": \"Akıllı Şarkı Sözleri\",\n        \"ud_ly_null\": \"Saf Müzik\",\n        \"ud_v32\": \"Uygun Fiyatlı\",\n        \"ud_v130\": \"Uzun Süreli\",\n        \"ud_info\": \"Not: <ul><li>1. Udio-32 kısa süreye sahiptir</li><li>2. Udio-130, Udio-32'nin iki katı fiyatındadır</li><li>3. İpucu, tarz, açıklama vb. içerebilir</li></ul>\",\n        \"ud_fail\": \"Bu şarkının oluşturulması başarısız oldu!\",\n        \"ud_doing\": \"Oluşturma sırasında çalınamaz\",\n        \"ud_continuation\": \"Devam\",\n        \"ud_precede\": \"Önceki\",\n\n        \"upImg2\": \"<span><b>Görüntü Yükle</b><br/>Bu model görüntü tanımayı desteklemektedir<br>Not: Ekstra görüntü ücretleri olacaktır<br/>Formatlar: jpeg jpg png gif</span><p>Sürükleyip bırakmayı destekler</p> <p class=\\\"pt-2\\\"><b>MP3 MP4 Yükle</b> <br>otomatik olarak whisper-1 modelini çağıracaktır<br>Formatlar: mp3 mp4 mpeg mpga m4a wav webm</p>\",\n        \"rml_info\": \"Not:<ul><li>1. Bir resim içermelidir</li><li>2. Modelin yalnızca bir gen3a_turbo'su vardır</li><li>3. 10 saniyenin fiyatı 5 saniyenin iki katıdır</li></ul>\",\n        \"rml_heng\": \"Yatay\",\n        \"rml_shu\": \"Dikey\",\n        \"pixabout\": \"Pixverse ile ilgili\",\n        \"pixkeyPlaceholder\": \"Pixverse API Anahtarı boş bırakılabilir\",\n        \"pixserver\": \"Pixverse API adresi\",\n        \"pixinfo\": \" Açıklama:<br> <ul> <li>1. v3.5 360p süre 5s Normal moduna dayanmaktadır</li><li>2. v2.5 0.5 katıdır</li> <li>3. Süre 10s 2 katıdır</li> <li>4. 540P 1.5 kat, 720P 2 kat, 1080P 4 katıdır</li> <li>5. Performans modu 2 katıdır</li> <li>6. Katlar çarpılır, örneğin 720P süre 10s 2*2 yani 4 katıdır, eğer performansı eklersek 8 kat olur</li></ul>\",\n\n        \"riffabout\": \"Riffusion Hakkında\",\n        \"riffkeyPlaceholder\": \"Riffusion API Anahtarı (isteğe bağlı)\",\n        \"riffserver\": \"Riffusion API Adresi\",\n        \"riffinfo\": \"Açıklama\",\n        \n        \"editImage\": \"Görüntü Düzenleme\",\n        \"editVideo\": \"Görüntüden Videoya\",\n        \"moreset\": \"Daha Fazla Parametre\",\n    },\n    \"mjset\": {\n        \"server\": \"Sunucu\",\n        \"about\": \"Hakkında\",\n        \"model\": \"Model\",\n        \"sysname\": \"Yapay Zeka Çizimi\"\n    },\n    \"mjtab\": {\n        \"chat\": \"Sohbet\",\n        \"draw\": \"Çizim\",\n        \"drawinfo\": \"Midjourney Motoru ile Yapay Zeka Çizimi\",\n        \"gallery\": \"Galeri\",\n        \"galleryInfo\": \"Benim Galerim\"\n    },\n    \"mjchat\": {\n        \"loading\": \"Resim Yükleniyor\",\n        \"openurl\": \"Bağlantıyı Doğrudan Aç\",\n        \"failReason\": \"Başarısızlık Nedeni:\",\n        \"reload\": \"Yeniden Yükle\",\n        \"progress\": \"İlerleme:\",\n        \"wait\": \"Görev gönderildi, lütfen bekleyin...\",\n        \"reroll\": \"Yeniden Çiz\",\n        \"wait2\": \"Görev {id} gönderildi, lütfen bekleyin\",\n        \"redrawEditing\": \"Kısmi Yeniden Çiz Düzenleme\",\n        \"face\": \"Yüz Değiştir\",\n        \"blend\": \"Resimleri Karıştır\",\n        \"draw\": \"Çizim\",\n        \"submiting\": \"Gönderiliyor\",\n        \"submit\": \"Gönder\",\n        \"wait3\": \"Lütfen kapatmayın! Resim oluşturuluyor...\",\n        \"success\": \"Başarıyla Kaydedildi\",\n        \"successTitle\": \"Başarı\",\n        \"modlePlaceholder\": \"Özel modeller, boşluklarla ayrılmış (isteğe bağlı)\",\n        \"myModle\": \"Özel Modeller\",\n        \"historyCnt\": \"Bağlam Sayısı\",\n        \"historyToken\": \"Daha fazla bağlam, doğruluğu artırır ancak daha fazla kredi tüketir\",\n        \"historyTCnt\": \"Yanıt Sayısı\",\n        \"historyTCntInfo\": \"Daha yüksek yanıt sayısı daha fazla kredi tüketebilir\",\n        \"role\": \"Rol Ayarı\",\n        \"rolePlaceholder\": \"Konuşmanız için özel bir rol ayarlayın (isteğe bağlı)\",\n        \"loading2\": \"Yükleniyor...\",\n        \"loadmore\": \"Daha Fazla Yükle\",\n        \"nofind\": \"Bulunamadı\",\n        \"nofind2\": \"ilgili içerik. Aşağıdakileri deneyebilirsiniz:\",\n        \"success2\": \"Değiştirme Başarılı!\",\n        \"modelChange\": \"Model Değişikliği\",\n        \"search\": \"Ara\",\n        \"searchPlaceholder\": \"GPT isimleri, açıklamalar\",\n        \"attr\": \"Ekler\",\n        \"noproduct\": \"Galari henüz giriş yapmamış\",\n        \"myGallery\": \"Benim Galerim\",\n        \"yourHead\": \"Senin Avatarın\",\n        \"your2Head\": \"Ünlü Resim\",\n        \"tipInfo\": \"Not:<li>1. Resimlerin uygun bir şekilde oluşturulması için yüz içermesi gerekir</li><li>2. 'Ünlü Resim', MJ çizimi kullanılarak oluşturulabilir</li><li>3. 'Ünlü Resim', aynı zamanda anime karakterlerini içerebilir</li><li>4. 'Senin Avatarın', bir pasaport fotoğrafı boyutunda olması önerilir</li>\",\n        \"placeInput\": \"Lütfen prompt'u doldurun!\",\n        \"more5sb\": \"En fazla 5 resim yükleyin\",\n        \"exSuccess\": \"Başarıyla Dışa Aktar... İndirme klasörünü kontrol edin\",\n        \"downloadSave\": \"ai_drawing.txt\",\n        \"noproducet\": \"Şu anda olgun çalışma yok\",\n        \"imgBili\": \"Resim Oranı\",\n        \"imagEx\": \"Sanat Eseri Resim Bağlantılarını Dışa Aktar\",\n        \"prompt\": \"Prompts\",\n        \"imgCYes\": \"Temel Resim İçerir\",\n        \"imgCUpload\": \"Temel Resim Yükle\",\n        \"imgCInfo\": \"Temel Resim Bilgisi:<br/>1. MJ çizimi için kendi resimlerinizi temel olarak kullanın<br/>2. Birden fazla temel resim kullanabilirsiniz, her biri 1M boyutunu geçmemeli\",\n        \"imgCadd\": \"+Ekle\",\n        \"del\": \"Sil\",\n        \"img2text\": \"Resimden Metne\",\n        \"img2textinfo\": \"Hangi prompts kullanacağınızdan emin değil misiniz? Resimden Metne'yi deneyin! Bir resim göndererek prompts alın\",\n        \"traning\": \"Çevriliyor...\",\n        \"imgcreate\": \"Resim Oluştur\",\n        \"imginfo\": \"Diğer parametreler:<li>1 --no: Resimden arabaları hariç tutmak için --no car'ı yoksayın</li><li>2 --seed: --seed 123456 ile önce bir tohum alın</li><li>3 --chaos 10: Karıştırma (aralık: 0-100)</li><li>4 --tile: Parçalama</li>\",\n        \"tStyle\": \"Stil\",\n        \"tView\": \"Görünüm\",\n        \"tShot\": \"Karakter Çekimi\",\n        \"tLight\": \"Aydınlatma\",\n        \"tQuality\": \"Resim Kalitesi\",\n        \"tStyles\": \"Sanatsal Seviye\",\n        \"tVersion\": \"Model Sürümü\",\n        \"dalleInfo\": \"Not:<li>1. DALL-E, OpenAI tarafından sağlanan bir resim oluşturma modelidir</li><li>2. OpenAI resimlerinin bir son kullanma tarihi vardır, bu nedenle yedekleme yapın</li><li>3. Not: 1790px resimlerin fiyatı iki katıdır</li>\",\n        \"version\": \"Sürüm\",\n        \"size\": \"Boyut\",\n        \"blendInfo\": \"Not:<li>1. En az 2 resmi karıştırın</li><li>2. Karıştırmak için en fazla 6 resim kullanılabilir</li>\",\n        \"blendStart\": \"Karışımı Başlat\",\n        \"no2add\": \"Çift resim ekleme\",\n        \"add2more\": \"Lütfen iki veya daha fazla resim ekleyin\",\n        \"no1m\": \"Resim boyutu 1M'yi aşamaz\",\n        \"imgExt\": \"Resimler sadece jpg, gif, png, jpeg formatlarını destekler\",\n        \"setSync\": \"Midjourney ve Suno'yu senkronize et\",\n        \"addGPTS\": \"GPT'ler Ekle\",\n        \"addPlaceholder\": \"GPT'lerin GID'sini buraya yapıştırın veya GPT'lerin bağlantısını doğrudan yapıştırın\",\n        \"gidError\": \"Geçerli GID bulunamadı, lütfen tekrar doldurun\",\n        \"success3\": \"GPT'ler başarıyla eklendi!\"\n    },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n  ,suno:{\n    \"description\": \"Açıklama Modu\",\n    \"custom\": \"Profesyonel Mod\",\n    \"style\": \"Şarkı Tarzı\",\n    \"stylepls\": \"Şarkı Adı, örneğin: Pop Müzik\",\n    \"emputy\": \"Mevcut içerik yok\",\n    \"noly\": \"Söz yok\",\n    \"inputly\": \"Lütfen şarkı adını veya sözleri girin\",\n    \"doingly\": \"Devam ediyor, lütfen bekleyin.\",\n    \"doingly2\": \"Sözler getiriliyor...\",\n    \"title\": \"Şarkı Adı\",\n    \"titlepls\": \"Şarkı Adı, örneğin: Tatil\",\n    \"desc\": \"Şarkı Açıklaması\",\n    \"descpls\": \"Şarkı açıklaması, örneğin: Tatil hakkında orijinal pop müziği\",\n    \"noneedly\": \"Söz gerekli değil\",\n    \"rank\": \"Rastgele seçim\",\n    \"ly\": \"Sözler\",\n    \"lypls\": \"Sözler: belirli bir formatta\",\n    \"generate\": \"Şarkı Oluştur\",\n    \"generately\": \"Sözler Oluştur\",\n    \"nodata\": \"Lütfen önce şarkı oluşturun ki şarkı listesi olsun\",\n    \"menu\": \"Müzik\",\n    \"menuinfo\": \"Suno Müzik Oluşturma\",\n    \"server\": \"Suno API Uç Noktası\",\n    \"serverabout\": \"Suno İlgili\",\n    \"setOpenKeyPlaceholder\": \"Suno API için İlgili Anahtar; isteğe bağlı\",\n\n    upMps: 'Ses yükle',\n    extend: 'Genişlet',\n    extendFrom: 'Şundan genişlet',\n    extendAt: 'Genişletmeyi başlat',\n    fail: 'Başarısız',\n    info: 'Açıklamalar:<br>Yüklenen sesin süresi 6 saniye ile 60 saniye arasında olmalıdır'\n   }\n   ,video:{\n    \"menu\": \"Videolar\",\n    \"menuinfo\": \"Luma ve diğer video oluşturma\",\n    \"descpls\": \"Video oluşturma açıklaması\",\n    \"lumaabout\": \"Luma Hakkında\",\n    \"lumaserver\": \"Luma API adresi\",\n    \"setOpenKeyPlaceholder\": \"Luma API anahtarı, isteğe bağlı\",\n    \"generate\": \"Video Oluştur\",\n    \"nodata\": \"Mevcut video yok, lütfen önce oluşturun!\",\n    \"selectimg\": \"Resim Seç\",\n    \"clear\": \"Temizle\",\n    \"plsInput\": \"Lütfen içerik girin!\",\n    \"submitSuccess\": \"Başarıyla gönderildi!\",\n    \"process\": \"Video oluşturuluyor...\",\n    \"repeat\": \"Yeniden dene\",\n    \"lumainfo\": \"Açıklama: <ul><li>1. Pro ve rahat demo videoları su işareti olan bağlantılara sahiptir.</li><li>2. Pro su işaretsiz sürüm, 'İndir' düğmesi aracılığıyla indirme bağlantısını almayı gerektirir.</li><li>3. Pro sürümler için bağlantılar zaman sınırlıdır; lütfen MP4 dosyasını yerel olarak zamanında kaydedin.</li><li>4. Pro sürümler için, 30 dakika içinde MP4 dosyasını yerel olarak kaydedin, çünkü kanal engellenebilir veya durdurulabilir.</li><li>5. Pro sürümleri için indirme bağlantısı geçersizse, su işareti olan video bağlantısı sağlanacaktır.</li></ul>\",\n    \"runwayabout\": \"Runway ile İlgili\",\n    \"runwayserver\": \"Runway API Adresi\",\n    \"setOpenKeyPlaceholder2\": \"Runway API anahtarı, isteğe bağlı\",\n    \"endImg\": \"Son kare\",\n    \"runwayinfo\": \"Açıklama: <ul><li>1. Runway görüntüleri ve videoları geçerlilik süresine sahiptir.</li><li>2. Lütfen video oluşturduktan sonra 30 dakika içinde MP4 dosyasını yerel olarak kaydedin.</li></ul>\",\n    \"nosup\": \"Geçici olarak desteklenmiyor\",\n    \"rwgen2\": \"Sürüm: Gen-2, maliyet etkin\",\n    \"rwgen3\": \"Sürüm: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\"\n    }\n    ,\n    dance:{\n        menu: \"Dans\",\n        menuinfo: \"Viggle ve diğerleri ile dans videoları oluşturun.\",\n        character: \"Karakter\",\n        viggleabout: \"Viggle Hakkında\",\n        viggleserver: \"Viggle API Endpoint\",\n        setOpenKeyPlaceholder: \"Viggle API anahtarı, isteğe bağlı\",\n        info: \"Yönergeler:<br>1. Karakter görüntüleri tercihen tam boy fotoğraflar olmalıdır.<br>2. Dans şablonu videoları kişisel videolar olmalı, grup dansları değil.\",\n        model: \"Model\",\n        bgw: \"Beyaz Arka Plan\",\n        bgg: \"Yeşil Arka Plan\",\n        bgmoban: \"Şablon Arka Planı\",\n        bgrole: \"Karakter Arka Planı\",\n        gring: \"Oluşturuluyor...\",\n        uprolefirst: \"Lütfen önce karakter resmi yükleyin\",\n        uprolefail: \"Yükleme başarısız oldu\",\n        upvideo: \"+ Şablon Dans Videosu Yükle\",\n        usevideo: \"+ Resmi Şablonu Kullan\",\n        moban: \"Dans Şablonu\",\n        moban2: \"Şablon Adı\",\n        use: \"Kullan\"\n    }\n  }\n"
  },
  {
    "path": "src/locales/vi-VN.ts",
    "content": "export default {\n  common: {\n    add: 'Thêm',\n    addSuccess: 'Thêm thành công',\n    edit: 'Sửa',\n    editSuccess: 'Sửa thành công',\n    delete: 'Xóa',\n    deleteSuccess: 'Xóa thành công',\n    save: 'Lưu',\n    saveSuccess: 'Lưu thành công',\n    reset: 'Đặt lại',\n    action: 'Hành động',\n    export: 'Xuất',\n    exportSuccess: 'Xuất thành công',\n    import: 'Nhập',\n    importSuccess: 'Nhập thành công',\n    clear: 'Dọn dẹp',\n    clearSuccess: 'Dọn dẹp thành công',\n    yes: 'Có',\n    no: 'Không',\n    confirm: 'Xác nhận',\n    download: 'Tải xuống',\n    noData: 'Không có dữ liệu',\n    wrong: 'Đã xảy ra lỗi, vui lòng thử lại sau.',\n    success: 'Thành công',\n    failed: 'Thất bại',\n    verify: 'Xác minh',\n    unauthorizedTips: 'Không được ủy quyền, vui lòng xác minh trước.',\n  },\n  chat: {\n    newChatButton: 'Tạo hội thoại',\n    placeholder: 'Hỏi tôi bất cứ điều gì...(Shift + Enter = ngắt dòng, \"/\" to trigger prompts)',\n    placeholderMobile: 'Hỏi tôi bất cứ điều gì...',\n    copy: 'Sao chép',\n    copied: 'Đã sao chép',\n    copyCode: 'Sao chép Code',\n    clearChat: 'Clear Chat',\n    clearChatConfirm: 'Bạn có chắc chắn xóa cuộc trò chuyện này?',\n    exportImage: 'Xuất hình ảnh',\n    exportImageConfirm: 'Bạn có chắc chắn xuất cuộc trò chuyện này sang png không?',\n    exportSuccess: 'Xuất thành công',\n    exportFailed: 'Xuất thất bại',\n    usingContext: 'Context Mode',\n    turnOnContext: 'Ở chế độ hiện tại, việc gửi tin nhắn sẽ mang theo các bản ghi trò chuyện trước đó.',\n    turnOffContext: 'Ở chế độ hiện tại, việc gửi tin nhắn sẽ không mang theo các bản ghi trò chuyện trước đó.',\n    deleteMessage: 'Xóa tin nhắn',\n    deleteMessageConfirm: 'Bạn có chắc chắn xóa tin nhắn này?',\n    deleteHistoryConfirm: 'Bạn có chắc chắn để xóa lịch sử này?',\n    clearHistoryConfirm: 'Bạn có chắc chắn để xóa lịch sử trò chuyện?',\n    preview: 'Xem trước',\n    showRawText: 'Hiển thị dưới dạng văn bản thô',\n  },\n  setting: {\n    setting: 'Cài đặt',\n    general: 'Chung',\n    advanced: 'Nâng cao',\n    config: 'Cấu hình',\n    avatarLink: 'Avatar Link',\n    name: 'Tên',\n    description: 'Miêu tả',\n    backgroundImage: 'Ảnh nền',\n    role: 'Vai trò',\n    temperature: 'Nhiệt độ',\n    top_p: 'Top_p',\n    resetUserInfo: 'Đặt lại thông tin người dùng',\n    chatHistory: 'Lịch sử trò chuyện',\n    theme: 'Giao diện',\n    language: 'Ngôn ngữ',\n    webdavSync: 'Đồng bộ WebDAV',\n    webdavConfig: 'Cấu hình',\n    webdavUrl: 'Địa chỉ WebDAV',\n    webdavUsername: 'Tên người dùng',\n    webdavPassword: 'Mật khẩu',\n    webdavConfigError: 'Vui lòng điền đầy đủ cấu hình WebDAV',\n    webdavNotConfigured: 'Vui lòng cấu hình WebDAV trước',\n    webdavSyncSuccess: 'Đồng bộ thành công',\n    webdavSyncError: 'Đồng bộ thất bại',\n    webdavTest: 'Kiểm tra kết nối',\n    webdavUpload: 'Tải lên',\n    webdavDownload: 'Tải xuống',\n    api: 'API',\n    reverseProxy: 'Reverse Proxy',\n    timeout: 'Timeout',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS Proxy',\n    balance: 'API Balance',\n    monthlyUsage: 'Sử dụng hàng tháng',\n  },\n  store: {\n    siderButton: 'Prompt Store',\n    local: 'Local',\n    online: 'Online',\n    title: 'Tiêu đề',\n    description: 'Miêu tả',\n    clearStoreConfirm: 'Cho dù để xóa dữ liệu?',\n    importPlaceholder: 'Vui lòng dán dữ liệu JSON vào đây',\n    addRepeatTitleTips: 'Tiêu đề trùng lặp, vui lòng nhập lại',\n    addRepeatContentTips: 'Nội dung trùng lặp: {msg}, vui lòng nhập lại',\n    editRepeatTitleTips: 'Xung đột tiêu đề, vui lòng sửa lại',\n    editRepeatContentTips: 'Xung đột nội dung {msg} , vui lòng sửa đổi lại',\n    importError: 'Key value mismatch',\n    importRepeatTitle: 'Tiêu đề liên tục bị bỏ qua: {msg}',\n    importRepeatContent: 'Nội dung liên tục bị bỏ qua: {msg}',\n    onlineImportWarning: 'Lưu ý: Vui lòng kiểm tra nguồn tệp JSON!',\n    downloadError: 'Vui lòng kiểm tra trạng thái mạng và tính hợp lệ của tệp JSON',\n  },\n  \"mj\": {\n    \"setOpen\": \"OpenAI liên quan\",\n    \"setOpenPlaceholder\": \"Phải chứa http(s)://\",\n    \"setOpenUrl\": \"Địa chỉ giao diện OpenAI\",\n    \"setOpenKeyPlaceholder\": \"Sử dụng khóa OpenAI tùy chỉnh để bỏ qua hạn chế mật khẩu\",\n    \"setMj\": \"Midjourney liên quan\",\n    \"setMjUrl\": \"Địa chỉ giao diện Midjourney:\",\n    \"setMjKeyPlaceholder\": \"Sử dụng Khóa Api Secret tùy chỉnh để bỏ qua hạn chế mật khẩu\",\n    \"setUploader\": \"Tải lên liên quan\",\n    \"setUploaderUrl\": \"Địa chỉ tải lên:\",\n    \"setBtSave\": \"Lưu\",\n    \"setBtBack\": \"Khôi phục mặc định\",\n\n    \"redraw\": \"Vẽ Lại Phần\",\n    \"fail1\": \"Anh/chị đừng vội, đang tải đó.\",\n    \"success1\": \"Ảnh đã làm mới thành công!\",\n    \"high_variation\": \"Biến Động Mạnh\",\n    \"low_variation\": \"Biến Động Nhẹ\",\n    \"p15\": \"Thu Phóng 1.5 lần\",\n    \"p20\": \"Thu Phóng 2 lần\",\n    \"p100\": \"Bình thường\",\n    \"retry\": \"Thử Lại Phân Tích\",\n    \"pan_left\": \"Phân Tích Lại Bên Trái\",\n    \"pan_right\": \"Phân Tích Lại Bên Phải\",\n    \"pan_up\": \"Phân Tích Lại Lên\",\n    \"pan_down\": \"Phân Tích Lại Xuống\",\n    \"up2\": \"Độ Phân Giải Cao 2 lần\",\n    \"up4\": \"Độ Phân Giải Cao 4 lần\",\n\n    \"thinking\": \"Đang suy nghĩ...\",\n    \"noReUpload\": \"Không thể tải lên lại\",\n    \"uploading\": \"Đang tải lên...\",\n    \"uploadSuccess\": \"Tải lên thành công\",\n    \"uploadFail\": \"Tải lên thất bại:\",\n    \"upPdf\": \"<span>Tải lên hình ảnh hoặc tệp đính kèm<br/>Bạn có thể tải lên hình ảnh, PDF, EXCEL và các tài liệu khác</span><p>Hỗ trợ kéo và thả</p>\",\n    \"upImg\": \"<span><b>Tải lên hình ảnh</b><br/>Sẽ tự động gọi mô hình gpt-4-vision-preview<br>Chú ý: Có thể áp dụng phí ảnh bổ sung<br/>Định dạng: jpeg, jpg, png, gif</span><p>Hỗ trợ kéo và thả</p> <p class=\\\"pt-2\\\"><b>Tải lên MP3 MP4</b> <br>Sẽ tự động gọi mô hình whisper-1<br>Định dạng: mp3, mp4, mpeg, mpga, m4a, wav, webm</p>\",\n    \"clearAll\": \"Xóa tất cả các tham số\",\n    \"czoom\": \"Tùy chỉnh\",\n    \"customTitle\": \"Tùy chỉnh zoom\",\n    \"zoominfo\": \"Sửa giá trị zoom, khoảng từ 1.0 đến 2.0, mặc định được đặt là 1.8\",\n\n    \"modleSuccess\": \"Tải mô hình thành công\",\n    \"setingSuccess\": \"Thiết lập thành công\",\n\n    \"tokenInfo1\": \"Còn lại Tokens = Độ dài mô hình - Thiết lập vai trò - Bối cảnh (Lịch sử cuộc trò chuyện) - Số phản hồi - Đầu vào hiện tại\",\n    \"tokenInfo2\": \"Để trống thiết lập vai trò và hệ thống sẽ cung cấp một giá trị mặc định.\",\n    \"noSuppertModel\": \"Làm mới, hiện tại mô hình này không được hỗ trợ!\",\n    \"failOcr\": \"Nhận dạng thất bại\",\n    \"remain\": \"Còn:\",\n\n    \"totalUsage\": \"Tổng số tiền đăng ký\",\n    \"disableGpt4\": \"GPT4 đã tắt\",\n    \"setTextInfo\": \"Lỗi Khóa API OpenAI, nhấp vào đây để thử lại\" ,\n\n    \"attr1\": \"Đính\",\n    \"ulink\": \"Liên kết Ảnh gốc\",\n    \"copyFail\": \"Sao chép thất bại\",\n    \"tts\": \"Văn bản thành Tiếng nói (TTS)\",\n    \"fail\": \"Đã xảy ra lỗi\",\n    \"noSupperChrom\": \"Trình duyệt không được hỗ trợ!\",\n    \"lang\": \"Âm thanh\",\n    \"ttsLoading\": \"Đang chuyển đổi thành tiếng nói...\",\n    \"ttsSuccess\": \"Chuyển đổi thành công\",\n    \"micIng\": \"Đang ghi âm, nói điều gì đó...\",\n    \"mStart\": \"Bắt đầu\",\n    \"mPause\": \"Tạm dừng\",\n    \"mGoon\": \"Tiếp tục\",\n    \"mRecord\": \"Ghi lại\",\n    \"mPlay\": \"Phát\",\n    \"mCanel\": \"Hủy\",\n    \"mSent\": \"Gửi\",\n    \"findVersion\": \"Phát hiện phiên bản cập nhật\",\n    \"yesLastVersion\": \"Đã là phiên bản mới nhất\",\n    \"infoStar\": \"Dự án này được mở nguồn tại <a class=\\\"text-blue-600 dark:text-blue-500\\\" href=\\\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\\\"_blank\\\">GitHub</a>, miễn phí và dựa trên giấy phép MIT mà không có bất kỳ hình thức thanh toán nào! </p><p>Nếu bạn thấy dự án này hữu ích, hãy cho nó một sao trên GitHub, cảm ơn bạn!\",\n    \"setBtSaveChat\": \"Chỉ lưu trò chuyện\",\n    \"setBtSaveSys\": \"Lưu vào hệ thống\",\n\n    \"wsrvClose\": \"Đóng wsrv\",\n    \"wsrvOpen\": \"Mở wsrv\",\n\n    \"temperature\": \"Ngẫu nhiên\",\n    \"temperatureInfo\": \"Khi giá trị (temperature) tăng, các phản hồi trở nên ngẫu nhiên hơn\",\n    \"top_p\": \"Lấy Mẫu Xác Suất Cao Nhất\",\n    \"top_pInfo\": \"(top_p) tương tự như ngẫu nhiên nhưng không nên thay đổi cùng với nhiệt độ\",\n    \"presence_penalty\": \"Sự Tươi Mới của Chủ đề\",\n    \"presence_penaltyInfo\": \"Khi giá trị (presence_penalty) tăng, có khả năng mở rộng đến các chủ đề mới cao hơn\",\n    \"frequency_penalty\": \"Hình Phạt Tần Số\",\n    \"frequency_penaltyInfo\": \"Khi giá trị (frequency_penalty) tăng, có khả năng giảm sự lặp lại của các từ nhiều hơn\"\n   ,\"tts_voice\": \"Nhân vật giọng TTS\",\n    \"typing\": \"Đang nhập\",\n    \"authErro\": \"Xác thực không thành công\",\n    \"authBt\": \"Vui lòng nhập lại mật khẩu truy cập xác thực\",\n\n    \"micWhisper\": \"Nhận diện giọng nói thì thầm\",\n    \"micAsr\": \"Nhận diện ngay lập tức\",\n    \"micRec\": \"Bắt đầu ghi âm, vui lòng nói chuyện! Sẽ tự động dừng nếu không có âm thanh trong vòng 2 giây.\",\n    \"micRecEnd\": \"Ghi âm đã kết thúc\",\n\n    subtle: 'Cao độ phân giải cao gấp 2 lần'\n    ,creative: 'Cao độ phân giải cao gấp 2 lần. Sáng tạo'\n    ,gpt_gx: 'GPTs sử dụng g-*',\n\n     \"ideoabout\": \"Về Ideogram\",\n    \"ideoserver\": \"Máy chủ Ideogram\",\n    \"ideokeyPlaceholder\": \"Khóa API cho Ideogram (tùy chọn)\",\n    \"ideopls\": \"Gợi ý mô tả hình ảnh\",\n    \"nohead\": \"Không bao gồm\",\n\n    klingabout: 'Liên quan đến Kling',\n    klingserver: 'Địa chỉ API Kling',\n    klingkeyPlaceholder: 'API Key Kling (tùy chọn)',\n    klingkey: 'Khóa Kling',\n    mode: 'Chế độ',\n    duration: 'Thời gian',\n    negative_prompt: 'Đặt văn bản không có đối tượng ở đây',\n    std: 'Hiệu suất cao',\n    pro: 'Chất lượng cao',\n    needImg: 'Vui lòng tải lên hình ảnh tham khảo để nó có hiệu lực!',\n    seed: 'Số hạt 1~2147483647',\n    klingInfo: 'Mô tả: <li>1. Chất lượng cao gấp 3,5 lần giá</li> <li>2. 10 giây gấp 2 lần giá</li> <li>3. Khung cuối cùng phải có hình ảnh tham khảo để có hiệu lực</li>'\n\n    ,\"camera_type\": \"Ống kính\",\n    \"cnull\": \"Ghép thông minh\",\n    \"down_back\": \"Di chuyển xuống và thu nhỏ\",\n    \"forward_up\": \"Đẩy tới và di chuyển lên\",\n    \"right_turn_forward\": \"Quay phải và đẩy tới\",\n    \"left_turn_forward\": \"Quay trái và đẩy tới\"\n    ,kling:'Kling'\n    ,rttab: 'Giọng nói',\n    rtinfo: 'Dịch vụ hội thoại giọng nói thời gian thực (realtime)',\n    rtsetting: 'Vui lòng thiết lập máy chủ. Hiện tại, Realtime chỉ hỗ trợ dịch vụ từ xa; nếu cần dịch vụ cục bộ, vui lòng liên hệ với tác giả.',\n    rjcloded: 'Kết nối đã bị ngắt',\n    checkkey: 'Vui lòng kiểm tra xem API key có chính xác không',\n    rtsuccess: 'Kết nối bình thường, duy trì cuộc gọi',\n    rtservererror: 'Lỗi kết nối máy chủ WebSocket!',\n    rtservererror2: 'Không hỗ trợ ghi âm, có thể do thiết bị!',\n    rtconecting: 'Đang kết nối đến máy chủ',\n\n    \"confirmDelete\": \"Bạn có chắc chắn muốn xóa không?\",\n    \"pikaabout\": \"Về Pika\",\n    \"pikaserver\": \"Địa chỉ API Pika\",\n    \"pikakeyPlaceholder\": \"Khóa API Pika (tùy chọn)\",\n    \"createFail\": \"Tạo không thành công\",\n    \"selecteff\": \"Hiệu ứng tham khảo\",\n\n    \"udioabout\": \"Về Udio\",\n    \"udiokeyPlaceholder\": \"API Key Udio (tùy chọn)\",\n    \"udioserver\": \"Địa chỉ API Udio\",\n    \"ud_prompt\": \"Gợi ý\",\n    \"ud_prompt_pls\": \"Gợi ý: Mô tả, Phong cách\",\n    \"ud_ly_write\": \"Lời bài hát tùy chỉnh\",\n    \"ud_ly_auto\": \"Lời bài hát thông minh\",\n    \"ud_ly_null\": \"Nhạc không lời\",\n    \"ud_v32\": \"Giá cả phải chăng\",\n    \"ud_v130\": \"Thời gian dài\",\n    \"ud_info\": \"Lưu ý: <ul><li>1. Udio-32 có thời gian ngắn</li><li>2. Udio-130 có giá gấp đôi Udio-32</li><li>3. Gợi ý có thể bao gồm phong cách, mô tả, v.v.</li></ul>\",\n    \"ud_fail\": \"Không thể tạo bài hát này!\",\n    \"ud_doing\": \"Không thể phát trong khi đang tạo\",\n    \"ud_continuation\": \"Tiếp tục\",\n    \"ud_precede\": \"Trước\",\n    \"upImg2\": \"<span><b>Tải lên hình ảnh</b><br/>Mô hình này hỗ trợ nhận diện hình ảnh<br>Chú ý: sẽ có phí hình ảnh bổ sung<br/>Định dạng: jpeg jpg png gif</span><p>Hỗ trợ kéo và thả</p> <p class=\\\"pt-2\\\"><b>Tải lên MP3 MP4</b> <br>Sẽ tự động gọi mô hình whisper-1<br>Định dạng bao gồm: mp3 mp4 mpeg mpga m4a wav webm</p>\",\n    \"rml_info\": \"Chú ý:<ul><li>1. Phải có hình ảnh</li><li>2. Mô hình chỉ có một gen3a_turbo</li><li>3. Giá cho 10 giây gấp đôi giá cho 5 giây</li></ul>\",\n    \"rml_heng\": \"Chế độ ngang\",\n    \"rml_shu\": \"Chế độ dọc\",\n    \n    \"pixabout\": \"Liên quan đến Pixverse\",\n    \"pixkeyPlaceholder\": \"Khóa API Pixverse có thể để trống\",\n    \"pixserver\": \"Địa chỉ API Pixverse\",\n    \"pixinfo\": \" Mô tả:<br> <ul> <li>1. Dựa trên v3.5 360p thời gian 5s chế độ Normal</li><li>2. v2.5 là 0.5 lần</li> <li>3. Thời gian 10s là 2 lần</li> <li>4. 540P là 1.5 lần, 720P là 2 lần, 1080P là 4 lần</li> <li>5. Chế độ hiệu suất là 2 lần</li> <li>6. Các bội số được nhân với nhau, ví dụ 720P thời gian 10s là 2*2 tức là 4 lần, nếu thêm hiệu suất thì sẽ là 8 lần</li></ul>\",\n\n    \"riffabout\": \"Về Riffusion\",\n    \"riffkeyPlaceholder\": \"Khóa API Riffusion (không bắt buộc)\",\n    \"riffserver\": \"Địa chỉ API Riffusion\",\n    \"riffinfo\": \"Mô tả\",\n\n    \"editImage\": \"Chỉnh sửa hình ảnh\",\n    \"editVideo\": \"Hình ảnh thành video\",\n    \"moreset\": \"Thêm tham số\",\n\n  },\n  \"mjset\": {\n    \"server\": \"Máy chủ\",\n    \"about\": \"Về\",\n    \"model\": \"Mô hình\",\n    \"sysname\": \"Trí tuệ nhân tạo vẽ\"\n  },\n  \"mjtab\": {\n    \"chat\": \"nói\",\n    \"draw\": \"Vẽ\",\n    \"drawinfo\": \"Vẽ trí tuệ nhân tạo Midjourney\",\n    \"gallery\": \"sách\",\n    \"galleryInfo\": \"Phòng trưng bày của tôi\"\n  },\n  \"mjchat\": {\n    \"loading\": \"Đang tải hình ảnh\",\n    \"openurl\": \"Mở liên kết trực tiếp\",\n    \"failReason\": \"Lý do thất bại:\",\n    \"reload\": \"Tải lại\",\n    \"progress\": \"Tiến triển:\",\n    \"wait\": \"Nhiệm vụ đã được gửi, vui lòng đợi...\",\n    \"reroll\": \"Vẽ lại\",\n    \"wait2\": \"Nhiệm vụ {id} đã được gửi, vui lòng đợi\",\n    \"redrawEditing\": \"Chỉnh sửa vẽ lại\",\n    \"face\": \"Thay đổi khuôn mặt\",\n    \"blend\": \"Trộn ảnh\",\n    \"draw\": \"Vẽ\",\n    \"submiting\": \"Đang gửi\",\n    \"submit\": \"Gửi\",\n    \"wait3\": \"Vui lòng không tắt! Đang tạo ảnh...\",\n    \"success\": \"Lưu thành công\",\n    \"successTitle\": \"Thành công\",\n    \"modlePlaceholder\": \"Mô hình tùy chỉnh, cách nhau bằng khoảng trắng, không bắt buộc\",\n    \"myModle\": \"Mô hình tùy chỉnh của tôi\",\n    \"historyCnt\": \"Số ngữ cảnh\",\n    \"historyToken\": \"Số ngữ cảnh nhiều hơn sẽ làm cho bộ nhớ chính xác hơn, nhưng sẽ tiêu tốn nhiều chi phí hơn\",\n    \"historyTCnt\": \"Số câu trả lời\",\n    \"historyTCntInfo\": \"Số câu trả lời càng nhiều, khả năng tiêu tốn chi phí càng cao\",\n    \"role\": \"Đặt vai trò\",\n    \"rolePlaceholder\": \"Đặt một vai trò riêng cho cuộc trò chuyện của bạn, không bắt buộc\",\n    \"loading2\": \"Đang tải...\",\n    \"loadmore\": \"Tải thêm\",\n    \"nofind\": \"Không thể tìm thấy\",\n    \"nofind2\": \"Nội dung liên quan không tìm thấy, bạn có thể thử những nội dung sau đây\",\n    \"success2\": \"Chuyển đổi thành công!\",\n    \"modelChange\": \"Thay đổi mô hình\",\n    \"search\": \"Tìm kiếm\",\n    \"searchPlaceholder\": \"Tên GPTs, giới thiệu\",\n    \"attr\": \"Phụ kiện\",\n    \"noproduct\": \"Phòng trưng bày chưa có sản phẩm của bạn\",\n    \"myGallery\": \"Phòng trưng bày của tôi\",\n    \"yourHead\": \"Ảnh đại diện của bạn\",\n    \"your2Head\": \"Ảnh ngôi sao\",\n    \"tipInfo\": \"Chú ý: <li>1 Hình ảnh phải chứa khuôn mặt, nếu không sẽ không xuất hiện ảnh</li> <li>2 'Ảnh ngôi sao' có thể sử dụng MJ để vẽ trước</li> <li>3 'Ảnh ngôi sao' có thể là hình ảnh hoạt hình</li> <li>4 'Ảnh đại diện của bạn' nên sử dụng ảnh cá nhân 1 inch</li>\",\n    \"placeInput\": \"Vui lòng điền từ gợi ý!\",\n    \"more5sb\": \"Tối đa tải lên 5 ảnh\",\n    \"exSuccess\": \"Xuất thành công... Vui lòng kiểm tra thanh tải về\",\n    \"downloadSave\": \"ai vẽ.txt\",\n    \"noproducet\": \"Hiện chưa có sản phẩm chín thành\",\n    \"imgBili\": \"Tỉ lệ ảnh\",\n    \"imagEx\": \"Xuất liên kết hình ảnh tác phẩm\",\n    \"prompt\": \"Từ gợi ý\",\n    \"imgCYes\": \"Có ảnh nền\",\n    \"imgCUpload\": \"Tự tải ảnh nền\",\n    \"imgCInfo\": \"Thông tin ảnh nền: <br/> 1. Ảnh nền có thể sử dụng ảnh cá nhân của bạn làm cơ sở để MJ vẽ hình <br/> 2. Có thể sử dụng nhiều ảnh nền, tối đa 5 ảnh, mỗi ảnh không quá 1M\",\n    \"imgCadd\": \"+ Thêm\",\n    \"del\": \"Xóa\",\n    \"img2text\": \"Hình thành văn\",\n    \"img2textinfo\": \"Không biết cách đặt từ gợi ý? Hãy thử Hình thành văn! <br/> Gửi hình ảnh, nhận từ gợi ý\",\n    \"traning\": \"Đang dịch...\",\n    \"imgcreate\": \"Tạo ảnh\",\n    \"imginfo\": \"Tham số khác: <li>1 --no Bỏ qua --no, không xuất hiện xe trong hình ảnh </li><li>2 --seed Có thể lấy hạt giống trước --seed 123456 </li> <li>3 --chaos 10 Hỗn loạn (phạm vi: 0-100)</li> <li>4 --tile Fragmentation </li>\",\n    \"tStyle\": \"Phong cách\",\n    \"tView\": \"Góc nhìn\",\n    \"tShot\": \"Góc chụp người\",\n    \"tLight\": \"Ánh sáng\",\n    \"tQuality\": \"Chất lượng hình ảnh\",\n    \"tStyles\": \"Mức độ nghệ thuật\",\n    \"tVersion\": \"Phiên bản mô hình\",\n    \"dalleInfo\": \"Chú ý: <li>1 Dall-e là mô hình vẽ hình do OpenAI cung cấp</li>  <li>2 Hình ảnh của OpenAI có thời gian sử dụng, hãy sao lưu đúng cách</li>   <li>3 Lưu ý: Giá của hình ảnh 1790px là gấp đôi</li>\",\n    \"version\": \"Phiên bản\",\n    \"size\": \"Kích thước\",\n    \"blendInfo\": \"Chú ý: <li>1 Kết hợp ít nhất 2 hình ảnh</li> <li>2 Tối đa có thể tải lên 6 hình ảnh</li>\",\n    \"blendStart\": \"Bắt đầu kết hợp\",\n    \"no2add\": \"Vui lòng không thêm hình ảnh giống nhau\",\n    \"add2more\": \"Vui lòng thêm ít nhất hai hình ảnh\",\n    \"no1m\": \"Kích thước hình ảnh không quá 1M\",\n    \"imgExt\": \"Chỉ hỗ trợ định dạng jpg, gif, png, jpeg cho hình ảnh\",\n    \"setSync\": \"Đồng bộ hóa Midjourney và Suno\",\n    \"addGPTS\": \"Thêm GPTs\",\n    \"addPlaceholder\": \"Dán GID của GPTs vào đây hoặc dán trực tiếp liên kết của GPTs\",\n    \"gidError\": \"Không tìm thấy GID hợp lệ, vui lòng điền lại\",\n    \"success3\": \"Thêm GPTs thành công!\"\n  },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"General\",\n\t\t\tclear: \"Clear\",\n\t\t\thd: \"HD\",\n\t\t\tultraHd: \"Ultra HD\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"Cyberpunk\",\n\t\t\tstar: \"Star\",\n\t\t\tanime: \"Anime\",\n\t\t\tjapaneseComicsManga: \"Japanese Comics/Manga\",\n\t\t\tinkWashPaintingStyle: \"Ink Wash Painting Style\",\n\t\t\toriginal: \"Original\",\n\t\t\tlandscape: \"Landscape\",\n\t\t\tillustration: \"Illustration\",\n\t\t\tmanga: \"Manga\",\n\t\t\tmodernOrganic: \"Modern Organic\",\n\t\t\tgenesis: \"Genesis\",\n\t\t\tposterstyle: \"Poster Style\",\n\t\t\tsurrealism: \"Surrealism\",\n\t\t\tsketch: \"Sketch\",\n\t\t\trealism: \"Realism\",\n\t\t\twatercolorPainting: \"Watercolor Painting\",\n\t\t\tcubism: \"Cubism\",\n\t\t\tblackAndWhite: \"Black and White\",\n\t\t\tfmPhotography: \"Film Photography Style\",\n\t\t\tcinematic: \"Cinematic\",\n\t\t\tclearFacialFeatures: \"Clear Facial Features\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"Wide View\",\n\t\t\tbirdView: \"Bird's Eye View\",\n\t\t\ttopView: \"Top View\",\n\t\t\tupview: \"Upview\",\n\t\t\tfrontView: \"Front View\",\n\t\t\theadshot: \"Headshot\",\n\t\t\tultrawideshot: \"Ultrawide Shot\",\n\t\t\tmediumShot: \"Medium Shot (MS)\",\n\t\t\tlongShot: \"Long Shot (LS)\",\n\t\t\tdepthOfField: \"Depth of Field (DOF)\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"Face Shot (VCU)\",\n\t\t\tbigCloseUp: \"Big Close-Up (BCU)\",\n\t\t\tcloseUp: \"Close-Up (CU)\",\n\t\t\twaistShot: \"Waist Shot (WS)\",\n\t\t\tkneeShot: \"Knee Shot (KS)\",\n\t\t\tfullLengthShot: \"Full Length Shot (FLS)\",\n\t\t\textraLongShot: \"Extra Long Shot (ELS)\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"Style Low\",\n\t\t\tstyleMed: \"Style Medium\",\n\t\t\tstyleHigh: \"Style High\",\n\t\t\tstyleVeryHigh: \"Style Very High\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"Cold Light\",\n\t\t\twarmLight: \"Warm Light\",\n\t\t\thardLighting: \"Hard Lighting\",\n\t\t\tdramaticLight: \"Dramatic Light\",\n\t\t\treflectionLight: \"Reflection Light\",\n\t\t\tmistyFoggy: \"Misty/Foggy\",\n\t\t\tnaturalLight: \"Natural Light\",\n\t\t\tsunLight: \"Sun Light\",\n\t\t\tmoody: \"Moody\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney Bot\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"Square (1:1)\",\n\t\t\tportrait: \"Portrait (2:3)\",\n\t\t\tlandscape: \"Landscape (3:2)\",\n\t\t},\n\t}\n  ,suno:{\n    \"description\": \"Chế độ mô tả\",\n    \"custom\": \"Chế độ chuyên nghiệp\",\n    \"style\": \"Phong cách bài hát\",\n    \"stylepls\": \"Tên bài hát, ví dụ: Nhạc Pop\",\n    \"emputy\": \"Không có nội dung\",\n    \"noly\": \"Không có lời bài hát\",\n    \"inputly\": \"Vui lòng nhập tên bài hát hoặc lời bài hát\",\n    \"doingly\": \"Đang tiến hành, vui lòng đợi.\",\n    \"doingly2\": \"Đang lấy lời bài hát...\",\n    \"title\": \"Tên bài hát\",\n    \"titlepls\": \"Tên bài hát, ví dụ: Kỳ nghỉ\",\n    \"desc\": \"Mô tả bài hát\",\n    \"descpls\": \"Mô tả bài hát, ví dụ: Nhạc pop gốc về kỳ nghỉ\",\n    \"noneedly\": \"Không cần lời bài hát\",\n    \"rank\": \"Lựa chọn ngẫu nhiên\",\n    \"ly\": \"Lời bài hát\",\n    \"lypls\": \"Lời bài hát: với một định dạng nhất định\",\n    \"generate\": \"Sáng tác bài hát\",\n    \"generately\": \"Tạo lời bài hát\",\n    \"nodata\": \"Vui lòng sáng tạo trước để có danh sách bài hát\",\n\n    \"menu\": \"Âm nhạc\",\n    \"menuinfo\": \"Sáng tạo âm nhạc Suno\",\n    \"server\": \"Điểm cuối API Suno\",\n    \"serverabout\": \"Liên quan đến Suno\",\n    \"setOpenKeyPlaceholder\": \"Khóa liên quan cho API Suno; tùy chọn\",\n\n    upMps: 'Tải lên âm thanh',\n    extend: 'Mở rộng',\n    extendFrom: 'Mở rộng từ',\n    extendAt: 'Bắt đầu mở rộng từ',\n    fail: 'Thất bại',\n    info: 'Hướng dẫn:<br>Thời lượng tải lên âm thanh phải từ 6 giây đến 60 giây'\n\n   }\n   ,video:{\n    \"menu\": \"Video\",\n    \"menuinfo\": \"Tạo video Luma và các video khác\",\n    \"descpls\": \"Mô tả tạo video\",\n    \"lumaabout\": \"Về Luma\",\n    \"lumaserver\": \"Địa chỉ API Luma\",\n    \"setOpenKeyPlaceholder\": \"Khóa API Luma, không bắt buộc\",\n    \"generate\": \"Tạo video\",\n    \"nodata\": \"Không có video có sẵn, vui lòng tạo trước!\",\n    \"selectimg\": \"Chọn ảnh\",\n    \"clear\": \"Xóa\",\n    \"plsInput\": \"Vui lòng nhập nội dung!\",\n    \"submitSuccess\": \"Đã gửi thành công!\",\n    \"process\": \"Đang tạo video...\",\n    \"repeat\": \"Thử lại\",\n\n    \"lumainfo\": \"Giải thích: <ul><li>1. Video demo Pro và relax có liên kết có watermark.</li><li>2. Phiên bản Pro không có watermark cần phải lấy liên kết tải xuống qua nút 'Tải về'.</li><li>3. Các liên kết phiên bản Pro có thời hạn; vui lòng lưu trữ tập tin MP4 vào máy cục bộ kịp thời.</li><li>4. Đối với phiên bản Pro, lưu tập tin MP4 vào máy cục bộ trong vòng 30 phút sau khi tạo ra, vì kênh có thể bị chặn hoặc ngừng hoạt động.</li><li>5. Nếu liên kết tải xuống cho phiên bản Pro không hợp lệ, sẽ cung cấp liên kết video có watermark.</li></ul>\",\n    \"runwayabout\": \"Liên quan đến Runway\",\n    \"runwayserver\": \"Địa chỉ API Runway\",\n    \"setOpenKeyPlaceholder2\": \"Khóa API Runway, không bắt buộc\",\n    \"endImg\": \"Hình cuối\",\n    \"runwayinfo\": \"Giải thích: <ul><li>1. Các hình ảnh và video của Runway có thời hạn.</li><li>2. Vui lòng lưu trữ tập tin MP4 vào máy cục bộ trong vòng 30 phút sau khi tạo video.</li></ul>\",\n    \"nosup\": \"Tạm thời không hỗ trợ\",\n    \"rwgen2\": \"Phiên bản: Gen-2, hiệu quả chi phí\",\n    \"rwgen3\": \"Phiên bản: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\"\n\n  }\n  ,dance:{\n    menu: \"Nhảy múa\",\n    menuinfo: \"Tạo video nhảy múa với Viggle và các dịch vụ khác.\",\n    character: \"Nhân vật\", \n    viggleabout: \"Thông tin về Viggle\",\n    viggleserver: \"Địa chỉ API của Viggle\",\n    setOpenKeyPlaceholder: \"Khóa API của Viggle, không bắt buộc\",\n    info: \"Hướng dẫn:<br>1. Hình ảnh nhân vật nên là ảnh toàn thân.<br>2. Video mẫu nhảy múa nên là video cá nhân, không phải là nhóm nhảy.\",\n    model: \"Mẫu\",\n    bgw: \"Nền trắng\",\n    bgg: \"Nền xanh lá\",\n    bgmoban: \"Nền mẫu\",\n    bgrole: \"Nền nhân vật\",\n    gring: \"Đang tạo...\",\n    uprolefirst: \"Vui lòng tải ảnh nhân vật lên trước\",\n    uprolefail: \"Tải lên thất bại\",\n    upvideo: \"+ Tải lên Video mẫu nhảy múa\",\n    usevideo: \"+ Sử dụng Mẫu chính thức\",\n    moban: \"Mẫu nhảy múa\",\n    moban2: \"Tên mẫu\",\n    use: \"Sử dụng\"\n}\n\n}\n"
  },
  {
    "path": "src/locales/zh-CN.ts",
    "content": "export default {\n  common: {\n    add: '添加',\n    addSuccess: '添加成功',\n    edit: '编辑',\n    editSuccess: '编辑成功',\n    delete: '删除',\n    deleteSuccess: '删除成功',\n    save: '保存',\n    saveSuccess: '保存成功',\n    reset: '重置',\n    action: '操作',\n    export: '导出',\n    exportSuccess: '导出成功',\n    import: '导入',\n    importSuccess: '导入成功',\n    hide: '隐藏',\n    clear: '清空',\n    clearSuccess: '清空成功',\n    yes: '是',\n    no: '否',\n    confirm: '确定',\n    download: '下载',\n    noData: '暂无数据',\n    wrong: '好像出错了，请稍后再试。',\n    success: '操作成功',\n    failed: '操作失败',\n    verify: '验证',\n    unauthorizedTips: '未经授权，请先进行验证。',\n    stopResponding: '停止响应',\n  },\n  chat: {\n    newChatButton: '新建聊天',\n    //placeholder: '来说点什么吧...（Shift + Enter = 换行，\"/\" 触发提示词）',\n    placeholder: '可输入说点什么，也可贴截图或拖拽文件（Shift + Enter = 换行，\"/\" 触发提示词）',\n    placeholderMobile: '来说点什么...',\n    copy: '复制',\n    copied: '复制成功',\n    copyCode: '复制代码',\n    clearChat: '清空会话',\n    clearChatConfirm: '是否清空会话?',\n    exportImage: '保存会话到图片',\n    exportImageConfirm: '是否将会话保存为图片?',\n    exportSuccess: '保存成功',\n    exportFailed: '保存失败',\n    usingContext: '上下文模式',\n    turnOnContext: '当前模式下, 发送消息会携带之前的聊天记录',\n    turnOffContext: '当前模式下, 发送消息不会携带之前的聊天记录',\n    deleteMessage: '删除消息',\n    deleteMessageConfirm: '是否删除此消息?',\n    deleteHistoryConfirm: '确定删除此记录?',\n    clearHistoryConfirm: '确定清空记录?',\n    preview: '预览',\n    showRawText: '显示原文',\n  },\n  setting: {\n    setting: '设置',\n    general: '总览',\n    advanced: '高级',\n    config: '配置',\n    avatarLink: '头像链接',\n    name: '名称',\n    description: '描述',\n    backgroundImage: '背景图片',\n    role: '角色设定',\n    temperature: 'Temperature',\n    top_p: 'Top_p',\n    resetUserInfo: '重置用户信息',\n    chatHistory: '聊天记录',\n    theme: '主题',\n    language: '语言',\n    webdavSync: 'WebDAV 同步',\n    webdavConfig: '配置',\n    webdavUrl: 'WebDAV 地址',\n    webdavUsername: '用户名',\n    webdavPassword: '密码',\n    webdavConfigError: '请填写完整的 WebDAV 配置',\n    webdavNotConfigured: '请先配置 WebDAV',\n    webdavSyncSuccess: '同步成功',\n    webdavSyncError: '同步失败',\n    webdavTest: '测试连接',\n    webdavUpload: '上传',\n    webdavDownload: '下载',\n    api: 'API',\n    reverseProxy: '反向代理',\n    timeout: '超时',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS Proxy',\n    balance: 'API余额',\n    monthlyUsage: '本月使用量',\n  },\n  store: {\n    siderButton: '提示词商店',\n    local: '本地',\n    online: '在线',\n    title: '标题',\n    description: '描述',\n    clearStoreConfirm: '是否清空数据？',\n    importPlaceholder: '请粘贴 JSON 数据到此处',\n    addRepeatTitleTips: '标题重复，请重新输入',\n    addRepeatContentTips: '内容重复：{msg}，请重新输入',\n    editRepeatTitleTips: '标题冲突，请重新修改',\n    editRepeatContentTips: '内容冲突{msg} ，请重新修改',\n    importError: '键值不匹配',\n    importRepeatTitle: '标题重复跳过：{msg}',\n    importRepeatContent: '内容重复跳过：{msg}',\n    onlineImportWarning: '注意：请检查 JSON 文件来源！',\n    downloadError: '请检查网络状态与 JSON 文件有效性',\n  },\n\n\n  mjset:{\n    server:'服务端'\n    ,about:'关于'\n    ,model:'模型'\n    ,sysname:'AI绘图'\n  }\n\n  ,mjtab:{\n    chat:'对话'\n    ,draw:'绘画'\n    ,drawinfo:'AI绘画 Midjourney引擎'\n    ,gallery:'画廊'\n    ,galleryInfo:'我的画廊'\n  }\n  ,mjchat:{\n    loading:'正在载入图片'\n    ,openurl:'直接打开链接'\n    ,failReason:'失败原因：'\n    ,reload:'重新获取'\n    ,progress:'进度：'\n    ,wait:'任务已经提交请等待...'\n    ,reroll:'重绘'\n    ,wait2:'任务 {id} 已经提交请等待'\n    ,redrawEditing:'局部重绘编辑'\n    ,face:'换脸'\n    ,blend:'混图'\n    ,draw:'绘图'\n    ,submiting:'提交中'\n    ,submit:'提交'\n    ,wait3:'请勿关闭! 图片生成中...'\n    ,success:'保存成功'\n    ,successTitle:'成功'\n    ,modlePlaceholder:'自定义模型多个用空格隔开，不是必须'\n    ,myModle:'自定义模型'\n    ,historyCnt:'上下文数量'\n    ,historyToken:'更多的上下文会使记忆更精确，但会消耗更多的额度'\n    ,historyTCnt:'回复数'\n    ,historyTCntInfo:'(max_tokens)回复数越大 ,越有可能消耗更多的额度'\n    ,role:'角色设定'\n    ,rolePlaceholder:'给你的会话设置一个专属的角色，不是必须'\n    ,loading2:'正在加载...'\n    ,loadmore:'加载更多'\n    ,nofind:'未能找到'\n    ,nofind2:'相关内容, 你可尝试以下内容'\n    ,success2:'切换成功！'\n    ,modelChange:'模型切换'\n    ,search:'搜索'\n    ,searchPlaceholder:'GPTs名字、介绍'\n    ,attr:'附件'\n    ,noproduct:'画廊还没有您的作品'\n    ,myGallery:'我的画廊'\n    ,yourHead:'你的头像'\n    ,your2Head:'明星图'\n    ,tipInfo:'说明：<li>1 图片都必须包含脸，否则出不来图</li> <li>2 “明星图”可以先用mj绘画制作出来</li> <li>3 “明星图”其实动漫图也行</li> <li>4 “你的头像”建议用一寸个人照</li>'\n    ,placeInput: '请填写提示词！'\n    ,more5sb: '最多上传5张图片'\n    ,exSuccess: '导出成功... 请看下载栏'\n    ,downloadSave: \"ai绘画.txt\"\n    ,noproducet: \"暂时没成熟作品\"\n    ,imgBili:'图片比例'\n    ,imagEx:'作品图片链接导出'\n    ,prompt:'提示词'\n    ,imgCYes:'含有垫图'\n    ,imgCUpload:'自传垫图'\n    ,imgCInfo:'垫图说明：<br/> 1.垫图可使用自己的图片作为基础，让MJ来绘图<br/> 2.可以使用多张垫图 最多5张， 单张图片不超过1M<br/>'\n    ,imgCadd:'+添加'\n    ,del:'删除'\n    ,img2text:'图生文'\n    ,img2textinfo:'不知如何写提示词？用图生文试试！<br/>提交图片，出提示词'\n    ,traning:'翻译中...'\n    ,imgcreate:'生成图片'\n    ,imginfo:'其他参数：  <li>1 --no 忽略 --no car 图中不出现车 </li><li>2 --seed 可先获取种子 --seed 123456 </li> <li>3 --chaos 10 混合(范围：0-100)</li> <li>4 --tile 碎片化 </li>  <li>5 --cw 0 只参考五官, 100 参考五官、头发、服装等  </li>'\n    ,tStyle:'风格'\n    ,tView:'视角'\n    ,tShot:'人物镜头'\n    ,tLight:'灯光'\n    ,tQuality:'画质'\n    ,tStyles:'艺术程度'\n    ,tVersion:'模型版本'\n    ,dalleInfo:' 说明：   <li>1 dall-e 是openAi提供的画图模型</li>  <li>2 openAi的图片有时效性，请做好备份</li>   <li>3 注意：1790px的图片价格是双倍</li> <li>4 注意：dall-e-2、gpt-image-1 支持多图参考</li> '\n    ,version:'版本'\n    ,size:'尺寸'\n    ,blendInfo:'说明： <li>1 合成至少2张图片</li> <li>2 最多可传6张图</li> '\n    ,blendStart:'开始合成'\n    ,no2add:'请勿重复添加图片'\n    ,add2more:'请添加两张以上图片'\n    ,no1m:'图片大小不能超过{m}M'\n    ,imgExt:'图片仅支持jpg,gif,png,jpeg格式'\n    ,setSync:'同步Midjourney、Suno设置'\n\n    ,addGPTS:'新增GPTs'\n    ,addPlaceholder:'将GPTs的gid贴这儿 也可直接贴gpts的链接'\n    ,gidError:'未找到有效的gid，请重新填写'\n    ,success3:'新增GPTs成功！'\n\n  },\n  mj:{\n    setOpen:'OpenAI 相关',\n    setOpenPlaceholder:'必须包含 http(s)://'\n    ,setOpenUrl:'OpenAI接口地址'\n    ,setOpenKeyPlaceholder:'使用自定义 OpenAI Key 绕过密码访问限制'\n    ,setMj:'Midjourney 相关'\n    ,setMjUrl:'Midjourney接口地址:'\n    ,setMjKeyPlaceholder:'使用自定义 Api Secret 绕过密码访问限制'\n    ,setUploader:'上传相关'\n    ,setUploaderUrl:'上传地址:'\n    ,setBtSave:'保存'\n    ,setBtBack:'恢复默认'\n\n    ,\n    redraw:'局部重绘'\n    ,fail1:'客官不要太急嘛，正在加载呢'\n    ,success1:'图片刷新成功！'\n    ,high_variation:'强变化'\n    ,low_variation:'弱变化'\n    ,p15:'变焦1.5倍'\n    ,p20:'变焦2倍'\n    ,p100:'方正'\n\n    ,retry:'重分析'\n    ,pan_left:'向左'\n    ,pan_right:'向右'\n    ,pan_up:'向上'\n    ,pan_down:'向下'\n    ,up2:'高清2倍'\n    ,up4:'高清4倍',\n\n    thinking:'思考中...'\n    ,noReUpload:'不能重复上传'\n    ,uploading:'上传中...'\n    ,uploadSuccess:'上传成功'\n    ,uploadFail:'上传失败:'\n    ,upPdf:'<span>上传图片、附件<br/>能上传图片、PDF、EXCEL等文档</span><p>支持拖拽</p>'\n    ,upImg:'<span><b>上传图片</b><br/>会自动调用 gpt-4-vision-preview 模型<br>注意：会有额外的图片费用<br/>格式: jpeg jpg png gif</span><p>支持拖拽</p> <p class=\"pt-2\"><b>上传MP3 MP4</b> <br>会自动直接调用 whisper-1 模型<br>格式有：mp3 mp4 mpeg mpga m4a wav webm</p>'\n    ,clearAll:'清参数'\n    ,czoom:'自定义'\n    ,customTitle:'自定义变焦'\n    ,zoominfo:'修改zoom值,范围在 1.0~2.0 默认设置为1.8',\n\n    modleSuccess:'模型加载成功'\n    ,setingSuccess:'设置成功'\n\n    ,tokenInfo1:'剩余Tokens = 模型长度 - 角色设定 - 上下文(会话历史) - 回复数 - 当前输入'\n    ,tokenInfo2:'角色设定留空，系统会给一个默认的'\n    ,noSuppertModel:'刷新，暂不支持此模型！'\n    ,failOcr:'识别失败'\n    ,remain:'剩:'\n\n    ,totalUsage:'订阅总额'\n    ,disableGpt4:'已禁用GPT4'\n    ,setTextInfo:'OpenAi Api Key 错误，点击这里重新'\n\n    ,attr1:'附'\n    ,ulink:'原图链接'\n    ,copyFail:'复制失败'\n    ,tts:'TTS 文本转语音'\n    ,fail:'发生错误'\n    ,noSupperChrom:'浏览器不支持！'\n    ,lang:'语音'\n    ,ttsLoading:'语音转化...'\n    ,ttsSuccess:'转化成功'\n    ,micIng:'正在录音，说点什么...'\n    ,mStart:'开始'\n    ,mPause:'暂停'\n    ,mGoon:'继续'\n    ,mRecord:'重录'\n    ,mPlay:'播放'\n    ,mCanel:'取消'\n    ,mSent:'发送'\n\n    ,findVersion:'发现更新版本'\n    ,yesLastVersion:'已是最新版本'\n    ,infoStar:'此项目开源于 <a  class=\"text-blue-600 dark:text-blue-500\" href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\" target=\"_blank\"> GitHub </a>，免费且基于 MIT 协议，没有任何形式的付费行为！ </p><p>如果你觉得此项目对你有帮助，请在 GitHub 帮我点个 Star，谢谢！'\n    ,setBtSaveChat:'仅保存会话'\n    ,setBtSaveSys: '保存至系统'\n\n    ,wsrvClose:'关闭 wsrv'\n    ,wsrvOpen:'开启 wsrv'\n\n    ,temperature:'随机性'\n    ,temperatureInfo:'(temperature)值越大，回复越随机'\n    ,top_p:'核采样'\n    ,top_pInfo:'(top_p)与随机性类似，但不要和随机性一起更改 '\n    ,presence_penalty:'话题新鲜度  '\n    ,presence_penaltyInfo:'(presence_penalty)值越大，越有可能扩展到新话题'\n    ,frequency_penalty:'频率惩罚度'\n    ,frequency_penaltyInfo:' (frequency_penalty)值越大，越有可能降低重复字词'\n\n    ,tts_voice:'TTS 语音人物'\n    ,typing:'正在输入'\n\n    ,authErro:'授权失败'\n    ,authBt:'请重新输入授权访问密码'\n\n    ,micWhisper:'Whisper语音识别'\n    ,micAsr:'即时识别'\n    ,micRec:'开始录音,请说话！2秒内无声音将自动关闭'\n    ,micRecEnd:'录音已结束'\n\n    ,subtle:'高清2倍'\n    ,creative:'高清2倍.创意'\n    ,gpt_gx:'GPTs用g-*'\n\n    ,ideoabout:'Ideogram 相关'\n    ,ideoserver:'Ideogram 接口地址'\n    ,ideokeyPlaceholder:'Ideogram 的API Key 可不填'\n    ,ideopls:'图片描述 提示词'\n    ,nohead:'不含'\n\n    ,klingabout:'可灵 相关'\n    ,klingserver:'可灵 接口地址'\n    ,klingkeyPlaceholder:'可灵 的API Key 可不填'\n    ,klingkey:'可灵 Key'\n    ,mode:'模式'\n    ,duration:'时长'\n    ,negative_prompt:'不含物体的文字放这儿'\n    ,std:'高性能'\n    ,pro:'高表现'\n    ,needImg:'请传参考图才生效！'\n    ,seed:'种子数字 1~2147483647'\n    ,klingInfo:'说明： <li>1. 高表现是3.5倍的价格</li>  <li>2. 10s是2倍的价格</li> <li>3. 尾帧必须有参考图片才生效</li> <li>4. v1.5 v1.6的价格都是v1.0的2倍</li><li>5. v2-master的价格都是v1.0的10倍</li>'\n\n    ,camera_type:'镜头'\n    ,cnull:'智能匹配'\n    ,down_back: '下移拉远'\n    ,forward_up: '推进上移'\n    ,right_turn_forward: '右旋推进'\n    ,left_turn_forward: '左旋推进'\n\n    ,kling:'可灵'\n\n    ,rttab:'语音'\n    ,rtinfo:'实时语音对话服务(realtime)'\n    ,rtsetting:'请设置服务端，目前Realtime 仅支持远程服务；需本地服务请联系作者'\n    ,rjcloded:'连接已断开'\n    ,checkkey:'请检查 api key 是否正确'\n    ,rtsuccess:'连接正常保持通话'\n    ,rtservererror:'websocket 连接服务器错误！'\n    ,rtservererror2:'不支持录音，可能是设备原因！'\n    ,rtconecting:'正在连接服务器'\n\n    ,confirmDelete:'确认要删除？'\n    ,pikaabout:'Pika 相关'\n    ,pikaserver:'Pika 接口地址'\n    ,pikakeyPlaceholder:'Pika 的API Key 可不填'\n    ,createFail:'生成失败'\n    ,selecteff:'参考效果'\n\n    ,udioabout:'Udio 相关'\n    ,udiokeyPlaceholder:'Udio 的API Key 可不填'\n    ,udioserver:'Udio 接口地址'\n    ,ud_prompt:'提示词'\n    ,ud_prompt_pls:'提示词: 描述、曲风'\n    ,ud_ly_write:'自定义歌词'\n    ,ud_ly_auto:'智能歌词'\n    ,ud_ly_null:'纯音乐'\n    ,ud_v32:'实惠'\n    ,ud_v130:'时间长'\n    ,ud_info:'注意：<ul><li>1.udio-32 时长短</li><li>2.udio-130 价格是udio-32的2倍 </li><li>3.提示词内可以放风格、描述等</li></ul>'\n    ,ud_fail:\"这首歌生成失败！\"\n    ,ud_doing:\"生成中无法播放\"\n    ,ud_continuation:\"后扩展\"\n    ,ud_precede:\"前扩展\"\n\n    ,upImg2:'<span><b>上传图片</b><br/>该模型支持识图<br>注意：会有额外的图片费用<br/>格式: jpeg jpg png gif</span><p>支持拖拽</p> <p class=\"pt-2\"><b>上传MP3 MP4</b> <br>会自动直接调用 whisper-1 模型<br>格式有：mp3 mp4 mpeg mpga m4a wav webm</p>'\n    ,rml_info:'注意：<ul><li>1.必须带图</li><li>2.模型支持 gen3a_turbo、gen4_turbo </li><li>3.10s的价格是5s的双倍</li><li>4.gen4_turbo 支持的ratio 比例类型更多</li></ul>'\n    ,rml_heng:'横屏'\n    ,rml_shu:'竖屏'\n\n    ,pixabout:'Pixverse 相关'\n    ,pixkeyPlaceholder:'Pixverse 的API Key 可不填'\n    ,pixserver:'Pixverse 接口地址'\n    ,pixinfo:' 说明：<br>  <ul> <li>1.以v3.5 360p 时长5s 模式 Normal 为基数</li><li>2.支持v4 v3.5 低版本不再支持</li>  <li>3.时长8s 是 2倍</li> <li>4.540P 1.5倍 720P 2倍 1080P 4倍</li> <li>5.模式 performance 2倍</li> <li>6.倍数是相乘的 比如 720P 时长8s 那就是 2*2是4倍，如果再加performance 就是8倍</li></ul>'\n  \n   ,server_load:'服务端获取'\n   ,model_select:'模型选择'\n\n   ,riffabout:'Riffusion 相关'\n   ,riffkeyPlaceholder:'Riffusion 的API Key 可不填'\n   ,riffserver:'Riffusion 接口地址'\n   ,riffinfo:'说明'\n\n   ,editImage:'图片编辑'\n   ,editVideo:'图生视频'\n   ,moreset:'更多参数'\n\n   \n  },\n\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"一般\",\n\t\t\tclear: \"清晰\",\n\t\t\thd: \"高清\",\n\t\t\tultraHd: \"超高清\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"赛博朋克\",\n\t\t\tstar: \"星际\",\n\t\t\tanime: \"动漫\",\n\t\t\tjapaneseComicsManga: \"日本漫画\",\n\t\t\tinkWashPaintingStyle: \"水墨画风格\",\n\t\t\toriginal: \"原创\",\n\t\t\tlandscape: \"风景画\",\n\t\t\tillustration: \"插画\",\n\t\t\tmanga: \"漫画\",\n\t\t\tmodernOrganic: \"现代自然\",\n\t\t\tgenesis: \"创世纪\",\n\t\t\tposterstyle: \"海报风格\",\n\t\t\tsurrealism: \"超现实主义\",\n\t\t\tsketch: \"素描\",\n\t\t\trealism: \"写实\",\n\t\t\twatercolorPainting: \"水彩画\",\n\t\t\tcubism: \"立体主义\",\n\t\t\tblackAndWhite: \"黑白\",\n\t\t\tfmPhotography: \"胶片摄影风格\",\n\t\t\tcinematic: \"电影化\",\n\t\t\tclearFacialFeatures: \"清晰的面部特征\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"宽视角\",\n\t\t\tbirdView: \"鸟瞰视角\",\n\t\t\ttopView: \"顶视角\",\n\t\t\tupview: \"仰视角\",\n\t\t\tfrontView: \"正面视角\",\n\t\t\theadshot: \"头部特写\",\n\t\t\tultrawideshot: \"超广角视角\",\n\t\t\tmediumShot: \"中景\",\n\t\t\tlongShot: \"远景\",\n\t\t\tdepthOfField: \"景深\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"脸部特写\",\n\t\t\tbigCloseUp: \"大特写\",\n\t\t\tcloseUp: \"特写\",\n\t\t\twaistShot: \"腰部以上\",\n\t\t\tkneeShot: \"膝盖以上\",\n\t\t\tfullLengthShot: \"全身照\",\n\t\t\textraLongShot: \"极远景\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"低强度风格\",\n\t\t\tstyleMed: \"中等强度风格\",\n\t\t\tstyleHigh: \"高强度风格\",\n\t\t\tstyleVeryHigh: \"非常高强度风格\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"冷光\",\n\t\t\twarmLight: \"暖光\",\n\t\t\thardLighting: \"硬光\",\n\t\t\tdramaticLight: \"戏剧性光线\",\n\t\t\treflectionLight: \"反射光\",\n\t\t\tmistyFoggy: \"薄雾\",\n\t\t\tnaturalLight: \"自然光\",\n\t\t\tsunLight: \"阳光\",\n\t\t\tmoody: \"情绪化\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney 机器人\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"正方形 (1:1)\",\n\t\t\tportrait: \"肖像 (2:3)\",\n\t\t\tlandscape: \"风景 (3:2)\",\n\t\t},\n\t}\n\n  ,suno:{\n    description:\"描述模式\"\n    ,custom:\"定制模式\"\n    ,style:'歌曲风格'\n    ,stylepls:'歌曲名称比如:流行音乐'\n    ,emputy:'暂无内容'\n    ,noly:'无歌词'\n    ,inputly:'请输入歌曲名称或歌词'\n    ,doingly:\"正在执行请稍后.\"\n    ,doingly2: \"正在获取歌词...\"\n    ,title:'歌曲名称'\n    ,titlepls:'歌曲名称比如:假期'\n    ,desc:'歌曲描述'\n    ,descpls:'歌曲描述 比如:关于假期的原声流行音乐'\n    ,noneedly:'无需歌词'\n    ,rank:'随机获取'\n    ,ly:'歌词'\n    ,lypls:'歌词:有一定的格式'\n    ,generate:'创作歌曲'\n    ,generately:'生成歌词'\n    ,nodata:'请先创作才有歌曲列表'\n\n    ,menu:'音乐'\n    ,menuinfo:'Suno、Udio等音乐创作'\n    ,server:'Suno 接口地址'\n    ,serverabout:'Suno 相关'\n    ,setOpenKeyPlaceholder:'Suno API 的相关KEY；可不填'\n\n    ,upMps:'上传音频'\n    ,extend:'延伸'\n    ,extendFrom:'延伸于'\n    ,extendAt:'延伸开始于'\n    ,fail:'失败'\n    ,info:'说明:<br>上传音频时长必须在6s-60s内'\n    ,lyricsFail:'获取歌曲失败'\n  }\n  ,video:{\n    menu:\"视频\",\n    menuinfo:'Veo 可灵 pixverse等 视频创作',\n    descpls:'视频创作描述',\n    lumaabout:\"Luma 相关\",\n    lumaserver:\"Luma 接口地址\",\n    setOpenKeyPlaceholder:'Luma API 的key, 可不填',\n    generate:'生成视频',\n    nodata:'暂无可用视频，请先生成！',\n    selectimg:'参考图片',\n    clear:'清除',\n    plsInput:'请输入内容！',\n    submitSuccess:'已提交成功！',\n    process:'视频生成中...',\n    repeat:'重新获取',\n    pending:'状态:队列中',\n    processing:'状态:生产中',\n    failed:'状态:生成失败！',\n    download:'下载',\n    extend:'延展',\n\n    lumainfo:'说明：<ul><li >1.relax版已下线，<b style=\"color:red\">入口已经更换到pro无水印版</b></li><li>2.无水印版本需要通过“下载按钮”得到下载链接</li><li>3.pro得到的链接有时限；请及时保存mp4文件到本地</li><li>4.请在生成后的30分钟内；将mp4保存到本地，渠道号也可能被封或者下线</li> <li>5.当下载链接无效时会给出带水印的视频链接</li></ul>',\n    runwayabout:'Runway 相关',\n    runwayserver:'Runway 接口地址',\n    setOpenKeyPlaceholder2:'Runway API 的key, 可不填',\n    endImg:'尾帧图',\n    runwayinfo:'说明：<ul><li>1. Runway 图片与视频都有有效期</li>  <li>2. 请在生成视频后30分钟内将mp4保存到本地</li>  <li>3. 过期重新获取，可能存在账号下线而获取失败</li><li>4. Gen3A Turbo 必须带图或者视频</li><li>5. 参考可以是图或者视频mp4 </li></ul>',\n    nosup:'暂不支持',\n    rwgen2:'版本: Gen-2, 价格实惠',\n    rwgen3:'版本: Gen-3 Alpha',\n    rwgen3fast:'版本: Gen-3 Alpha Fast',\n    repeat2:'过期.重新获取',\n\n    rwgen3turbo:'版本: Gen-3 Alpha Turbo',\n    gen3a_turbo_img:'Gen-3 Alpha Turbo 必须带图'\n\n    ,selectModel:'请选择模型'\n\n  }\n  ,dance:{\n    menu:\"舞蹈\",\n    menuinfo:'Viggle等 舞蹈视频创作'\n    ,character:'人物角色'\n    ,viggleabout:\"Viggle 相关\",\n    viggleserver:\"Viggle 接口地址\",\n    setOpenKeyPlaceholder:'Viggle API 的key, 可不填',\n    info:'说明:<br>1.角色图片最好是个人全身照片<br>2.舞蹈模版视频最好是个人视频 别传群舞<br>3.生成会给出倍数价格 2电量 表示2倍的基础价格',\n    model:'模型',\n    bgw:'白色背景',\n    bgg:'绿色背景',\n    bgmoban:'模版背景',\n    bgrole:'角色背景',\n    gring:'生成中...',\n    uprolefirst:'请先上传角色图片',\n    uprolefail:'上传失败',\n    upvideo:'+上传模版舞蹈视频',\n    usevideo:'+使用官网模版',\n    moban:'舞蹈模版',\n    moban2:'模版名称',\n    use:'使用',\n  }\n\n\n}\n"
  },
  {
    "path": "src/locales/zh-TW.ts",
    "content": "export default {\n  common: {\n    add: '新增',\n    addSuccess: '新增成功',\n    edit: '編輯',\n    editSuccess: '編輯成功',\n    delete: '刪除',\n    deleteSuccess: '刪除成功',\n    save: '儲存',\n    saveSuccess: '儲存成功',\n    reset: '重設',\n    action: '操作',\n    export: '匯出',\n    exportSuccess: '匯出成功',\n    import: '匯入',\n    importSuccess: '匯入成功',\n    clear: '清除',\n    clearSuccess: '清除成功',\n    yes: '是',\n    no: '否',\n    confirm: '確認',\n    download: '下載',\n    noData: '目前無資料',\n    wrong: '發生錯誤，請稍後再試。',\n    success: '操作成功',\n    failed: '操作失敗',\n    verify: '驗證',\n    unauthorizedTips: '未經授權，請先進行驗證。',\n    stopResponding: '停止回應',\n  },\n  chat: {\n    newChatButton: '新增對話',\n    //placeholder: '來說點什麼...（Shift + Enter = 換行，\"/\" 觸發提示詞）',\n    placeholder: '可輸入說點什麼，也可貼截圖或拖拽檔案（Shift + Enter = 換行，\"/\" 觸發提示詞）',\n    placeholderMobile: '來說點什麼...',\n    copy: '複製',\n    copied: '複製成功',\n    copyCode: '複製代碼',\n    clearChat: '清除對話',\n    clearChatConfirm: '是否清空對話?',\n    exportImage: '儲存對話為圖片',\n    exportImageConfirm: '是否將對話儲存為圖片?',\n    exportSuccess: '儲存成功',\n    exportFailed: '儲存失敗',\n    usingContext: '上下文模式',\n    turnOnContext: '啟用上下文模式，在此模式下，發送訊息會包含之前的聊天記錄。',\n    turnOffContext: '關閉上下文模式，在此模式下，發送訊息不會包含之前的聊天記錄。',\n    deleteMessage: '刪除訊息',\n    deleteMessageConfirm: '是否刪除此訊息?',\n    deleteHistoryConfirm: '確定刪除此紀錄?',\n    clearHistoryConfirm: '確定清除紀錄?',\n    preview: '預覽',\n    showRawText: '顯示原文',\n  },\n  setting: {\n    setting: '設定',\n    general: '總覽',\n    advanced: '進階',\n    config: '設定',\n    avatarLink: '頭貼連結',\n    name: '名稱',\n    description: '描述',\n    backgroundImage: '背景圖片',\n    role: '角色設定',\n    temperature: 'Temperature',\n    top_p: 'Top_p',\n    resetUserInfo: '重設使用者資訊',\n    chatHistory: '紀錄',\n    theme: '主題',\n    language: '語言',\n    webdavSync: 'WebDAV 同步',\n    webdavConfig: '配置',\n    webdavUrl: 'WebDAV 地址',\n    webdavUsername: '使用者名稱',\n    webdavPassword: '密碼',\n    webdavConfigError: '請填寫完整的 WebDAV 配置',\n    webdavNotConfigured: '請先配置 WebDAV',\n    webdavSyncSuccess: '同步成功',\n    webdavSyncError: '同步失敗',\n    webdavTest: '測試連接',\n    webdavUpload: '上傳',\n    webdavDownload: '下載',\n    api: 'API',\n    reverseProxy: '反向代理',\n    timeout: '逾時',\n    socks: 'Socks',\n    httpsProxy: 'HTTPS Proxy',\n    balance: 'API Credit 餘額',\n    monthlyUsage: '本月使用量',\n  },\n  store: {\n    siderButton: '提示詞商店',\n    local: '本機',\n    online: '線上',\n    title: '標題',\n    description: '描述',\n    clearStoreConfirm: '是否清除資料？',\n    importPlaceholder: '請將 JSON 資料貼在此處',\n    addRepeatTitleTips: '標題重複，請重新輸入',\n    addRepeatContentTips: '內容重複：{msg}，請重新輸入',\n    editRepeatTitleTips: '標題衝突，請重新修改',\n    editRepeatContentTips: '內容衝突{msg} ，請重新修改',\n    importError: '鍵值不符合',\n    importRepeatTitle: '因標題重複跳過：{msg}',\n    importRepeatContent: '因內容重複跳過：{msg}',\n    onlineImportWarning: '注意：請檢查 JSON 檔案來源！',\n    downloadError: '請檢查網路狀態與 JSON 檔案有效性',\n  },\n\n  \"mj\": {\n    \"setOpen\": \"OpenAI 相關\",\n    \"setOpenPlaceholder\": \"必須包含 http(s)://\",\n    \"setOpenUrl\": \"OpenAI接口地址\",\n    \"setOpenKeyPlaceholder\": \"使用自定義 OpenAI Key 繞過密碼訪問限制\",\n    \"setMj\": \"Midjourney 相關\",\n    \"setMjUrl\": \"Midjourney接口地址:\",\n    \"setMjKeyPlaceholder\": \"使用自定義 Api Secret 繞過密碼訪問限制\",\n    \"setUploader\": \"上傳相關\",\n    \"setUploaderUrl\": \"上傳地址:\",\n    \"setBtSave\": \"保存\",\n    \"setBtBack\": \"恢復默認\",\n    \"redraw\": \"局部重繪\",\n    \"fail1\": \"客官不要太急嘛，正在加載呢\",\n    \"success1\": \"圖片刷新成功！\",\n    \"high_variation\": \"強變化\",\n    \"low_variation\": \"弱變化\",\n    \"p15\": \"變焦1.5倍\",\n    \"p20\": \"變焦2倍\",\n    \"p100\": \"方正\",\n    \"retry\": \"重分析\",\n    \"pan_left\": \"向左\",\n    \"pan_right\": \"向右\",\n    \"pan_up\": \"向上\",\n    \"pan_down\": \"向下\",\n    \"up2\": \"高清2倍\",\n    \"up4\": \"高清4倍\",\n\n    \"thinking\": \"思考中...\",\n    \"noReUpload\": \"不能重複上傳\",\n    \"uploading\": \"上傳中...\",\n    \"uploadSuccess\": \"上傳成功\",\n    \"uploadFail\": \"上傳失敗:\",\n    \"upPdf\": \"<span>上傳圖片或附件<br/>可以上傳圖片、PDF、EXCEL等文檔</span><p>支持拖放</p>\",\n    \"upImg\": \"<span><b>上傳圖片</b><br/>將自動調用 gpt-4-vision-preview 模型<br>注意：可能會有額外的圖片費用<br/>格式：jpeg、jpg、png、gif</span><p>支持拖放</p> <p class=\\\"pt-2\\\"><b>上傳MP3 MP4</b> <br>將自動直接調用 whisper-1 模型<br>格式：mp3、mp4、mpeg、mpga、m4a、wav、webm</p>\",\n    \"clearAll\": \"清參數\",\n    \"czoom\": \"自定義\",\n    \"customTitle\": \"自定義變焦\",\n    \"zoominfo\": \"修改zoom值，範圍在 1.0 到 2.0，默认设置為1.8\",\n\n  \"modleSuccess\": \"模型成功載入\",\n    \"setingSuccess\": \"設定成功\",\n\n    \"tokenInfo1\": \"剩餘Tokens = 模型長度 - 角色設定 - 上下文（對話歷史） - 回覆數 - 目前輸入\",\n    \"tokenInfo2\": \"保持角色設定為空，系統將提供默認值。\",\n    \"noSuppertModel\": \"刷新，目前不受此模型支持！\",\n    \"failOcr\": \"識別失敗\",\n    \"remain\": \"餘:\",\n\n    \"totalUsage\": \"訂閱總額\",\n    \"disableGpt4\": \"已禁用GPT4\",\n    \"setTextInfo\": \"OpenAI API Key 錯誤，點擊這裡重新\",\n\n    \"attr1\": \"附\",\n    \"ulink\": \"原圖鏈接\",\n    \"copyFail\": \"複製失敗\",\n    \"tts\": \"文字轉語音\",\n    \"fail\": \"發生錯誤\",\n    \"noSupperChrom\": \"瀏覽器不支援！\",\n    \"lang\": \"語音\",\n    \"ttsLoading\": \"轉換中...\",\n    \"ttsSuccess\": \"轉換成功\",\n    \"micIng\": \"錄音中，請說些什麼...\",\n    \"mStart\": \"開始\",\n    \"mPause\": \"暫停\",\n    \"mGoon\": \"繼續\",\n    \"mRecord\": \"重新錄製\",\n    \"mPlay\": \"播放\",\n    \"mCanel\": \"取消\",\n    \"mSent\": \"發送\",\n    \"findVersion\": \"發現更新版本\",\n    \"yesLastVersion\": \"已是最新版本\",\n    \"infoStar\": \"此專案在 <a class=\\\"text-blue-600 dark:text-blue-500\\\" href=\\\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\\\" target=\\\"_blank\\\">GitHub</a> 上以 MIT 協議開源，免費且沒有任何付費行為！ </p><p>如果你覺得這個專案對你有幫助，請在 GitHub 上給它一顆星，謝謝！\",\n    \"setBtSaveChat\": \"僅保存對話\",\n    \"setBtSaveSys\": \"保存至系統\",\n    \"wsrvClose\": \"關閉 wsrv\",\n    \"wsrvOpen\": \"開啟 wsrv\",\n    \"temperature\": \"隨機性\",\n    \"temperatureInfo\": \"隨著 (temperature) 值的增加，回覆變得更隨機\",\n    \"top_p\": \"概率抽樣\",\n    \"top_pInfo\": \"(top_p) 類似於隨機性，但不應與溫度一同更改\",\n    \"presence_penalty\": \"話題新鮮度\",\n    \"presence_penaltyInfo\": \"隨著 (presence_penalty) 值的增加，擴展到新話題的機會更高\",\n    \"frequency_penalty\": \"頻率懲罰\",\n    \"frequency_penaltyInfo\": \"隨著 (frequency_penalty) 值的增加，降低重複字詞的可能性更高\",\n    \"tts_voice\": \"TTS 語音角色\",\n    \"typing\": \"正在輸入\",\n    \"authErro\": \"授權失敗\",\n    \"authBt\": \"請重新輸入授權訪問密碼\",\n    \"micWhisper\": \"Whisper語音識別\",\n    \"micAsr\": \"即時識別\",\n    \"micRec\": \"開始錄音，請說話！2秒內無聲音將自動關閉\",\n    \"micRecEnd\": \"錄音已結束\",\n    subtle: '高清2倍'\n    ,creative: '高清2倍. 創意'\n    ,gpt_gx: 'GPTs 用 g-*',\n    \"ideoabout\": \"有關 Ideogram\",\n    \"ideoserver\": \"Ideogram 伺服器\",\n    \"ideokeyPlaceholder\": \"Ideogram 的 API 金鑰（可選）\",\n    \"ideopls\": \"圖片描述提示詞\",\n    \"nohead\": \"不含\",\n\n    klingabout: '可靈 相關',\n    klingserver: '可靈 接口地址',\n    klingkeyPlaceholder: '可靈 的API Key 可不填',\n    klingkey: '可靈 Key',\n    mode: '模式',\n    duration: '時長',\n    negative_prompt: '不含物體的文字放這裡',\n    std: '高性能',\n    pro: '高表現',\n    needImg: '請傳參考圖才生效！',\n    seed: '種子數字 1~2147483647',\n    klingInfo: '說明： <li>1. 高表現是3.5倍的價格</li> <li>2. 10秒是2倍的價格</li> <li>3. 尾幀必須有參考圖片才生效</li>'\n    ,\"camera_type\": \"鏡頭\",\n    \"cnull\": \"智能配對\",\n    \"down_back\": \"下移拉遠\",\n    \"forward_up\": \"推進上移\",\n    \"right_turn_forward\": \"右旋推進\",\n    \"left_turn_forward\": \"左旋推進\"\n    ,kling:'可灵',\n    rttab: '語音',\n    rtinfo: '實時語音對話服務(realtime)',\n    rtsetting: '請設置服務器，目前Realtime僅支持遠程服務；需本地服務請聯繫作者',\n    rjcloded: '連接已斷開',\n    checkkey: '請檢查api key是否正確',\n    rtsuccess: '連接正常保持通話',\n    rtservererror: 'websocket連接服務器錯誤！',\n    rtservererror2: '不支持錄音，可能是設備原因！',\n    rtconecting: '正在連接服務器',\n    \"confirmDelete\": \"確認要刪除？\",\n    \"pikaabout\": \"Pika 相關\",\n    \"pikaserver\": \"Pika 接口地址\",\n    \"pikakeyPlaceholder\": \"Pika 的API Key 可不填\",\n    \"createFail\": \"生成失敗\",\n    \"selecteff\": \"參考效果\",\n\n     \"udioabout\": \"關於 Udio\",\n    \"udiokeyPlaceholder\": \"Udio API 金鑰（可選）\",\n    \"udioserver\": \"Udio 接口地址\",\n    \"ud_prompt\": \"提示詞\",\n    \"ud_prompt_pls\": \"提示詞：描述、風格\",\n    \"ud_ly_write\": \"自訂歌詞\",\n    \"ud_ly_auto\": \"智能歌詞\",\n    \"ud_ly_null\": \"純音樂\",\n    \"ud_v32\": \"實惠\",\n    \"ud_v130\": \"時間長\",\n    \"ud_info\": \"注意：<ul><li>1. Udio-32 時長短</li><li>2. Udio-130 價格是 Udio-32 的兩倍</li><li>3. 提示詞內可以放風格、描述等</li></ul>\",\n    \"ud_fail\": \"這首歌生成失敗！\",\n    \"ud_doing\": \"生成中無法播放\",\n    \"ud_continuation\": \"後擴展\",\n    \"ud_precede\": \"前擴展\",\n\n    \"upImg2\": \"<span><b>上載圖片</b><br/>該模型支持識圖<br>注意：會有額外的圖片費用<br/>格式：jpeg jpg png gif</span><p>支持拖曳</p> <p class=\\\"pt-2\\\"><b>上載MP3 MP4</b> <br>會自動直接調用 whisper-1 模型<br>格式包括：mp3 mp4 mpeg mpga m4a wav webm</p>\",\n    \"rml_info\": \"注意：<ul><li>1. 必須帶圖</li><li>2. 模型只有一個 gen3a_turbo</li><li>3. 10秒的價格是5秒的雙倍</li></ul>\",\n    \"rml_heng\": \"橫屏\",\n    \"rml_shu\": \"豎屏\",\n   \n    \"pixabout\": \"與 Pixverse 相關\",\n    \"pixkeyPlaceholder\": \"Pixverse 的 API 金鑰可不填\",\n    \"pixserver\": \"Pixverse 接口地址\",\n    \"pixinfo\": \" 說明：<br> <ul> <li>1.以 v3.5 360p 時長 5s 模式 Normal 為基數</li><li>2.v2.5 是 0.5 倍</li> <li>3.時長 10s 是 2 倍</li> <li>4.540P 1.5 倍，720P 2 倍，1080P 4 倍</li> <li>5.模式 performance 2 倍</li> <li>6.倍數是相乘的，比如 720P 時長 10s 那就是 2*2 是 4 倍，如果再加 performance 就是 8 倍</li></ul>\",\n\n    \"riffabout\": \"關於 Riffusion\",\n    \"riffkeyPlaceholder\": \"Riffusion API 金鑰（可選）\",\n    \"riffserver\": \"Riffusion 接口地址\",\n    \"riffinfo\": \"說明\",\n\n    \"editImage\": \"圖片編輯\",\n    \"editVideo\": \"圖生視頻\",\n    \"moreset\": \"更多參數\",\n    \n  },\n  \"mjset\": {\n    \"server\": \"服務端\",\n    \"about\": \"關於\",\n    \"model\": \"模型\",\n    \"sysname\": \"AI繪圖\"\n  },\n  \"mjtab\": {\n    \"chat\": \"對話\",\n    \"draw\": \"繪畫\",\n    \"drawinfo\": \"AI繪畫 Midjourney引擎\",\n    \"gallery\": \"畫廊\",\n    \"galleryInfo\": \"我的畫廊\"\n  },\n  \"mjchat\": {\n    \"loading\": \"正在載入圖片\",\n    \"openurl\": \"直接打開鏈接\",\n    \"failReason\": \"失敗原因：\",\n    \"reload\": \"重新獲取\",\n    \"progress\": \"進度：\",\n    \"wait\": \"任務已經提交請等待...\",\n    \"reroll\": \"重繪\",\n    \"wait2\": \"任務 {id} 已經提交請等待\",\n    \"redrawEditing\": \"局部重繪編輯\",\n    \"face\": \"換臉\",\n    \"blend\": \"混圖\",\n    \"draw\": \"繪圖\",\n    \"submiting\": \"提交中\",\n    \"submit\": \"提交\",\n    \"wait3\": \"請勿關閉! 圖片生成中...\",\n    \"success\": \"保存成功\",\n    \"successTitle\": \"成功\",\n    \"modlePlaceholder\": \"自定義模型多個用空格隔開，不是必須\",\n    \"myModle\": \"自定義模型\",\n    \"historyCnt\": \"上下文數量\",\n    \"historyToken\": \"更多的上下文會使記憶更精確，但會消耗更多的額度\",\n    \"historyTCnt\": \"回復數\",\n    \"historyTCntInfo\": \"回復數越大 ,越有可能消耗更多的額度\",\n    \"role\": \"角色設定\",\n    \"rolePlaceholder\": \"給你的會話設置一個專屬的角色，不是必須\",\n    \"loading2\": \"正在加載...\",\n    \"loadmore\": \"加載更多\",\n    \"nofind\": \"未能找到\",\n    \"nofind2\": \"相關內容, 你可嘗試以下內容\",\n    \"success2\": \"切換成功！\",\n    \"modelChange\": \"模型切換\",\n    \"search\": \"搜索\",\n    \"searchPlaceholder\": \"GPTs名字、介紹\",\n    \"attr\": \"附件\",\n    \"noproduct\": \"畫廊還沒有您的作品\",\n    \"myGallery\": \"我的畫廊\",\n    \"yourHead\": \"你的頭像\",\n    \"your2Head\": \"明星圖\",\n    \"tipInfo\": \"說明：<li>1 圖片都必須包含臉，否則出不來圖</li> <li>2 “明星圖”可以先用mj繪畫製作出來</li> <li>3 “明星圖”其實動漫圖也行</li> <li>4 “你的頭像”建議用一寸個人照</li>\",\n    \"placeInput\": \"請填寫提示詞！\",\n    \"more5sb\": \"最多上傳5張圖片\",\n    \"exSuccess\": \"導出成功... 請看下載欄\",\n    \"downloadSave\": \"ai繪畫.txt\",\n    \"noproducet\": \"暫時沒成熟作品\",\n    \"imgBili\": \"圖片比例\",\n    \"imagEx\": \"作品圖片鏈接導出\",\n    \"prompt\": \"提示詞\",\n    \"imgCYes\": \"含有墊圖\",\n    \"imgCUpload\": \"自傳墊圖\",\n    \"imgCInfo\": \"墊圖說明：<br/> 1.墊圖可使用自己的圖片作為基礎，讓MJ來繪圖<br/> 2.可以使用多張墊圖 最多5張， 單張圖片不超過1M<br/>\",\n    \"imgCadd\": \"+添加\",\n    \"del\": \"刪除\",\n    \"img2text\": \"圖生文\",\n    \"img2textinfo\": \"不知如何寫提示詞？用圖生文試試！<br/>提交圖片，出提示詞\",\n    \"traning\": \"翻譯中...\",\n    \"imgcreate\": \"生成圖片\",\n    \"imginfo\": \"其他參數：  <li>1 --no 忽略 --no car 圖中不出現車 </li><li>2 --seed 可先獲取種子 --seed 123456 </li> <li>3 --chaos 10 混合(範圍：0-100)</li> <li>4 --tile 碎片化 </li> \",\n    \"tStyle\": \"風格\",\n    \"tView\": \"視角\",\n    \"tShot\": \"人物鏡頭\",\n    \"tLight\": \"燈光\",\n    \"tQuality\": \"畫質\",\n    \"tStyles\": \"藝術程度\",\n    \"version\": \"版本\",\n    \"size\": \"尺寸\",\n    \"blendInfo\": \"說明： <li>1 合成至少2張圖片</li> <li>2 最多可傳6張圖</li> \",\n    \"blendStart\": \"開始合成\",\n    \"no2add\": \"請勿重複添加圖片\",\n    \"add2more\": \"請添加兩張以上圖片\",\n    \"no1m\": \"圖片大小不能超過1M\",\n    \"imgExt\": \"圖片僅支持jpg,gif,png,jpeg格式\",\n    \"setSync\": \"同步Midjourney和Suno\",\n    \"addGPTS\": \"新增 GPTs\",\n    \"addPlaceholder\": \"將 GPTs 的 gid 貼這裡 也可直接貼 GPTs 的鏈接\",\n    \"gidError\": \"未找到有效的 gid，请重新填寫\",\n    \"success3\": \"新增 GPTs 成功！\"\n  },\n\tdraw: {\n\t\tqualityList: {\n\t\t\tgeneral: \"一般\",\n\t\t\tclear: \"清晰\",\n\t\t\thd: \"高清\",\n\t\t\tultraHd: \"超高清\",\n\t\t},\n\t\tstyleList: {\n\t\t\tcyberpunk: \"賽博朋克\",\n\t\t\tstar: \"星際\",\n\t\t\tanime: \"動漫\",\n\t\t\tjapaneseComicsManga: \"日本漫畫\",\n\t\t\tinkWashPaintingStyle: \"水墨畫風格\",\n\t\t\toriginal: \"原創\",\n\t\t\tlandscape: \"風景畫\",\n\t\t\tillustration: \"插畫\",\n\t\t\tmanga: \"漫畫\",\n\t\t\tmodernOrganic: \"現代自然\",\n\t\t\tgenesis: \"創世紀\",\n\t\t\tposterstyle: \"海報風格\",\n\t\t\tsurrealism: \"超現實主義\",\n\t\t\tsketch: \"素描\",\n\t\t\trealism: \"寫實\",\n\t\t\twatercolorPainting: \"水彩畫\",\n\t\t\tcubism: \"立體主義\",\n\t\t\tblackAndWhite: \"黑白\",\n\t\t\tfmPhotography: \"膠片攝影風格\",\n\t\t\tcinematic: \"電影化\",\n\t\t\tclearFacialFeatures: \"清晰的面部特徵\",\n\t\t},\n\t\tviewList: {\n\t\t\twideView: \"寬視角\",\n\t\t\tbirdView: \"鳥瞰視角\",\n\t\t\ttopView: \"頂視角\",\n\t\t\tupview: \"仰視角\",\n\t\t\tfrontView: \"正面視角\",\n\t\t\theadshot: \"頭部特寫\",\n\t\t\tultrawideshot: \"超廣角視角\",\n\t\t\tmediumShot: \"中景\",\n\t\t\tlongShot: \"遠景\",\n\t\t\tdepthOfField: \"景深\",\n\t\t},\n\t\tshotList: {\n\t\t\tfaceShot: \"臉部特寫\",\n\t\t\tbigCloseUp: \"大特寫\",\n\t\t\tcloseUp: \"特寫\",\n\t\t\twaistShot: \"腰部以上\",\n\t\t\tkneeShot: \"膝蓋以上\",\n\t\t\tfullLengthShot: \"全身照\",\n\t\t\textraLongShot: \"極遠景\",\n\t\t},\n\t\tstylesList: {\n\t\t\tstyleLow: \"低強度風格\",\n\t\t\tstyleMed: \"中等強度風格\",\n\t\t\tstyleHigh: \"高強度風格\",\n\t\t\tstyleVeryHigh: \"非常高強度風格\",\n\t\t},\n\t\tlightList: {\n\t\t\tcoldLight: \"冷光\",\n\t\t\twarmLight: \"暖光\",\n\t\t\thardLighting: \"硬光\",\n\t\t\tdramaticLight: \"戲劇性光線\",\n\t\t\treflectionLight: \"反射光\",\n\t\t\tmistyFoggy: \"薄霧\",\n\t\t\tnaturalLight: \"自然光\",\n\t\t\tsunLight: \"陽光\",\n\t\t\tmoody: \"情緒化\",\n\t\t},\n\t\tversionList: {\n\t\t\tmjV6: \"MJ V6\",\n\t\t\tmjV61: \"MJ V6.1\",\n\t\t\tmjV52: \"MJ V5.2\",\n\t\t\tmjV51: \"MJ V5.1\",\n\t\t\tnijiV6: \"Niji V6\",\n\t\t\tnijiV5: \"Niji V5\",\n\t\t\tnijiV4: \"Niji V4\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tbotList: {\n\t\t\tmidjourneyBot: \"Midjourney 機器人\",\n\t\t\tnijiJourney: \"Niji Journey\",\n\t\t},\n\t\tdimensionsList: {\n\t\t\tsquare: \"正方形 (1:1)\",\n\t\t\tportrait: \"肖像 (2:3)\",\n\t\t\tlandscape: \"風景 (3:2)\",\n\t\t},\n\t}\n  ,suno:{\n    \"description\": \"描述模式\",\n    \"custom\": \"專業模式\",\n    \"style\": \"歌曲風格\",\n    \"stylepls\": \"歌曲名稱，例如：流行音樂\",\n    \"emputy\": \"暫無內容\",\n    \"noly\": \"無歌詞\",\n    \"inputly\": \"請輸入歌曲名稱或歌詞\",\n    \"doingly\": \"正在進行中，請稍候。\",\n    \"doingly2\": \"正在獲取歌詞...\",\n    \"title\": \"歌曲名稱\",\n    \"titlepls\": \"歌曲名稱，例如：假期\",\n    \"desc\": \"歌曲描述\",\n    \"descpls\": \"歌曲描述，例如：關於假期的原聲流行音樂\",\n    \"noneedly\": \"無需歌詞\",\n    \"rank\": \"隨機獲取\",\n    \"ly\": \"歌詞\",\n    \"lypls\": \"歌詞：有一定的格式\",\n    \"generate\": \"創作歌曲\",\n    \"generately\": \"生成歌詞\",\n    \"nodata\": \"請先創作才有歌曲列表\",\n\n    \"menu\": \"音樂\",\n    \"menuinfo\": \"Suno 音樂創作\",\n    \"server\": \"Suno API 端點\",\n    \"serverabout\": \"Suno 相關\",\n    \"setOpenKeyPlaceholder\": \"Suno API 的相關KEY；可不填\",\n\n    upMps: '上載音頻',\n    extend: '擴展',\n    extendFrom: '擴展自',\n    extendAt: '擴展始於',\n    fail: '失敗',\n    info: '說明：<br>上載音頻的持續時間必須在6秒到60秒之間'\n\n   }\n   ,video:{\n    \"menu\": \"視頻\",\n    \"menuinfo\": \"Luma及其他視頻創作\",\n    \"descpls\": \"視頻創作描述\",\n    \"lumaabout\": \"關於Luma\",\n    \"lumaserver\": \"Luma API端點\",\n    \"setOpenKeyPlaceholder\": \"Luma API金鑰，選填\",\n    \"generate\": \"生成視頻\",\n    \"nodata\": \"暫無可用視頻，請先生成！\",\n    \"selectimg\": \"選擇圖片\",\n    \"clear\": \"清除\",\n    \"plsInput\": \"請輸入內容！\",\n    \"submitSuccess\": \"提交成功！\",\n    \"process\": \"視頻生成中...\",\n    \"repeat\": \"重新獲取\",\n\n    \"lumainfo\": \"說明：<ul><li>1. Pro 和 relax 演示視頻都有水印的鏈接</li><li>2. Pro 無水印版本需要通過「下載按鈕」得到下載鏈接</li><li>3. Pro 得到的鏈接有時限；請及時保存 MP4 文件到本地</li><li>4. Pro 請在生成後的 30 分鐘內；將 MP4 保存到本地，渠道號也可能被封或者下線</li><li>5. Pro 當下載鏈接無效時會給出帶水印的視頻鏈接</li></ul>\",\n    \"runwayabout\": \"Runway 相關\",\n    \"runwayserver\": \"Runway 接口地址\",\n    \"setOpenKeyPlaceholder2\": \"Runway API 的key, 可不填\",\n    \"endImg\": \"尾幀圖\",\n    \"runwayinfo\": \"說明：<ul><li>1. Runway 圖片與視頻都有有效期</li><li>2. 請在生成視頻後 30 分鐘內將 MP4 保存到本地</li></ul>\",\n    \"nosup\": \"暫不支持\",\n    \"rwgen2\": \"版本: Gen-2, 價格實惠\",\n    \"rwgen3\": \"版本: Gen-3 Alpha\",\n    \"repeat2\":\"Expired.Reget\",\n    \n    rwgen3turbo:'版本: Gen-3 Alpha Turbo',\n    gen3a_turbo_img:'Gen-3 Alpha Turbo 必须带图',\n  },\n  dance:{\n    menu: \"跳舞\",\n    menuinfo: \"使用 Viggle 等創作舞蹈影片。\",\n    character: \"人物角色\",\n    viggleabout: \"關於 Viggle\",\n    viggleserver: \"Viggle API 接口地址\",\n    setOpenKeyPlaceholder: \"Viggle API 的 key，可選填\",\n    info: \"說明：<br>1. 角色圖片最好是全身照片。<br>2. 舞蹈模板影片最好是個人影片，不要是團體舞蹈。\",\n    model: \"模型\",\n    bgw: \"白色背景\",\n    bgg: \"綠色背景\",\n    bgmoban: \"模板背景\",\n    bgrole: \"角色背景\",\n    gring: \"生成中...\",\n    uprolefirst: \"請先上傳角色圖片\",\n    uprolefail: \"上傳失敗\",\n    upvideo: \"+ 上傳模板跳舞影片\",\n    usevideo: \"+ 使用官方模板\",\n    moban: \"跳舞模板\",\n    moban2: \"模板名稱\",\n    use: \"使用\"\n}\n\n}\n"
  },
  {
    "path": "src/main.ts",
    "content": "import { createApp } from 'vue'\nimport App from './App.vue'\nimport { setupI18n } from './locales'\nimport { setupAssets, setupScrollbarStyle } from './plugins'\nimport { setupStore } from './store'\nimport { setupRouter } from './router'\n\nasync function bootstrap() {\n  const app = createApp(App)\n  setupAssets()\n\n  setupScrollbarStyle()\n\n  setupStore(app)\n\n  setupI18n(app)\n\n  await setupRouter(app)\n\n  app.mount('#app')\n}\n\nbootstrap()\n"
  },
  {
    "path": "src/plugins/assets.ts",
    "content": "import 'katex/dist/katex.min.css'\nimport '@/styles/lib/tailwind.css'\nimport '@/styles/lib/highlight.less'\nimport '@/styles/lib/github-markdown.less'\nimport '@/styles/global.less'\n\n/** Tailwind's Preflight Style Override */\nfunction naiveStyleOverride() {\n  const meta = document.createElement('meta')\n  meta.name = 'naive-ui-style'\n  document.head.appendChild(meta)\n}\n\nfunction setupAssets() {\n  naiveStyleOverride()\n}\n\nexport default setupAssets\n"
  },
  {
    "path": "src/plugins/index.ts",
    "content": "import setupAssets from './assets'\nimport setupScrollbarStyle from './scrollbarStyle'\n\nexport { setupAssets, setupScrollbarStyle }\n"
  },
  {
    "path": "src/plugins/scrollbarStyle.ts",
    "content": "import { darkTheme, lightTheme } from 'naive-ui'\n\nconst setupScrollbarStyle = () => {\n  const style = document.createElement('style')\n  const styleContent = `\n    ::-webkit-scrollbar {\n      background-color: transparent;\n      width: ${lightTheme.Scrollbar.common?.scrollbarWidth};\n    }\n    ::-webkit-scrollbar-thumb {\n      background-color: ${lightTheme.Scrollbar.common?.scrollbarColor};\n      border-radius: ${lightTheme.Scrollbar.common?.scrollbarBorderRadius};\n    }\n    html.dark ::-webkit-scrollbar {\n      background-color: transparent;\n      width: ${darkTheme.Scrollbar.common?.scrollbarWidth};\n    }\n    html.dark ::-webkit-scrollbar-thumb {\n      background-color: ${darkTheme.Scrollbar.common?.scrollbarColor};\n      border-radius: ${darkTheme.Scrollbar.common?.scrollbarBorderRadius};\n    }\n  `\n\n  style.innerHTML = styleContent\n  document.head.appendChild(style)\n}\n\nexport default setupScrollbarStyle\n"
  },
  {
    "path": "src/router/index.ts",
    "content": "import type { App } from 'vue'\nimport type { RouteRecordRaw } from 'vue-router'\nimport { createRouter, createWebHashHistory } from 'vue-router'\nimport { setupPageGuard } from './permission'\nimport { ChatLayout } from '@/views/chat/layout'\nimport mjlayout from '@/views/mj/layout.vue'\nimport sunoLayout from '@/views/suno/layout.vue'\nimport lumaLayout from '@/views/luma/layout.vue'\n\nconst routes: RouteRecordRaw[] = [\n  {\n    path: '/',\n    name: 'Root',\n    component: ChatLayout,\n    redirect: '/chat',\n    children: [\n      {\n        path: '/chat/:uuid?',\n        name: 'Chat',\n        component: () => import('@/views/chat/index.vue'),\n      },\n    ],\n  },\n   {\n    path: '/g',\n    name: 'g',\n    component: ChatLayout,\n    redirect: '/g/g-2fkFE8rbu',\n    children: [\n      {\n        path: '/g/:gid',\n        name: 'GPTs',\n        component: () => import('@/views/chat/index.vue'),\n      },\n    ],\n  },\n   {\n    path: '/m',\n    name: 'm',\n    component: ChatLayout,\n    redirect: '/m/gpt-3.5-turbo',\n    children: [\n      {\n        path: '/m/:gid',\n        name: 'Model',\n        component: () => import('@/views/chat/index.vue'),\n      },\n    ],\n  },\n  {\n    path: '/s',\n    name: 's',\n    component: ChatLayout,\n    redirect: '/s/t',\n    children: [\n      {\n        path: '/s/t',\n        name: 'Setting',\n        component: () => import('@/views/chat/index.vue'),\n      },\n    ],\n  },\n\n\n  {\n    path: '/draw',\n    name: 'Rootdraw',\n    component: mjlayout,\n    redirect: '/draw/index',\n    children: [\n      {\n        path: '/draw/:uuid?',\n        name: 'draw',\n        component: () => import('@/views/mj/draw.vue'),\n      },\n    ],\n  },\n\n    {\n    path: '/music',\n    name: 'music',\n    component: sunoLayout,\n    redirect: '/music/index',\n    children: [\n      {\n        path: '/music/:uuid?',\n        name: 'music',\n        component: () => import('@/views/suno/music.vue'),\n      },\n    ],\n\n    \n\n  },\n  {\n    path: '/video',\n    name: 'video',\n    component: lumaLayout,\n    redirect: '/video/index',\n    children: [\n      {\n        path: '/video/:uuid?',\n        name: 'video',\n        component: () => import('@/views/luma/video.vue'),\n      },\n    ],\n  },\n\n  {\n    path: '/dance',\n    name: 'dance',\n    component: lumaLayout,\n    redirect: '/dance/index',\n    children: [\n      {\n        path: '/dance/:uuid?',\n        name: 'dance',\n        component: () => import('@/views/viggle/dance.vue'),\n      },\n    ],\n  },\n\n  {\n    path: '/wav',\n    name: 'wav',\n    component: lumaLayout,\n    redirect: '/wav/index',\n    children: [\n      {\n        path: '/wav/:uuid?',\n        name: 'wav',\n        component: () => import('@/views/wav/wav.vue'),\n      },\n    ],\n  },\n\n  //调试\n  // {\n  //   path: '/mytest',\n  //   name: 'mytest',\n  //   component: () => import('@/views/mj/myTest.vue'),\n  // },\n\n  {\n    path: '/404',\n    name: '404',\n    component: () => import('@/views/exception/404/index.vue'),\n  },\n\n  {\n    path: '/500',\n    name: '500',\n    component: () => import('@/views/exception/500/index.vue'),\n  },\n\n  {\n    path: '/:pathMatch(.*)*',\n    name: 'notFound',\n    redirect: '/404',\n  },\n]\n\nexport const router = createRouter({\n  history: createWebHashHistory(),\n  routes,\n  scrollBehavior: () => ({ left: 0, top: 0 }),\n})\n\nsetupPageGuard(router)\n\nexport async function setupRouter(app: App) {\n  app.use(router)\n  await router.isReady()\n}\n"
  },
  {
    "path": "src/router/permission.ts",
    "content": "import type { Router } from 'vue-router'\nimport { useAuthStoreWithout } from '@/store/modules/auth'\n\nexport function setupPageGuard(router: Router) {\n  router.beforeEach(async (to, from, next) => {\n    const authStore = useAuthStoreWithout()\n    if (!authStore.session) {\n      try {\n        const data = await authStore.getSession()\n        if (String(data.auth) === 'false' && authStore.token)\n          authStore.removeToken()\n        if (to.path === '/500')\n          next({ name: 'Root' })\n        else\n          next()\n      }\n      catch (error) {\n        if (to.path !== '/500')\n          next({ name: '500' })\n        else\n          next()\n      }\n    }\n    else {\n      next()\n    }\n  })\n}\n"
  },
  {
    "path": "src/static/mitf/assets/mj.js",
    "content": "var Sa = function(c, a) {\n  c = c || this;\n  var h = c.window\n    , p = c.document\n    , d = new function() {\n      var e = /^(statics|enumerable|beans|preserve)$/\n        , t = []\n        , n = t.slice\n        , i = Object.create\n        , r = Object.getOwnPropertyDescriptor\n        , s = Object.defineProperty\n        , u = t.forEach || function(_, v) {\n        for (var b = 0, T = this.length; b < T; b++)\n          _.call(v, this[b], b, this)\n      }\n        , o = function(_, v) {\n        for (var b in this)\n          this.hasOwnProperty(b) && _.call(v, this[b], b, this)\n      }\n        , l = Object.assign || function(_) {\n        for (var v = 1, b = arguments.length; v < b; v++) {\n          var T = arguments[v];\n          for (var x in T)\n            T.hasOwnProperty(x) && (_[x] = T[x])\n        }\n        return _\n      }\n        , f = function(_, v, b) {\n        if (_) {\n          var T = r(_, \"length\");\n          (T && typeof T.value == \"number\" ? u : o).call(_, v, b = b || _)\n        }\n        return b\n      };\n      function g(_, v, b, T, x) {\n        var S = {};\n        function I(N, L) {\n          L = L || (L = r(v, N)) && (L.get ? L : L.value),\n          typeof L == \"string\" && L[0] === \"#\" && (L = _[L.substring(1)] || L);\n          var R = typeof L == \"function\", D = L, V = x || R && !L.base ? L && L.get ? N in _ : _[N] : null, z;\n          (!x || !V) && (R && V && (L.base = V),\n          R && T !== !1 && (z = N.match(/^([gs]et|is)(([A-Z])(.*))$/)) && (S[z[3].toLowerCase() + z[4]] = z[2]),\n          (!D || R || !D.get || typeof D.get != \"function\" || !y.isPlainObject(D)) && (D = {\n            value: D,\n            writable: !0\n          }),\n          (r(_, N) || {\n            configurable: !0\n          }).configurable && (D.configurable = !0,\n            D.enumerable = b ?? !z),\n            s(_, N, D))\n        }\n        if (v) {\n          for (var m in v)\n            v.hasOwnProperty(m) && !e.test(m) && I(m);\n          for (var m in S) {\n            var w = S[m]\n              , E = _[\"set\" + w]\n              , A = _[\"get\" + w] || E && _[\"is\" + w];\n            A && (T === !0 || A.length === 0) && I(m, {\n              get: A,\n              set: E\n            })\n          }\n        }\n        return _\n      }\n      function y() {\n        for (var _ = 0, v = arguments.length; _ < v; _++) {\n          var b = arguments[_];\n          b && l(this, b)\n        }\n        return this\n      }\n      return g(y, {\n        inject: function(_) {\n          if (_) {\n            var v = _.statics === !0 ? _ : _.statics\n              , b = _.beans\n              , T = _.preserve;\n            v !== _ && g(this.prototype, _, _.enumerable, b, T),\n              g(this, v, null, b, T)\n          }\n          for (var x = 1, S = arguments.length; x < S; x++)\n            this.inject(arguments[x]);\n          return this\n        },\n        extend: function() {\n          for (var _ = this, v, b, T = 0, x, S = arguments.length; T < S && !(v && b); T++)\n            x = arguments[T],\n              v = v || x.initialize,\n              b = b || x.prototype;\n          return v = v || function() {\n            _.apply(this, arguments)\n          }\n            ,\n            b = v.prototype = b || i(this.prototype),\n            s(b, \"constructor\", {\n              value: v,\n              writable: !0,\n              configurable: !0\n            }),\n            g(v, this),\n          arguments.length && this.inject.apply(v, arguments),\n            v.base = _,\n            v\n        }\n      }).inject({\n        enumerable: !1,\n        initialize: y,\n        set: y,\n        inject: function() {\n          for (var _ = 0, v = arguments.length; _ < v; _++) {\n            var b = arguments[_];\n            b && g(this, b, b.enumerable, b.beans, b.preserve)\n          }\n          return this\n        },\n        extend: function() {\n          var _ = i(this);\n          return _.inject.apply(_, arguments)\n        },\n        each: function(_, v) {\n          return f(this, _, v)\n        },\n        clone: function() {\n          return new this.constructor(this)\n        },\n        statics: {\n          set: l,\n          each: f,\n          create: i,\n          define: s,\n          describe: r,\n          clone: function(_) {\n            return l(new _.constructor, _)\n          },\n          isPlainObject: function(_) {\n            var v = _ != null && _.constructor;\n            return v && (v === Object || v === y || v.name === \"Object\")\n          },\n          pick: function(_, v) {\n            return _ !== a ? _ : v\n          },\n          slice: function(_, v, b) {\n            return n.call(_, v, b)\n          }\n        }\n      })\n    }\n  ;\n  d.inject({\n    enumerable: !1,\n    toString: function() {\n      return this._id != null ? (this._class || \"Object\") + (this._name ? \" '\" + this._name + \"'\" : \" @\" + this._id) : \"{ \" + d.each(this, function(e, t) {\n        if (!/^_/.test(t)) {\n          var n = typeof e;\n          this.push(t + \": \" + (n === \"number\" ? k.instance.number(e) : n === \"string\" ? \"'\" + e + \"'\" : e))\n        }\n      }, []).join(\", \") + \" }\"\n    },\n    getClassName: function() {\n      return this._class || \"\"\n    },\n    importJSON: function(e) {\n      return d.importJSON(e, this)\n    },\n    exportJSON: function(e) {\n      return d.exportJSON(this, e)\n    },\n    toJSON: function() {\n      return d.serialize(this)\n    },\n    set: function(e, t) {\n      return e && d.filter(this, e, t, this._prioritize),\n        this\n    }\n  }, {\n    beans: !1,\n    statics: {\n      exports: {},\n      extend: function e() {\n        var t = e.base.apply(this, arguments)\n          , n = t.prototype._class;\n        return n && !d.exports[n] && (d.exports[n] = t),\n          t\n      },\n      equals: function(e, t) {\n        if (e === t)\n          return !0;\n        if (e && e.equals)\n          return e.equals(t);\n        if (t && t.equals)\n          return t.equals(e);\n        if (e && t && typeof e == \"object\" && typeof t == \"object\") {\n          if (Array.isArray(e) && Array.isArray(t)) {\n            var n = e.length;\n            if (n !== t.length)\n              return !1;\n            for (; n--; )\n              if (!d.equals(e[n], t[n]))\n                return !1\n          } else {\n            var i = Object.keys(e)\n              , n = i.length;\n            if (n !== Object.keys(t).length)\n              return !1;\n            for (; n--; ) {\n              var r = i[n];\n              if (!(t.hasOwnProperty(r) && d.equals(e[r], t[r])))\n                return !1\n            }\n          }\n          return !0\n        }\n        return !1\n      },\n      read: function(e, t, n, i) {\n        if (this === d) {\n          var r = this.peek(e, t);\n          return e.__index++,\n            r\n        }\n        var s = this.prototype\n          , u = s._readIndex\n          , o = t || u && e.__index || 0\n          , l = e.length\n          , f = e[o];\n        if (i = i || l - o,\n        f instanceof this || n && n.readNull && f == null && i <= 1)\n          return u && (e.__index = o + 1),\n            f && n && n.clone ? f.clone() : f;\n        if (f = d.create(s),\n        u && (f.__read = !0),\n          f = f.initialize.apply(f, o > 0 || o + i < l ? d.slice(e, o, o + i) : e) || f,\n          u) {\n          e.__index = o + f.__read;\n          var g = f.__filtered;\n          g && (e.__filtered = g,\n            f.__filtered = a),\n            f.__read = a\n        }\n        return f\n      },\n      peek: function(e, t) {\n        return e[e.__index = t || e.__index || 0]\n      },\n      remain: function(e) {\n        return e.length - (e.__index || 0)\n      },\n      readList: function(e, t, n, i) {\n        for (var r = [], s, u = t || 0, o = i ? u + i : e.length, l = u; l < o; l++)\n          r.push(Array.isArray(s = e[l]) ? this.read(s, 0, n) : this.read(e, l, n, 1));\n        return r\n      },\n      readNamed: function(e, t, n, i, r) {\n        var s = this.getNamed(e, t)\n          , u = s !== a;\n        if (u) {\n          var o = e.__filtered;\n          if (!o) {\n            var l = this.getSource(e);\n            o = e.__filtered = d.create(l),\n              o.__unfiltered = l\n          }\n          o[t] = a\n        }\n        return this.read(u ? [s] : e, n, i, r)\n      },\n      readSupported: function(e, t) {\n        var n = this.getSource(e)\n          , i = this\n          , r = !1;\n        return n && Object.keys(n).forEach(function(s) {\n          if (s in t) {\n            var u = i.readNamed(e, s);\n            u !== a && (t[s] = u),\n              r = !0\n          }\n        }),\n          r\n      },\n      getSource: function(e) {\n        var t = e.__source;\n        if (t === a) {\n          var n = e.length === 1 && e[0];\n          t = e.__source = n && d.isPlainObject(n) ? n : null\n        }\n        return t\n      },\n      getNamed: function(e, t) {\n        var n = this.getSource(e);\n        if (n)\n          return t ? n[t] : e.__filtered || n\n      },\n      hasNamed: function(e, t) {\n        return !!this.getNamed(e, t)\n      },\n      filter: function(e, t, n, i) {\n        var r;\n        function s(g) {\n          if (!(n && g in n) && !(r && g in r)) {\n            var y = t[g];\n            y !== a && (e[g] = y)\n          }\n        }\n        if (i) {\n          for (var u = {}, o = 0, l, f = i.length; o < f; o++)\n            (l = i[o])in t && (s(l),\n              u[l] = !0);\n          r = u\n        }\n        return Object.keys(t.__unfiltered || t).forEach(s),\n          e\n      },\n      isPlainValue: function(e, t) {\n        return d.isPlainObject(e) || Array.isArray(e) || t && typeof e == \"string\"\n      },\n      serialize: function(e, t, n, i) {\n        t = t || {};\n        var r = !i, s;\n        if (r && (t.formatter = new k(t.precision),\n          i = {\n            length: 0,\n            definitions: {},\n            references: {},\n            add: function(y, _) {\n              var v = \"#\" + y._id\n                , b = this.references[v];\n              if (!b) {\n                this.length++;\n                var T = _.call(y)\n                  , x = y._class;\n                x && T[0] !== x && T.unshift(x),\n                  this.definitions[v] = T,\n                  b = this.references[v] = [v]\n              }\n              return b\n            }\n          }),\n        e && e._serialize) {\n          s = e._serialize(t, i);\n          var u = e._class;\n          u && !e._compactSerialize && (r || !n) && s[0] !== u && s.unshift(u)\n        } else if (Array.isArray(e)) {\n          s = [];\n          for (var o = 0, l = e.length; o < l; o++)\n            s[o] = d.serialize(e[o], t, n, i)\n        } else if (d.isPlainObject(e)) {\n          s = {};\n          for (var f = Object.keys(e), o = 0, l = f.length; o < l; o++) {\n            var g = f[o];\n            s[g] = d.serialize(e[g], t, n, i)\n          }\n        } else\n          typeof e == \"number\" ? s = t.formatter.number(e, t.precision) : s = e;\n        return r && i.length > 0 ? [[\"dictionary\", i.definitions], s] : s\n      },\n      deserialize: function(e, t, n, i, r) {\n        var s = e\n          , u = !n\n          , o = u && e && e.length && e[0][0] === \"dictionary\";\n        if (n = n || {},\n          Array.isArray(e)) {\n          var l = e[0]\n            , f = l === \"dictionary\";\n          if (e.length == 1 && /^#/.test(l))\n            return n.dictionary[l];\n          l = d.exports[l],\n            s = [];\n          for (var g = l ? 1 : 0, y = e.length; g < y; g++)\n            s.push(d.deserialize(e[g], t, n, f, o));\n          if (l) {\n            var _ = s;\n            t ? s = t(l, _, u || r) : s = new l(_)\n          }\n        } else if (d.isPlainObject(e)) {\n          s = {},\n          i && (n.dictionary = s);\n          for (var v in e)\n            s[v] = d.deserialize(e[v], t, n)\n        }\n        return o ? s[1] : s\n      },\n      exportJSON: function(e, t) {\n        var n = d.serialize(e, t);\n        return t && t.asString == !1 ? n : JSON.stringify(n)\n      },\n      importJSON: function(e, t) {\n        return d.deserialize(typeof e == \"string\" ? JSON.parse(e) : e, function(n, i, r) {\n          var s = r && t && t.constructor === n\n            , u = s ? t : d.create(n.prototype);\n          if (i.length === 1 && u instanceof oe && (s || !(u instanceof ct))) {\n            var o = i[0];\n            d.isPlainObject(o) && (o.insert = !1,\n            s && (i = i.concat([oe.INSERT])))\n          }\n          return (s ? u.set : n).apply(u, i),\n          s && (t = null),\n            u\n        })\n      },\n      push: function(e, t) {\n        var n = t.length;\n        if (n < 4096)\n          e.push.apply(e, t);\n        else {\n          var i = e.length;\n          e.length += n;\n          for (var r = 0; r < n; r++)\n            e[i + r] = t[r]\n        }\n        return e\n      },\n      splice: function(e, t, n, i) {\n        var r = t && t.length\n          , s = n === a;\n        n = s ? e.length : n,\n        n > e.length && (n = e.length);\n        for (var u = 0; u < r; u++)\n          t[u]._index = n + u;\n        if (s)\n          return d.push(e, t),\n            [];\n        var o = [n, i];\n        t && d.push(o, t);\n        for (var l = e.splice.apply(e, o), u = 0, f = l.length; u < f; u++)\n          l[u]._index = a;\n        for (var u = n + r, f = e.length; u < f; u++)\n          e[u]._index = u;\n        return l\n      },\n      capitalize: function(e) {\n        return e.replace(/\\b[a-z]/g, function(t) {\n          return t.toUpperCase()\n        })\n      },\n      camelize: function(e) {\n        return e.replace(/-(.)/g, function(t, n) {\n          return n.toUpperCase()\n        })\n      },\n      hyphenate: function(e) {\n        return e.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase()\n      }\n    }\n  });\n  var M = {\n    on: function(e, t) {\n      if (typeof e != \"string\")\n        d.each(e, function(s, u) {\n          this.on(u, s)\n        }, this);\n      else {\n        var n = this._eventTypes\n          , i = n && n[e]\n          , r = this._callbacks = this._callbacks || {};\n        r = r[e] = r[e] || [],\n        r.indexOf(t) === -1 && (r.push(t),\n        i && i.install && r.length === 1 && i.install.call(this, e))\n      }\n      return this\n    },\n    off: function(e, t) {\n      if (typeof e != \"string\") {\n        d.each(e, function(u, o) {\n          this.off(o, u)\n        }, this);\n        return\n      }\n      var n = this._eventTypes, i = n && n[e], r = this._callbacks && this._callbacks[e], s;\n      return r && (!t || (s = r.indexOf(t)) !== -1 && r.length === 1 ? (i && i.uninstall && i.uninstall.call(this, e),\n        delete this._callbacks[e]) : s !== -1 && r.splice(s, 1)),\n        this\n    },\n    once: function(e, t) {\n      return this.on(e, function n() {\n        t.apply(this, arguments),\n          this.off(e, n)\n      })\n    },\n    emit: function(e, t) {\n      var n = this._callbacks && this._callbacks[e];\n      if (!n)\n        return !1;\n      var i = d.slice(arguments, 1)\n        , r = t && t.target && !t.currentTarget;\n      n = n.slice(),\n      r && (t.currentTarget = this);\n      for (var s = 0, u = n.length; s < u; s++)\n        if (n[s].apply(this, i) == !1) {\n          t && t.stop && t.stop();\n          break\n        }\n      return r && delete t.currentTarget,\n        !0\n    },\n    responds: function(e) {\n      return !!(this._callbacks && this._callbacks[e])\n    },\n    attach: \"#on\",\n    detach: \"#off\",\n    fire: \"#emit\",\n    _installEvents: function(e) {\n      var t = this._eventTypes\n        , n = this._callbacks\n        , i = e ? \"install\" : \"uninstall\";\n      if (t) {\n        for (var r in n)\n          if (n[r].length > 0) {\n            var s = t[r]\n              , u = s && s[i];\n            u && u.call(this, r)\n          }\n      }\n    },\n    statics: {\n      inject: function e(t) {\n        var n = t._events;\n        if (n) {\n          var i = {};\n          d.each(n, function(r, s) {\n            var u = typeof r == \"string\"\n              , o = u ? r : s\n              , l = d.capitalize(o)\n              , f = o.substring(2).toLowerCase();\n            i[f] = u ? {} : r,\n              o = \"_\" + o,\n              t[\"get\" + l] = function() {\n                return this[o]\n              }\n              ,\n              t[\"set\" + l] = function(g) {\n                var y = this[o];\n                y && this.off(f, y),\n                g && this.on(f, g),\n                  this[o] = g\n              }\n          }),\n            t._eventTypes = i\n        }\n        return e.base.apply(this, arguments)\n      }\n    }\n  }\n    , F = d.extend({\n    _class: \"PaperScope\",\n    initialize: function e() {\n      ae = this,\n        this.settings = new d({\n          applyMatrix: !0,\n          insertItems: !0,\n          handleSize: 4,\n          hitTolerance: 0\n        }),\n        this.project = null,\n        this.projects = [],\n        this.tools = [],\n        this._id = e._id++,\n        e._scopes[this._id] = this;\n      var t = e.prototype;\n      if (!this.support) {\n        var n = Je.getContext(1, 1) || {};\n        t.support = {\n          nativeDash: \"setLineDash\"in n || \"mozDash\"in n,\n          nativeBlendModes: nn.nativeModes\n        },\n          Je.release(n)\n      }\n      if (!this.agent) {\n        var i = c.navigator.userAgent.toLowerCase()\n          , r = (/(darwin|win|mac|linux|freebsd|sunos)/.exec(i) || [])[0]\n          , s = r === \"darwin\" ? \"mac\" : r\n          , u = t.agent = t.browser = {\n          platform: s\n        };\n        s && (u[s] = !0),\n          i.replace(/(opera|chrome|safari|webkit|firefox|msie|trident|atom|node|jsdom)\\/?\\s*([.\\d]+)(?:.*version\\/([.\\d]+))?(?:.*rv\\:v?([.\\d]+))?/g, function(o, l, f, g, y) {\n            if (!u.chrome) {\n              var _ = l === \"opera\" ? g : /^(node|trident)$/.test(l) ? y : f;\n              u.version = _,\n                u.versionNumber = parseFloat(_),\n                l = {\n                  trident: \"msie\",\n                  jsdom: \"node\"\n                }[l] || l,\n                u.name = l,\n                u[l] = !0\n            }\n          }),\n        u.chrome && delete u.webkit,\n        u.atom && delete u.chrome\n      }\n    },\n    version: \"0.12.17\",\n    getView: function() {\n      var e = this.project;\n      return e && e._view\n    },\n    getPaper: function() {\n      return this\n    },\n    execute: function(e, t) {},\n    install: function(e) {\n      var t = this;\n      d.each([\"project\", \"view\", \"tool\"], function(i) {\n        d.define(e, i, {\n          configurable: !0,\n          get: function() {\n            return t[i]\n          }\n        })\n      });\n      for (var n in this)\n        !/^_/.test(n) && this[n] && (e[n] = this[n])\n    },\n    setup: function(e) {\n      return h.paper = this,\n        this.project = new ye(e),\n        this\n    },\n    createCanvas: function(e, t) {\n      return Je.getCanvas(e, t)\n    },\n    activate: function() {\n      ae = this\n    },\n    clear: function() {\n      for (var e = this.projects, t = this.tools, n = e.length - 1; n >= 0; n--)\n        e[n].remove();\n      for (var n = t.length - 1; n >= 0; n--)\n        t[n].remove()\n    },\n    remove: function() {\n      this.clear(),\n        delete F._scopes[this._id]\n    },\n    statics: new function() {\n      function e(t) {\n        return t += \"Attribute\",\n          function(n, i) {\n            return n[t](i) || n[t](\"data-paper-\" + i)\n          }\n      }\n      return {\n        _scopes: {},\n        _id: 0,\n        get: function(t) {\n          return this._scopes[t] || null\n        },\n        getAttribute: e(\"get\"),\n        hasAttribute: e(\"has\")\n      }\n    }\n  })\n    , Z = d.extend(M, {\n    initialize: function(e) {\n      this._scope = ae,\n        this._index = this._scope[this._list].push(this) - 1,\n      (e || !this._scope[this._reference]) && this.activate()\n    },\n    activate: function() {\n      if (!this._scope)\n        return !1;\n      var e = this._scope[this._reference];\n      return e && e !== this && e.emit(\"deactivate\"),\n        this._scope[this._reference] = this,\n        this.emit(\"activate\", e),\n        !0\n    },\n    isActive: function() {\n      return this._scope[this._reference] === this\n    },\n    remove: function() {\n      return this._index == null ? !1 : (d.splice(this._scope[this._list], null, this._index, 1),\n      this._scope[this._reference] == this && (this._scope[this._reference] = null),\n        this._scope = null,\n        !0)\n    },\n    getView: function() {\n      return this._scope.getView()\n    }\n  })\n    , q = {\n    findItemBoundsCollisions: function(e, t, n) {\n      function i(u) {\n        for (var o = new Array(u.length), l = 0; l < u.length; l++) {\n          var f = u[l].getBounds();\n          o[l] = [f.left, f.top, f.right, f.bottom]\n        }\n        return o\n      }\n      var r = i(e)\n        , s = !t || t === e ? r : i(t);\n      return this.findBoundsCollisions(r, s, n || 0)\n    },\n    findCurveBoundsCollisions: function(e, t, n, i) {\n      function r(_) {\n        for (var v = Math.min, b = Math.max, T = new Array(_.length), x = 0; x < _.length; x++) {\n          var S = _[x];\n          T[x] = [v(S[0], S[2], S[4], S[6]), v(S[1], S[3], S[5], S[7]), b(S[0], S[2], S[4], S[6]), b(S[1], S[3], S[5], S[7])]\n        }\n        return T\n      }\n      var s = r(e)\n        , u = !t || t === e ? s : r(t);\n      if (i) {\n        for (var o = this.findBoundsCollisions(s, u, n || 0, !1, !0), l = this.findBoundsCollisions(s, u, n || 0, !0, !0), f = [], g = 0, y = o.length; g < y; g++)\n          f[g] = {\n            hor: o[g],\n            ver: l[g]\n          };\n        return f\n      }\n      return this.findBoundsCollisions(s, u, n || 0)\n    },\n    findBoundsCollisions: function(e, t, n, i, r) {\n      var s = !t || e === t\n        , u = s ? e : e.concat(t)\n        , o = e.length\n        , l = u.length;\n      function f(se, ue, Ie) {\n        for (var Ee = 0, de = se.length; Ee < de; ) {\n          var ve = de + Ee >>> 1;\n          u[se[ve]][ue] < Ie ? Ee = ve + 1 : de = ve\n        }\n        return Ee - 1\n      }\n      for (var g = i ? 1 : 0, y = g + 2, _ = i ? 0 : 1, v = _ + 2, b = new Array(l), T = 0; T < l; T++)\n        b[T] = T;\n      b.sort(function(se, ue) {\n        return u[se][g] - u[ue][g]\n      });\n      for (var x = [], S = new Array(o), T = 0; T < l; T++) {\n        var I = b[T]\n          , m = u[I]\n          , w = s ? I : I - o\n          , E = I < o\n          , A = s || !E\n          , N = E ? [] : null;\n        if (x.length) {\n          var L = f(x, y, m[g] - n) + 1;\n          if (x.splice(0, L),\n          s && r) {\n            N = N.concat(x);\n            for (var R = 0; R < x.length; R++) {\n              var D = x[R];\n              S[D].push(w)\n            }\n          } else\n            for (var V = m[v], z = m[_], R = 0; R < x.length; R++) {\n              var D = x[R]\n                , G = u[D]\n                , H = D < o\n                , K = s || D >= o;\n              (r || (E && K || A && H) && V >= G[_] - n && z <= G[v] + n) && (E && K && N.push(s ? D : D - o),\n              A && H && S[D].push(w))\n            }\n        }\n        if (E && (e === t && N.push(I),\n          S[I] = N),\n          x.length) {\n          var $ = m[y]\n            , W = f(x, y, $);\n          x.splice(W + 1, 0, I)\n        } else\n          x.push(I)\n      }\n      for (var T = 0; T < S.length; T++) {\n        var te = S[T];\n        te && te.sort(function(ue, Ie) {\n          return ue - Ie\n        })\n      }\n      return S\n    }\n  }\n    , k = d.extend({\n    initialize: function(e) {\n      this.precision = d.pick(e, 5),\n        this.multiplier = Math.pow(10, this.precision)\n    },\n    number: function(e) {\n      return this.precision < 16 ? Math.round(e * this.multiplier) / this.multiplier : e\n    },\n    pair: function(e, t, n) {\n      return this.number(e) + (n || \",\") + this.number(t)\n    },\n    point: function(e, t) {\n      return this.number(e.x) + (t || \",\") + this.number(e.y)\n    },\n    size: function(e, t) {\n      return this.number(e.width) + (t || \",\") + this.number(e.height)\n    },\n    rectangle: function(e, t) {\n      return this.point(e, t) + (t || \",\") + this.size(e, t)\n    }\n  });\n  k.instance = new k;\n  var O = new function() {\n    var e = [[.5773502691896257], [0, .7745966692414834], [.33998104358485626, .8611363115940526], [0, .5384693101056831, .906179845938664], [.2386191860831969, .6612093864662645, .932469514203152], [0, .4058451513773972, .7415311855993945, .9491079123427585], [.1834346424956498, .525532409916329, .7966664774136267, .9602898564975363], [0, .3242534234038089, .6133714327005904, .8360311073266358, .9681602395076261], [.14887433898163122, .4333953941292472, .6794095682990244, .8650633666889845, .9739065285171717], [0, .26954315595234496, .5190961292068118, .7301520055740494, .8870625997680953, .978228658146057], [.1252334085114689, .3678314989981802, .5873179542866175, .7699026741943047, .9041172563704749, .9815606342467192], [0, .2304583159551348, .44849275103644687, .6423493394403402, .8015780907333099, .9175983992229779, .9841830547185881], [.10805494870734367, .31911236892788974, .5152486363581541, .6872929048116855, .827201315069765, .9284348836635735, .9862838086968123], [0, .20119409399743451, .3941513470775634, .5709721726085388, .7244177313601701, .8482065834104272, .937273392400706, .9879925180204854], [.09501250983763744, .2816035507792589, .45801677765722737, .6178762444026438, .755404408355003, .8656312023878318, .9445750230732326, .9894009349916499]]\n      , t = [[1], [.8888888888888888, .5555555555555556], [.6521451548625461, .34785484513745385], [.5688888888888889, .47862867049936647, .23692688505618908], [.46791393457269104, .3607615730481386, .17132449237917036], [.4179591836734694, .3818300505051189, .27970539148927664, .1294849661688697], [.362683783378362, .31370664587788727, .22238103445337448, .10122853629037626], [.3302393550012598, .31234707704000286, .26061069640293544, .1806481606948574, .08127438836157441], [.29552422471475287, .26926671930999635, .21908636251598204, .1494513491505806, .06667134430868814], [.2729250867779006, .26280454451024665, .23319376459199048, .18629021092773426, .1255803694649046, .05566856711617366], [.24914704581340277, .2334925365383548, .20316742672306592, .16007832854334622, .10693932599531843, .04717533638651183], [.2325515532308739, .22628318026289723, .2078160475368885, .17814598076194574, .13887351021978725, .09212149983772845, .04048400476531588], [.2152638534631578, .2051984637212956, .18553839747793782, .15720316715819355, .12151857068790319, .08015808715976021, .03511946033175186], [.2025782419255613, .19843148532711158, .1861610000155622, .16626920581699392, .13957067792615432, .10715922046717194, .07036604748810812, .03075324199611727], [.1894506104550685, .18260341504492358, .16915651939500254, .14959598881657674, .12462897125553388, .09515851168249279, .062253523938647894, .027152459411754096]]\n      , n = Math.abs\n      , i = Math.sqrt\n      , r = Math.pow\n      , s = Math.log2 || function(y) {\n      return Math.log(y) * Math.LOG2E\n    }\n      , u = 1e-12\n      , o = 112e-18;\n    function l(y, _, v) {\n      return y < _ ? _ : y > v ? v : y\n    }\n    function f(y, _, v) {\n      function b(L) {\n        var R = L * 134217729\n          , D = L - R\n          , V = D + R\n          , z = L - V;\n        return [V, z]\n      }\n      var T = _ * _ - y * v\n        , x = _ * _ + y * v;\n      if (n(T) * 3 < x) {\n        var S = b(y)\n          , I = b(_)\n          , m = b(v)\n          , w = _ * _\n          , E = I[0] * I[0] - w + 2 * I[0] * I[1] + I[1] * I[1]\n          , A = y * v\n          , N = S[0] * m[0] - A + S[0] * m[1] + S[1] * m[0] + S[1] * m[1];\n        T = w - A + (E - N)\n      }\n      return T\n    }\n    function g() {\n      var y = Math.max.apply(Math, arguments);\n      return y && (y < 1e-8 || y > 1e8) ? r(2, -Math.round(s(y))) : 0\n    }\n    return {\n      EPSILON: u,\n      MACHINE_EPSILON: o,\n      CURVETIME_EPSILON: 1e-8,\n      GEOMETRIC_EPSILON: 1e-7,\n      TRIGONOMETRIC_EPSILON: 1e-8,\n      ANGULAR_EPSILON: 1e-5,\n      KAPPA: 4 * (i(2) - 1) / 3,\n      isZero: function(y) {\n        return y >= -u && y <= u\n      },\n      isMachineZero: function(y) {\n        return y >= -o && y <= o\n      },\n      clamp: l,\n      integrate: function(y, _, v, b) {\n        for (var T = e[b - 2], x = t[b - 2], S = (v - _) * .5, I = S + _, m = 0, w = b + 1 >> 1, E = b & 1 ? x[m++] * y(I) : 0; m < w; ) {\n          var A = S * T[m];\n          E += x[m++] * (y(I + A) + y(I - A))\n        }\n        return S * E\n      },\n      findRoot: function(y, _, v, b, T, x, S) {\n        for (var I = 0; I < x; I++) {\n          var m = y(v)\n            , w = m / _(v)\n            , E = v - w;\n          if (n(w) < S) {\n            v = E;\n            break\n          }\n          m > 0 ? (T = v,\n            v = E <= b ? (b + T) * .5 : E) : (b = v,\n            v = E >= T ? (b + T) * .5 : E)\n        }\n        return l(v, b, T)\n      },\n      solveQuadratic: function(y, _, v, b, T, x) {\n        var S, I = 1 / 0;\n        if (n(y) < u) {\n          if (n(_) < u)\n            return n(v) < u ? -1 : 0;\n          S = -v / _\n        } else {\n          _ *= -.5;\n          var m = f(y, _, v);\n          if (m && n(m) < o) {\n            var w = g(n(y), n(_), n(v));\n            w && (y *= w,\n              _ *= w,\n              v *= w,\n              m = f(y, _, v))\n          }\n          if (m >= -o) {\n            var E = m < 0 ? 0 : i(m)\n              , A = _ + (_ < 0 ? -E : E);\n            A === 0 ? (S = v / y,\n              I = -S) : (S = A / y,\n              I = v / A)\n          }\n        }\n        var N = 0\n          , L = T == null\n          , R = T - u\n          , D = x + u;\n        return isFinite(S) && (L || S > R && S < D) && (b[N++] = L ? S : l(S, T, x)),\n        I !== S && isFinite(I) && (L || I > R && I < D) && (b[N++] = L ? I : l(I, T, x)),\n          N\n      },\n      solveCubic: function(y, _, v, b, T, x, S) {\n        var I = g(n(y), n(_), n(v), n(b)), m, w, E, A, N;\n        I && (y *= I,\n          _ *= I,\n          v *= I,\n          b *= I);\n        function L(W) {\n          m = W;\n          var te = y * m;\n          w = te + _,\n            E = w * m + v,\n            A = (te + w) * m + E,\n            N = E * m + b\n        }\n        if (n(y) < u)\n          y = _,\n            w = v,\n            E = b,\n            m = 1 / 0;\n        else if (n(b) < u)\n          w = _,\n            E = v,\n            m = 0;\n        else {\n          L(-(_ / y) / 3);\n          var R = N / y\n            , D = r(n(R), 1 / 3)\n            , V = R < 0 ? -1 : 1\n            , z = -A / y\n            , G = z > 0 ? 1.324717957244746 * Math.max(D, i(z)) : D\n            , H = m - V * G;\n          if (H !== m) {\n            do\n              L(H),\n                H = A === 0 ? m : m - N / A / (1 + o);\n            while (V * H > V * m);\n            n(y) * m * m > n(b / m) && (E = -b / m,\n              w = (E - v) / m)\n          }\n        }\n        var K = O.solveQuadratic(y, w, E, T, x, S)\n          , $ = x == null;\n        return isFinite(m) && (K === 0 || K > 0 && m !== T[0] && m !== T[1]) && ($ || m > x - u && m < S + u) && (T[K++] = $ ? m : l(m, x, S)),\n          K\n      }\n    }\n  }\n    , B = {\n    _id: 1,\n    _pools: {},\n    get: function(e) {\n      if (e) {\n        var t = this._pools[e];\n        return t || (t = this._pools[e] = {\n          _id: 1\n        }),\n          t._id++\n      } else\n        return this._id++\n    }\n  }\n    , C = d.extend({\n    _class: \"Point\",\n    _readIndex: !0,\n    initialize: function(t, n) {\n      var i = typeof t\n        , r = this.__read\n        , s = 0;\n      if (i === \"number\") {\n        var u = typeof n == \"number\";\n        this._set(t, u ? n : t),\n        r && (s = u ? 2 : 1)\n      } else if (i === \"undefined\" || t === null)\n        this._set(0, 0),\n        r && (s = t === null ? 1 : 0);\n      else {\n        var o = i === \"string\" ? t.split(/[\\s,]+/) || [] : t;\n        s = 1,\n          Array.isArray(o) ? this._set(+o[0], +(o.length > 1 ? o[1] : o[0])) : \"x\"in o ? this._set(o.x || 0, o.y || 0) : \"width\"in o ? this._set(o.width || 0, o.height || 0) : \"angle\"in o ? (this._set(o.length || 0, 0),\n            this.setAngle(o.angle || 0)) : (this._set(0, 0),\n            s = 0)\n      }\n      return r && (this.__read = s),\n        this\n    },\n    set: \"#initialize\",\n    _set: function(e, t) {\n      return this.x = e,\n        this.y = t,\n        this\n    },\n    equals: function(e) {\n      return this === e || e && (this.x === e.x && this.y === e.y || Array.isArray(e) && this.x === e[0] && this.y === e[1]) || !1\n    },\n    clone: function() {\n      return new C(this.x,this.y)\n    },\n    toString: function() {\n      var e = k.instance;\n      return \"{ x: \" + e.number(this.x) + \", y: \" + e.number(this.y) + \" }\"\n    },\n    _serialize: function(e) {\n      var t = e.formatter;\n      return [t.number(this.x), t.number(this.y)]\n    },\n    getLength: function() {\n      return Math.sqrt(this.x * this.x + this.y * this.y)\n    },\n    setLength: function(e) {\n      if (this.isZero()) {\n        var t = this._angle || 0;\n        this._set(Math.cos(t) * e, Math.sin(t) * e)\n      } else {\n        var n = e / this.getLength();\n        O.isZero(n) && this.getAngle(),\n          this._set(this.x * n, this.y * n)\n      }\n    },\n    getAngle: function() {\n      return this.getAngleInRadians.apply(this, arguments) * 180 / Math.PI\n    },\n    setAngle: function(e) {\n      this.setAngleInRadians.call(this, e * Math.PI / 180)\n    },\n    getAngleInDegrees: \"#getAngle\",\n    setAngleInDegrees: \"#setAngle\",\n    getAngleInRadians: function() {\n      if (arguments.length) {\n        var e = C.read(arguments)\n          , t = this.getLength() * e.getLength();\n        if (O.isZero(t))\n          return NaN;\n        var n = this.dot(e) / t;\n        return Math.acos(n < -1 ? -1 : n > 1 ? 1 : n)\n      } else\n        return this.isZero() ? this._angle || 0 : this._angle = Math.atan2(this.y, this.x)\n    },\n    setAngleInRadians: function(e) {\n      if (this._angle = e,\n        !this.isZero()) {\n        var t = this.getLength();\n        this._set(Math.cos(e) * t, Math.sin(e) * t)\n      }\n    },\n    getQuadrant: function() {\n      return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3\n    }\n  }, {\n    beans: !1,\n    getDirectedAngle: function() {\n      var e = C.read(arguments);\n      return Math.atan2(this.cross(e), this.dot(e)) * 180 / Math.PI\n    },\n    getDistance: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = t.x - this.x\n        , i = t.y - this.y\n        , r = n * n + i * i\n        , s = d.read(e);\n      return s ? r : Math.sqrt(r)\n    },\n    normalize: function(e) {\n      e === a && (e = 1);\n      var t = this.getLength()\n        , n = t !== 0 ? e / t : 0\n        , i = new C(this.x * n,this.y * n);\n      return n >= 0 && (i._angle = this._angle),\n        i\n    },\n    rotate: function(e, t) {\n      if (e === 0)\n        return this.clone();\n      e = e * Math.PI / 180;\n      var n = t ? this.subtract(t) : this\n        , i = Math.sin(e)\n        , r = Math.cos(e);\n      return n = new C(n.x * r - n.y * i,n.x * i + n.y * r),\n        t ? n.add(t) : n\n    },\n    transform: function(e) {\n      return e ? e._transformPoint(this) : this\n    },\n    add: function() {\n      var e = C.read(arguments);\n      return new C(this.x + e.x,this.y + e.y)\n    },\n    subtract: function() {\n      var e = C.read(arguments);\n      return new C(this.x - e.x,this.y - e.y)\n    },\n    multiply: function() {\n      var e = C.read(arguments);\n      return new C(this.x * e.x,this.y * e.y)\n    },\n    divide: function() {\n      var e = C.read(arguments);\n      return new C(this.x / e.x,this.y / e.y)\n    },\n    modulo: function() {\n      var e = C.read(arguments);\n      return new C(this.x % e.x,this.y % e.y)\n    },\n    negate: function() {\n      return new C(-this.x,-this.y)\n    },\n    isInside: function() {\n      return Y.read(arguments).contains(this)\n    },\n    isClose: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = d.read(e);\n      return this.getDistance(t) <= n\n    },\n    isCollinear: function() {\n      var e = C.read(arguments);\n      return C.isCollinear(this.x, this.y, e.x, e.y)\n    },\n    isColinear: \"#isCollinear\",\n    isOrthogonal: function() {\n      var e = C.read(arguments);\n      return C.isOrthogonal(this.x, this.y, e.x, e.y)\n    },\n    isZero: function() {\n      var e = O.isZero;\n      return e(this.x) && e(this.y)\n    },\n    isNaN: function() {\n      return isNaN(this.x) || isNaN(this.y)\n    },\n    isInQuadrant: function(e) {\n      return this.x * (e > 1 && e < 4 ? -1 : 1) >= 0 && this.y * (e > 2 ? -1 : 1) >= 0\n    },\n    dot: function() {\n      var e = C.read(arguments);\n      return this.x * e.x + this.y * e.y\n    },\n    cross: function() {\n      var e = C.read(arguments);\n      return this.x * e.y - this.y * e.x\n    },\n    project: function() {\n      var e = C.read(arguments)\n        , t = e.isZero() ? 0 : this.dot(e) / e.dot(e);\n      return new C(e.x * t,e.y * t)\n    },\n    statics: {\n      min: function() {\n        var e = arguments\n          , t = C.read(e)\n          , n = C.read(e);\n        return new C(Math.min(t.x, n.x),Math.min(t.y, n.y))\n      },\n      max: function() {\n        var e = arguments\n          , t = C.read(e)\n          , n = C.read(e);\n        return new C(Math.max(t.x, n.x),Math.max(t.y, n.y))\n      },\n      random: function() {\n        return new C(Math.random(),Math.random())\n      },\n      isCollinear: function(e, t, n, i) {\n        return Math.abs(e * i - t * n) <= Math.sqrt((e * e + t * t) * (n * n + i * i)) * 1e-8\n      },\n      isOrthogonal: function(e, t, n, i) {\n        return Math.abs(e * n + t * i) <= Math.sqrt((e * e + t * t) * (n * n + i * i)) * 1e-8\n      }\n    }\n  }, d.each([\"round\", \"ceil\", \"floor\", \"abs\"], function(e) {\n    var t = Math[e];\n    this[e] = function() {\n      return new C(t(this.x),t(this.y))\n    }\n  }, {}))\n    , Q = C.extend({\n    initialize: function(t, n, i, r) {\n      this._x = t,\n        this._y = n,\n        this._owner = i,\n        this._setter = r\n    },\n    _set: function(e, t, n) {\n      return this._x = e,\n        this._y = t,\n      n || this._owner[this._setter](this),\n        this\n    },\n    getX: function() {\n      return this._x\n    },\n    setX: function(e) {\n      this._x = e,\n        this._owner[this._setter](this)\n    },\n    getY: function() {\n      return this._y\n    },\n    setY: function(e) {\n      this._y = e,\n        this._owner[this._setter](this)\n    },\n    isSelected: function() {\n      return !!(this._owner._selection & this._getSelection())\n    },\n    setSelected: function(e) {\n      this._owner._changeSelection(this._getSelection(), e)\n    },\n    _getSelection: function() {\n      return this._setter === \"setPosition\" ? 4 : 0\n    }\n  })\n    , J = d.extend({\n    _class: \"Size\",\n    _readIndex: !0,\n    initialize: function(t, n) {\n      var i = typeof t\n        , r = this.__read\n        , s = 0;\n      if (i === \"number\") {\n        var u = typeof n == \"number\";\n        this._set(t, u ? n : t),\n        r && (s = u ? 2 : 1)\n      } else if (i === \"undefined\" || t === null)\n        this._set(0, 0),\n        r && (s = t === null ? 1 : 0);\n      else {\n        var o = i === \"string\" ? t.split(/[\\s,]+/) || [] : t;\n        s = 1,\n          Array.isArray(o) ? this._set(+o[0], +(o.length > 1 ? o[1] : o[0])) : \"width\"in o ? this._set(o.width || 0, o.height || 0) : \"x\"in o ? this._set(o.x || 0, o.y || 0) : (this._set(0, 0),\n            s = 0)\n      }\n      return r && (this.__read = s),\n        this\n    },\n    set: \"#initialize\",\n    _set: function(e, t) {\n      return this.width = e,\n        this.height = t,\n        this\n    },\n    equals: function(e) {\n      return e === this || e && (this.width === e.width && this.height === e.height || Array.isArray(e) && this.width === e[0] && this.height === e[1]) || !1\n    },\n    clone: function() {\n      return new J(this.width,this.height)\n    },\n    toString: function() {\n      var e = k.instance;\n      return \"{ width: \" + e.number(this.width) + \", height: \" + e.number(this.height) + \" }\"\n    },\n    _serialize: function(e) {\n      var t = e.formatter;\n      return [t.number(this.width), t.number(this.height)]\n    },\n    add: function() {\n      var e = J.read(arguments);\n      return new J(this.width + e.width,this.height + e.height)\n    },\n    subtract: function() {\n      var e = J.read(arguments);\n      return new J(this.width - e.width,this.height - e.height)\n    },\n    multiply: function() {\n      var e = J.read(arguments);\n      return new J(this.width * e.width,this.height * e.height)\n    },\n    divide: function() {\n      var e = J.read(arguments);\n      return new J(this.width / e.width,this.height / e.height)\n    },\n    modulo: function() {\n      var e = J.read(arguments);\n      return new J(this.width % e.width,this.height % e.height)\n    },\n    negate: function() {\n      return new J(-this.width,-this.height)\n    },\n    isZero: function() {\n      var e = O.isZero;\n      return e(this.width) && e(this.height)\n    },\n    isNaN: function() {\n      return isNaN(this.width) || isNaN(this.height)\n    },\n    statics: {\n      min: function(e, t) {\n        return new J(Math.min(e.width, t.width),Math.min(e.height, t.height))\n      },\n      max: function(e, t) {\n        return new J(Math.max(e.width, t.width),Math.max(e.height, t.height))\n      },\n      random: function() {\n        return new J(Math.random(),Math.random())\n      }\n    }\n  }, d.each([\"round\", \"ceil\", \"floor\", \"abs\"], function(e) {\n    var t = Math[e];\n    this[e] = function() {\n      return new J(t(this.width),t(this.height))\n    }\n  }, {}))\n    , ne = J.extend({\n    initialize: function(t, n, i, r) {\n      this._width = t,\n        this._height = n,\n        this._owner = i,\n        this._setter = r\n    },\n    _set: function(e, t, n) {\n      return this._width = e,\n        this._height = t,\n      n || this._owner[this._setter](this),\n        this\n    },\n    getWidth: function() {\n      return this._width\n    },\n    setWidth: function(e) {\n      this._width = e,\n        this._owner[this._setter](this)\n    },\n    getHeight: function() {\n      return this._height\n    },\n    setHeight: function(e) {\n      this._height = e,\n        this._owner[this._setter](this)\n    }\n  })\n    , Y = d.extend({\n    _class: \"Rectangle\",\n    _readIndex: !0,\n    beans: !0,\n    initialize: function(t, n, i, r) {\n      var s = arguments, u = typeof t, o;\n      if (u === \"number\" ? (this._set(t, n, i, r),\n        o = 4) : u === \"undefined\" || t === null ? (this._set(0, 0, 0, 0),\n        o = t === null ? 1 : 0) : s.length === 1 && (Array.isArray(t) ? (this._set.apply(this, t),\n        o = 1) : t.x !== a || t.width !== a ? (this._set(t.x || 0, t.y || 0, t.width || 0, t.height || 0),\n        o = 1) : t.from === a && t.to === a && (this._set(0, 0, 0, 0),\n      d.readSupported(s, this) && (o = 1))),\n      o === a) {\n        var l = C.readNamed(s, \"from\"), f = d.peek(s), g = l.x, y = l.y, _, v;\n        if (f && f.x !== a || d.hasNamed(s, \"to\")) {\n          var b = C.readNamed(s, \"to\");\n          _ = b.x - g,\n            v = b.y - y,\n          _ < 0 && (g = b.x,\n            _ = -_),\n          v < 0 && (y = b.y,\n            v = -v)\n        } else {\n          var T = J.read(s);\n          _ = T.width,\n            v = T.height\n        }\n        this._set(g, y, _, v),\n          o = s.__index\n      }\n      var x = s.__filtered;\n      return x && (this.__filtered = x),\n      this.__read && (this.__read = o),\n        this\n    },\n    set: \"#initialize\",\n    _set: function(e, t, n, i) {\n      return this.x = e,\n        this.y = t,\n        this.width = n,\n        this.height = i,\n        this\n    },\n    clone: function() {\n      return new Y(this.x,this.y,this.width,this.height)\n    },\n    equals: function(e) {\n      var t = d.isPlainValue(e) ? Y.read(arguments) : e;\n      return t === this || t && this.x === t.x && this.y === t.y && this.width === t.width && this.height === t.height || !1\n    },\n    toString: function() {\n      var e = k.instance;\n      return \"{ x: \" + e.number(this.x) + \", y: \" + e.number(this.y) + \", width: \" + e.number(this.width) + \", height: \" + e.number(this.height) + \" }\"\n    },\n    _serialize: function(e) {\n      var t = e.formatter;\n      return [t.number(this.x), t.number(this.y), t.number(this.width), t.number(this.height)]\n    },\n    getPoint: function(e) {\n      var t = e ? C : Q;\n      return new t(this.x,this.y,this,\"setPoint\")\n    },\n    setPoint: function() {\n      var e = C.read(arguments);\n      this.x = e.x,\n        this.y = e.y\n    },\n    getSize: function(e) {\n      var t = e ? J : ne;\n      return new t(this.width,this.height,this,\"setSize\")\n    },\n    _fw: 1,\n    _fh: 1,\n    setSize: function() {\n      var e = J.read(arguments)\n        , t = this._sx\n        , n = this._sy\n        , i = e.width\n        , r = e.height;\n      t && (this.x += (this.width - i) * t),\n      n && (this.y += (this.height - r) * n),\n        this.width = i,\n        this.height = r,\n        this._fw = this._fh = 1\n    },\n    getLeft: function() {\n      return this.x\n    },\n    setLeft: function(e) {\n      if (!this._fw) {\n        var t = e - this.x;\n        this.width -= this._sx === .5 ? t * 2 : t\n      }\n      this.x = e,\n        this._sx = this._fw = 0\n    },\n    getTop: function() {\n      return this.y\n    },\n    setTop: function(e) {\n      if (!this._fh) {\n        var t = e - this.y;\n        this.height -= this._sy === .5 ? t * 2 : t\n      }\n      this.y = e,\n        this._sy = this._fh = 0\n    },\n    getRight: function() {\n      return this.x + this.width\n    },\n    setRight: function(e) {\n      if (!this._fw) {\n        var t = e - this.x;\n        this.width = this._sx === .5 ? t * 2 : t\n      }\n      this.x = e - this.width,\n        this._sx = 1,\n        this._fw = 0\n    },\n    getBottom: function() {\n      return this.y + this.height\n    },\n    setBottom: function(e) {\n      if (!this._fh) {\n        var t = e - this.y;\n        this.height = this._sy === .5 ? t * 2 : t\n      }\n      this.y = e - this.height,\n        this._sy = 1,\n        this._fh = 0\n    },\n    getCenterX: function() {\n      return this.x + this.width / 2\n    },\n    setCenterX: function(e) {\n      this._fw || this._sx === .5 ? this.x = e - this.width / 2 : (this._sx && (this.x += (e - this.x) * 2 * this._sx),\n        this.width = (e - this.x) * 2),\n        this._sx = .5,\n        this._fw = 0\n    },\n    getCenterY: function() {\n      return this.y + this.height / 2\n    },\n    setCenterY: function(e) {\n      this._fh || this._sy === .5 ? this.y = e - this.height / 2 : (this._sy && (this.y += (e - this.y) * 2 * this._sy),\n        this.height = (e - this.y) * 2),\n        this._sy = .5,\n        this._fh = 0\n    },\n    getCenter: function(e) {\n      var t = e ? C : Q;\n      return new t(this.getCenterX(),this.getCenterY(),this,\"setCenter\")\n    },\n    setCenter: function() {\n      var e = C.read(arguments);\n      return this.setCenterX(e.x),\n        this.setCenterY(e.y),\n        this\n    },\n    getArea: function() {\n      return this.width * this.height\n    },\n    isEmpty: function() {\n      return this.width === 0 || this.height === 0\n    },\n    contains: function(e) {\n      return e && e.width !== a || (Array.isArray(e) ? e : arguments).length === 4 ? this._containsRectangle(Y.read(arguments)) : this._containsPoint(C.read(arguments))\n    },\n    _containsPoint: function(e) {\n      var t = e.x\n        , n = e.y;\n      return t >= this.x && n >= this.y && t <= this.x + this.width && n <= this.y + this.height\n    },\n    _containsRectangle: function(e) {\n      var t = e.x\n        , n = e.y;\n      return t >= this.x && n >= this.y && t + e.width <= this.x + this.width && n + e.height <= this.y + this.height\n    },\n    intersects: function() {\n      var e = Y.read(arguments)\n        , t = d.read(arguments) || 0;\n      return e.x + e.width > this.x - t && e.y + e.height > this.y - t && e.x < this.x + this.width + t && e.y < this.y + this.height + t\n    },\n    intersect: function() {\n      var e = Y.read(arguments)\n        , t = Math.max(this.x, e.x)\n        , n = Math.max(this.y, e.y)\n        , i = Math.min(this.x + this.width, e.x + e.width)\n        , r = Math.min(this.y + this.height, e.y + e.height);\n      return new Y(t,n,i - t,r - n)\n    },\n    unite: function() {\n      var e = Y.read(arguments)\n        , t = Math.min(this.x, e.x)\n        , n = Math.min(this.y, e.y)\n        , i = Math.max(this.x + this.width, e.x + e.width)\n        , r = Math.max(this.y + this.height, e.y + e.height);\n      return new Y(t,n,i - t,r - n)\n    },\n    include: function() {\n      var e = C.read(arguments)\n        , t = Math.min(this.x, e.x)\n        , n = Math.min(this.y, e.y)\n        , i = Math.max(this.x + this.width, e.x)\n        , r = Math.max(this.y + this.height, e.y);\n      return new Y(t,n,i - t,r - n)\n    },\n    expand: function() {\n      var e = J.read(arguments)\n        , t = e.width\n        , n = e.height;\n      return new Y(this.x - t / 2,this.y - n / 2,this.width + t,this.height + n)\n    },\n    scale: function(e, t) {\n      return this.expand(this.width * e - this.width, this.height * (t === a ? e : t) - this.height)\n    }\n  }, d.each([[\"Top\", \"Left\"], [\"Top\", \"Right\"], [\"Bottom\", \"Left\"], [\"Bottom\", \"Right\"], [\"Left\", \"Center\"], [\"Top\", \"Center\"], [\"Right\", \"Center\"], [\"Bottom\", \"Center\"]], function(e, t) {\n    var n = e.join(\"\")\n      , i = /^[RL]/.test(n);\n    t >= 4 && (e[1] += i ? \"Y\" : \"X\");\n    var r = e[i ? 0 : 1]\n      , s = e[i ? 1 : 0]\n      , u = \"get\" + r\n      , o = \"get\" + s\n      , l = \"set\" + r\n      , f = \"set\" + s\n      , g = \"get\" + n\n      , y = \"set\" + n;\n    this[g] = function(_) {\n      var v = _ ? C : Q;\n      return new v(this[u](),this[o](),this,y)\n    }\n      ,\n      this[y] = function() {\n        var _ = C.read(arguments);\n        this[l](_.x),\n          this[f](_.y)\n      }\n  }, {\n    beans: !0\n  }))\n    , Me = Y.extend({\n      initialize: function(t, n, i, r, s, u) {\n        this._set(t, n, i, r, !0),\n          this._owner = s,\n          this._setter = u\n      },\n      _set: function(e, t, n, i, r) {\n        return this._x = e,\n          this._y = t,\n          this._width = n,\n          this._height = i,\n        r || this._owner[this._setter](this),\n          this\n      }\n    }, new function() {\n      var e = Y.prototype;\n      return d.each([\"x\", \"y\", \"width\", \"height\"], function(t) {\n        var n = d.capitalize(t)\n          , i = \"_\" + t;\n        this[\"get\" + n] = function() {\n          return this[i]\n        }\n          ,\n          this[\"set\" + n] = function(r) {\n            this[i] = r,\n            this._dontNotify || this._owner[this._setter](this)\n          }\n      }, d.each([\"Point\", \"Size\", \"Center\", \"Left\", \"Top\", \"Right\", \"Bottom\", \"CenterX\", \"CenterY\", \"TopLeft\", \"TopRight\", \"BottomLeft\", \"BottomRight\", \"LeftCenter\", \"TopCenter\", \"RightCenter\", \"BottomCenter\"], function(t) {\n        var n = \"set\" + t;\n        this[n] = function() {\n          this._dontNotify = !0,\n            e[n].apply(this, arguments),\n            this._dontNotify = !1,\n            this._owner[this._setter](this)\n        }\n      }, {\n        isSelected: function() {\n          return !!(this._owner._selection & 2)\n        },\n        setSelected: function(t) {\n          var n = this._owner;\n          n._changeSelection && n._changeSelection(2, t)\n        }\n      }))\n    }\n  )\n    , le = d.extend({\n    _class: \"Matrix\",\n    initialize: function e(t, n) {\n      var i = arguments\n        , r = i.length\n        , s = !0;\n      if (r >= 6 ? this._set.apply(this, i) : r === 1 || r === 2 ? t instanceof e ? this._set(t._a, t._b, t._c, t._d, t._tx, t._ty, n) : Array.isArray(t) ? this._set.apply(this, n ? t.concat([n]) : t) : s = !1 : r ? s = !1 : this.reset(),\n        !s)\n        throw new Error(\"Unsupported matrix parameters\");\n      return this\n    },\n    set: \"#initialize\",\n    _set: function(e, t, n, i, r, s, u) {\n      return this._a = e,\n        this._b = t,\n        this._c = n,\n        this._d = i,\n        this._tx = r,\n        this._ty = s,\n      u || this._changed(),\n        this\n    },\n    _serialize: function(e, t) {\n      return d.serialize(this.getValues(), e, !0, t)\n    },\n    _changed: function() {\n      var e = this._owner;\n      e && (e._applyMatrix ? e.transform(null, !0) : e._changed(25))\n    },\n    clone: function() {\n      return new le(this._a,this._b,this._c,this._d,this._tx,this._ty)\n    },\n    equals: function(e) {\n      return e === this || e && this._a === e._a && this._b === e._b && this._c === e._c && this._d === e._d && this._tx === e._tx && this._ty === e._ty\n    },\n    toString: function() {\n      var e = k.instance;\n      return \"[[\" + [e.number(this._a), e.number(this._c), e.number(this._tx)].join(\", \") + \"], [\" + [e.number(this._b), e.number(this._d), e.number(this._ty)].join(\", \") + \"]]\"\n    },\n    reset: function(e) {\n      return this._a = this._d = 1,\n        this._b = this._c = this._tx = this._ty = 0,\n      e || this._changed(),\n        this\n    },\n    apply: function(e, t) {\n      var n = this._owner;\n      return n ? (n.transform(null, d.pick(e, !0), t),\n        this.isIdentity()) : !1\n    },\n    translate: function() {\n      var e = C.read(arguments)\n        , t = e.x\n        , n = e.y;\n      return this._tx += t * this._a + n * this._c,\n        this._ty += t * this._b + n * this._d,\n        this._changed(),\n        this\n    },\n    scale: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = C.read(e, 0, {\n        readNull: !0\n      });\n      return n && this.translate(n),\n        this._a *= t.x,\n        this._b *= t.x,\n        this._c *= t.y,\n        this._d *= t.y,\n      n && this.translate(n.negate()),\n        this._changed(),\n        this\n    },\n    rotate: function(e) {\n      e *= Math.PI / 180;\n      var t = C.read(arguments, 1)\n        , n = t.x\n        , i = t.y\n        , r = Math.cos(e)\n        , s = Math.sin(e)\n        , u = n - n * r + i * s\n        , o = i - n * s - i * r\n        , l = this._a\n        , f = this._b\n        , g = this._c\n        , y = this._d;\n      return this._a = r * l + s * g,\n        this._b = r * f + s * y,\n        this._c = -s * l + r * g,\n        this._d = -s * f + r * y,\n        this._tx += u * l + o * g,\n        this._ty += u * f + o * y,\n        this._changed(),\n        this\n    },\n    shear: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = C.read(e, 0, {\n        readNull: !0\n      });\n      n && this.translate(n);\n      var i = this._a\n        , r = this._b;\n      return this._a += t.y * this._c,\n        this._b += t.y * this._d,\n        this._c += t.x * i,\n        this._d += t.x * r,\n      n && this.translate(n.negate()),\n        this._changed(),\n        this\n    },\n    skew: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = C.read(e, 0, {\n        readNull: !0\n      })\n        , i = Math.PI / 180\n        , r = new C(Math.tan(t.x * i),Math.tan(t.y * i));\n      return this.shear(r, n)\n    },\n    append: function(e, t) {\n      if (e) {\n        var n = this._a\n          , i = this._b\n          , r = this._c\n          , s = this._d\n          , u = e._a\n          , o = e._c\n          , l = e._b\n          , f = e._d\n          , g = e._tx\n          , y = e._ty;\n        this._a = u * n + l * r,\n          this._c = o * n + f * r,\n          this._b = u * i + l * s,\n          this._d = o * i + f * s,\n          this._tx += g * n + y * r,\n          this._ty += g * i + y * s,\n        t || this._changed()\n      }\n      return this\n    },\n    prepend: function(e, t) {\n      if (e) {\n        var n = this._a\n          , i = this._b\n          , r = this._c\n          , s = this._d\n          , u = this._tx\n          , o = this._ty\n          , l = e._a\n          , f = e._c\n          , g = e._b\n          , y = e._d\n          , _ = e._tx\n          , v = e._ty;\n        this._a = l * n + f * i,\n          this._c = l * r + f * s,\n          this._b = g * n + y * i,\n          this._d = g * r + y * s,\n          this._tx = l * u + f * o + _,\n          this._ty = g * u + y * o + v,\n        t || this._changed()\n      }\n      return this\n    },\n    appended: function(e) {\n      return this.clone().append(e)\n    },\n    prepended: function(e) {\n      return this.clone().prepend(e)\n    },\n    invert: function() {\n      var e = this._a\n        , t = this._b\n        , n = this._c\n        , i = this._d\n        , r = this._tx\n        , s = this._ty\n        , u = e * i - t * n\n        , o = null;\n      return u && !isNaN(u) && isFinite(r) && isFinite(s) && (this._a = i / u,\n        this._b = -t / u,\n        this._c = -n / u,\n        this._d = e / u,\n        this._tx = (n * s - i * r) / u,\n        this._ty = (t * r - e * s) / u,\n        o = this),\n        o\n    },\n    inverted: function() {\n      return this.clone().invert()\n    },\n    concatenate: \"#append\",\n    preConcatenate: \"#prepend\",\n    chain: \"#appended\",\n    _shiftless: function() {\n      return new le(this._a,this._b,this._c,this._d,0,0)\n    },\n    _orNullIfIdentity: function() {\n      return this.isIdentity() ? null : this\n    },\n    isIdentity: function() {\n      return this._a === 1 && this._b === 0 && this._c === 0 && this._d === 1 && this._tx === 0 && this._ty === 0\n    },\n    isInvertible: function() {\n      var e = this._a * this._d - this._c * this._b;\n      return e && !isNaN(e) && isFinite(this._tx) && isFinite(this._ty)\n    },\n    isSingular: function() {\n      return !this.isInvertible()\n    },\n    transform: function(e, t, n) {\n      return arguments.length < 3 ? this._transformPoint(C.read(arguments)) : this._transformCoordinates(e, t, n)\n    },\n    _transformPoint: function(e, t, n) {\n      var i = e.x\n        , r = e.y;\n      return t || (t = new C),\n        t._set(i * this._a + r * this._c + this._tx, i * this._b + r * this._d + this._ty, n)\n    },\n    _transformCoordinates: function(e, t, n) {\n      for (var i = 0, r = 2 * n; i < r; i += 2) {\n        var s = e[i]\n          , u = e[i + 1];\n        t[i] = s * this._a + u * this._c + this._tx,\n          t[i + 1] = s * this._b + u * this._d + this._ty\n      }\n      return t\n    },\n    _transformCorners: function(e) {\n      var t = e.x\n        , n = e.y\n        , i = t + e.width\n        , r = n + e.height\n        , s = [t, n, i, n, i, r, t, r];\n      return this._transformCoordinates(s, s, 4)\n    },\n    _transformBounds: function(e, t, n) {\n      for (var i = this._transformCorners(e), r = i.slice(0, 2), s = r.slice(), u = 2; u < 8; u++) {\n        var o = i[u]\n          , l = u & 1;\n        o < r[l] ? r[l] = o : o > s[l] && (s[l] = o)\n      }\n      return t || (t = new Y),\n        t._set(r[0], r[1], s[0] - r[0], s[1] - r[1], n)\n    },\n    inverseTransform: function() {\n      return this._inverseTransform(C.read(arguments))\n    },\n    _inverseTransform: function(e, t, n) {\n      var i = this._a\n        , r = this._b\n        , s = this._c\n        , u = this._d\n        , o = this._tx\n        , l = this._ty\n        , f = i * u - r * s\n        , g = null;\n      if (f && !isNaN(f) && isFinite(o) && isFinite(l)) {\n        var y = e.x - this._tx\n          , _ = e.y - this._ty;\n        t || (t = new C),\n          g = t._set((y * u - _ * s) / f, (_ * i - y * r) / f, n)\n      }\n      return g\n    },\n    decompose: function() {\n      var e = this._a, t = this._b, n = this._c, i = this._d, r = e * i - t * n, s = Math.sqrt, u = Math.atan2, o = 180 / Math.PI, l, f, g;\n      if (e !== 0 || t !== 0) {\n        var y = s(e * e + t * t);\n        l = Math.acos(e / y) * (t > 0 ? 1 : -1),\n          f = [y, r / y],\n          g = [u(e * n + t * i, y * y), 0]\n      } else if (n !== 0 || i !== 0) {\n        var _ = s(n * n + i * i);\n        l = Math.asin(n / _) * (i > 0 ? 1 : -1),\n          f = [r / _, _],\n          g = [0, u(e * n + t * i, _ * _)]\n      } else\n        l = 0,\n          g = f = [0, 0];\n      return {\n        translation: this.getTranslation(),\n        rotation: l * o,\n        scaling: new C(f),\n        skewing: new C(g[0] * o,g[1] * o)\n      }\n    },\n    getValues: function() {\n      return [this._a, this._b, this._c, this._d, this._tx, this._ty]\n    },\n    getTranslation: function() {\n      return new C(this._tx,this._ty)\n    },\n    getScaling: function() {\n      return this.decompose().scaling\n    },\n    getRotation: function() {\n      return this.decompose().rotation\n    },\n    applyToContext: function(e) {\n      this.isIdentity() || e.transform(this._a, this._b, this._c, this._d, this._tx, this._ty)\n    }\n  }, d.each([\"a\", \"b\", \"c\", \"d\", \"tx\", \"ty\"], function(e) {\n    var t = d.capitalize(e)\n      , n = \"_\" + e;\n    this[\"get\" + t] = function() {\n      return this[n]\n    }\n      ,\n      this[\"set\" + t] = function(i) {\n        this[n] = i,\n          this._changed()\n      }\n  }, {}))\n    , Se = d.extend({\n    _class: \"Line\",\n    initialize: function(t, n, i, r, s) {\n      var u = !1;\n      arguments.length >= 4 ? (this._px = t,\n        this._py = n,\n        this._vx = i,\n        this._vy = r,\n        u = s) : (this._px = t.x,\n        this._py = t.y,\n        this._vx = n.x,\n        this._vy = n.y,\n        u = i),\n      u || (this._vx -= this._px,\n        this._vy -= this._py)\n    },\n    getPoint: function() {\n      return new C(this._px,this._py)\n    },\n    getVector: function() {\n      return new C(this._vx,this._vy)\n    },\n    getLength: function() {\n      return this.getVector().getLength()\n    },\n    intersect: function(e, t) {\n      return Se.intersect(this._px, this._py, this._vx, this._vy, e._px, e._py, e._vx, e._vy, !0, t)\n    },\n    getSide: function(e, t) {\n      return Se.getSide(this._px, this._py, this._vx, this._vy, e.x, e.y, !0, t)\n    },\n    getDistance: function(e) {\n      return Math.abs(this.getSignedDistance(e))\n    },\n    getSignedDistance: function(e) {\n      return Se.getSignedDistance(this._px, this._py, this._vx, this._vy, e.x, e.y, !0)\n    },\n    isCollinear: function(e) {\n      return C.isCollinear(this._vx, this._vy, e._vx, e._vy)\n    },\n    isOrthogonal: function(e) {\n      return C.isOrthogonal(this._vx, this._vy, e._vx, e._vy)\n    },\n    statics: {\n      intersect: function(e, t, n, i, r, s, u, o, l, f) {\n        l || (n -= e,\n          i -= t,\n          u -= r,\n          o -= s);\n        var g = n * o - i * u;\n        if (!O.isMachineZero(g)) {\n          var y = e - r\n            , _ = t - s\n            , v = (u * _ - o * y) / g\n            , b = (n * _ - i * y) / g\n            , T = 1e-12\n            , x = -T\n            , S = 1 + T;\n          if (f || x < v && v < S && x < b && b < S)\n            return f || (v = v <= 0 ? 0 : v >= 1 ? 1 : v),\n              new C(e + v * n,t + v * i)\n        }\n      },\n      getSide: function(e, t, n, i, r, s, u, o) {\n        u || (n -= e,\n          i -= t);\n        var l = r - e\n          , f = s - t\n          , g = l * i - f * n;\n        return !o && O.isMachineZero(g) && (g = (l * n + l * n) / (n * n + i * i),\n        g >= 0 && g <= 1 && (g = 0)),\n          g < 0 ? -1 : g > 0 ? 1 : 0\n      },\n      getSignedDistance: function(e, t, n, i, r, s, u) {\n        return u || (n -= e,\n          i -= t),\n          n === 0 ? i > 0 ? r - e : e - r : i === 0 ? n < 0 ? s - t : t - s : ((r - e) * i - (s - t) * n) / (i > n ? i * Math.sqrt(1 + n * n / (i * i)) : n * Math.sqrt(1 + i * i / (n * n)))\n      },\n      getDistance: function(e, t, n, i, r, s, u) {\n        return Math.abs(Se.getSignedDistance(e, t, n, i, r, s, u))\n      }\n    }\n  })\n    , ye = Z.extend({\n    _class: \"Project\",\n    _list: \"projects\",\n    _reference: \"project\",\n    _compactSerialize: !0,\n    initialize: function(t) {\n      Z.call(this, !0),\n        this._children = [],\n        this._namedChildren = {},\n        this._activeLayer = null,\n        this._currentStyle = new Kt(null,null,this),\n        this._view = Ke.create(this, t || Je.getCanvas(1, 1)),\n        this._selectionItems = {},\n        this._selectionCount = 0,\n        this._updateVersion = 0\n    },\n    _serialize: function(e, t) {\n      return d.serialize(this._children, e, !0, t)\n    },\n    _changed: function(e, t) {\n      if (e & 1) {\n        var n = this._view;\n        n && (n._needsUpdate = !0,\n        !n._requested && n._autoUpdate && n.requestUpdate())\n      }\n      var i = this._changes;\n      if (i && t) {\n        var r = this._changesById\n          , s = t._id\n          , u = r[s];\n        u ? u.flags |= e : i.push(r[s] = {\n          item: t,\n          flags: e\n        })\n      }\n    },\n    clear: function() {\n      for (var e = this._children, t = e.length - 1; t >= 0; t--)\n        e[t].remove()\n    },\n    isEmpty: function() {\n      return !this._children.length\n    },\n    remove: function e() {\n      return e.base.call(this) ? (this._view && this._view.remove(),\n        !0) : !1\n    },\n    getView: function() {\n      return this._view\n    },\n    getCurrentStyle: function() {\n      return this._currentStyle\n    },\n    setCurrentStyle: function(e) {\n      this._currentStyle.set(e)\n    },\n    getIndex: function() {\n      return this._index\n    },\n    getOptions: function() {\n      return this._scope.settings\n    },\n    getLayers: function() {\n      return this._children\n    },\n    getActiveLayer: function() {\n      return this._activeLayer || new ct({\n        project: this,\n        insert: !0\n      })\n    },\n    getSymbolDefinitions: function() {\n      var e = []\n        , t = {};\n      return this.getItems({\n        class: ft,\n        match: function(n) {\n          var i = n._definition\n            , r = i._id;\n          return t[r] || (t[r] = !0,\n            e.push(i)),\n            !1\n        }\n      }),\n        e\n    },\n    getSymbols: \"getSymbolDefinitions\",\n    getSelectedItems: function() {\n      var e = this._selectionItems\n        , t = [];\n      for (var n in e) {\n        var i = e[n]\n          , r = i._selection;\n        r & 1 && i.isInserted() ? t.push(i) : r || this._updateSelection(i)\n      }\n      return t\n    },\n    _updateSelection: function(e) {\n      var t = e._id\n        , n = this._selectionItems;\n      e._selection ? n[t] !== e && (this._selectionCount++,\n        n[t] = e) : n[t] === e && (this._selectionCount--,\n        delete n[t])\n    },\n    selectAll: function() {\n      for (var e = this._children, t = 0, n = e.length; t < n; t++)\n        e[t].setFullySelected(!0)\n    },\n    deselectAll: function() {\n      var e = this._selectionItems;\n      for (var t in e)\n        e[t].setFullySelected(!1)\n    },\n    addLayer: function(e) {\n      return this.insertLayer(a, e)\n    },\n    insertLayer: function(e, t) {\n      if (t instanceof ct) {\n        t._remove(!1, !0),\n          d.splice(this._children, [t], e, 0),\n          t._setProject(this, !0);\n        var n = t._name;\n        n && t.setName(n),\n        this._changes && t._changed(5),\n        this._activeLayer || (this._activeLayer = t)\n      } else\n        t = null;\n      return t\n    },\n    _insertItem: function(e, t, n) {\n      return t = this.insertLayer(e, t) || (this._activeLayer || this._insertItem(a, new ct(oe.NO_INSERT), !0)).insertChild(e, t),\n      n && t.activate && t.activate(),\n        t\n    },\n    getItems: function(e) {\n      return oe._getItems(this, e)\n    },\n    getItem: function(e) {\n      return oe._getItems(this, e, null, null, !0)[0] || null\n    },\n    importJSON: function(e) {\n      this.activate();\n      var t = this._activeLayer;\n      return d.importJSON(e, t && t.isEmpty() && t)\n    },\n    removeOn: function(e) {\n      var t = this._removeSets;\n      if (t) {\n        e === \"mouseup\" && (t.mousedrag = null);\n        var n = t[e];\n        if (n) {\n          for (var i in n) {\n            var r = n[i];\n            for (var s in t) {\n              var u = t[s];\n              u && u != n && delete u[r._id]\n            }\n            r.remove()\n          }\n          t[e] = null\n        }\n      }\n    },\n    draw: function(e, t, n) {\n      this._updateVersion++,\n        e.save(),\n        t.applyToContext(e);\n      for (var i = this._children, r = new d({\n        offset: new C(0,0),\n        pixelRatio: n,\n        viewMatrix: t.isIdentity() ? null : t,\n        matrices: [new le],\n        updateMatrix: !0\n      }), s = 0, u = i.length; s < u; s++)\n        i[s].draw(e, r);\n      if (e.restore(),\n      this._selectionCount > 0) {\n        e.save(),\n          e.strokeWidth = 1;\n        var o = this._selectionItems\n          , l = this._scope.settings.handleSize\n          , f = this._updateVersion;\n        for (var g in o)\n          o[g]._drawSelection(e, t, l, o, f);\n        e.restore()\n      }\n    }\n  })\n    , oe = d.extend(M, {\n      statics: {\n        extend: function e(t) {\n          return t._serializeFields && (t._serializeFields = d.set({}, this.prototype._serializeFields, t._serializeFields)),\n            e.base.apply(this, arguments)\n        },\n        INSERT: {\n          insert: !0\n        },\n        NO_INSERT: {\n          insert: !1\n        }\n      },\n      _class: \"Item\",\n      _name: null,\n      _applyMatrix: !0,\n      _canApplyMatrix: !0,\n      _canScaleStroke: !1,\n      _pivot: null,\n      _visible: !0,\n      _blendMode: \"normal\",\n      _opacity: 1,\n      _locked: !1,\n      _guide: !1,\n      _clipMask: !1,\n      _selection: 0,\n      _selectBounds: !0,\n      _selectChildren: !1,\n      _serializeFields: {\n        name: null,\n        applyMatrix: null,\n        matrix: new le,\n        pivot: null,\n        visible: !0,\n        blendMode: \"normal\",\n        opacity: 1,\n        locked: !1,\n        guide: !1,\n        clipMask: !1,\n        selected: !1,\n        data: {}\n      },\n      _prioritize: [\"applyMatrix\"]\n    }, new function() {\n      var e = [\"onMouseDown\", \"onMouseUp\", \"onMouseDrag\", \"onClick\", \"onDoubleClick\", \"onMouseMove\", \"onMouseEnter\", \"onMouseLeave\"];\n      return d.each(e, function(t) {\n        this._events[t] = {\n          install: function(n) {\n            this.getView()._countItemEvent(n, 1)\n          },\n          uninstall: function(n) {\n            this.getView()._countItemEvent(n, -1)\n          }\n        }\n      }, {\n        _events: {\n          onFrame: {\n            install: function() {\n              this.getView()._animateItem(this, !0)\n            },\n            uninstall: function() {\n              this.getView()._animateItem(this, !1)\n            }\n          },\n          onLoad: {},\n          onError: {}\n        },\n        statics: {\n          _itemHandlers: e\n        }\n      })\n    }\n    , {\n      initialize: function() {},\n      _initialize: function(e, t) {\n        var n = e && d.isPlainObject(e)\n          , i = n && e.internal === !0\n          , r = this._matrix = new le\n          , s = n && e.project || ae.project\n          , u = ae.settings;\n        return this._id = i ? null : B.get(),\n          this._parent = this._index = null,\n          this._applyMatrix = this._canApplyMatrix && u.applyMatrix,\n        t && r.translate(t),\n          r._owner = this,\n          this._style = new Kt(s._currentStyle,this,s),\n          i || n && e.insert == !1 || !u.insertItems && !(n && e.insert == !0) ? this._setProject(s) : (n && e.parent || s)._insertItem(a, this, !0),\n        n && e !== oe.NO_INSERT && e !== oe.INSERT && this.set(e, {\n          internal: !0,\n          insert: !0,\n          project: !0,\n          parent: !0\n        }),\n          n\n      },\n      _serialize: function(e, t) {\n        var n = {}\n          , i = this;\n        function r(s) {\n          for (var u in s) {\n            var o = i[u];\n            d.equals(o, u === \"leading\" ? s.fontSize * 1.2 : s[u]) || (n[u] = d.serialize(o, e, u !== \"data\", t))\n          }\n        }\n        return r(this._serializeFields),\n        this instanceof We || r(this._style._defaults),\n          [this._class, n]\n      },\n      _changed: function(e) {\n        var t = this._symbol\n          , n = this._parent || t\n          , i = this._project;\n        e & 8 && (this._bounds = this._position = this._decomposed = a),\n        e & 16 && (this._globalMatrix = a),\n        n && e & 72 && oe._clearBoundsCache(n),\n        e & 2 && oe._clearBoundsCache(this),\n        i && i._changed(e, this),\n        t && t._changed(e)\n      },\n      getId: function() {\n        return this._id\n      },\n      getName: function() {\n        return this._name\n      },\n      setName: function(e) {\n        if (this._name && this._removeNamed(),\n        e === +e + \"\")\n          throw new Error(\"Names consisting only of numbers are not supported.\");\n        var t = this._getOwner();\n        if (e && t) {\n          var n = t._children\n            , i = t._namedChildren;\n          (i[e] = i[e] || []).push(this),\n          e in n || (n[e] = this)\n        }\n        this._name = e || a,\n          this._changed(256)\n      },\n      getStyle: function() {\n        return this._style\n      },\n      setStyle: function(e) {\n        this.getStyle().set(e)\n      }\n    }, d.each([\"locked\", \"visible\", \"blendMode\", \"opacity\", \"guide\"], function(e) {\n      var t = d.capitalize(e)\n        , n = \"_\" + e\n        , i = {\n        locked: 256,\n        visible: 265\n      };\n      this[\"get\" + t] = function() {\n        return this[n]\n      }\n        ,\n        this[\"set\" + t] = function(r) {\n          r != this[n] && (this[n] = r,\n            this._changed(i[e] || 257))\n        }\n    }, {}), {\n      beans: !0,\n      getSelection: function() {\n        return this._selection\n      },\n      setSelection: function(e) {\n        if (e !== this._selection) {\n          this._selection = e;\n          var t = this._project;\n          t && (t._updateSelection(this),\n            this._changed(257))\n        }\n      },\n      _changeSelection: function(e, t) {\n        var n = this._selection;\n        this.setSelection(t ? n | e : n & ~e)\n      },\n      isSelected: function() {\n        if (this._selectChildren) {\n          for (var e = this._children, t = 0, n = e.length; t < n; t++)\n            if (e[t].isSelected())\n              return !0\n        }\n        return !!(this._selection & 1)\n      },\n      setSelected: function(e) {\n        if (this._selectChildren)\n          for (var t = this._children, n = 0, i = t.length; n < i; n++)\n            t[n].setSelected(e);\n        this._changeSelection(1, e)\n      },\n      isFullySelected: function() {\n        var e = this._children\n          , t = !!(this._selection & 1);\n        if (e && t) {\n          for (var n = 0, i = e.length; n < i; n++)\n            if (!e[n].isFullySelected())\n              return !1;\n          return !0\n        }\n        return t\n      },\n      setFullySelected: function(e) {\n        var t = this._children;\n        if (t)\n          for (var n = 0, i = t.length; n < i; n++)\n            t[n].setFullySelected(e);\n        this._changeSelection(1, e)\n      },\n      isClipMask: function() {\n        return this._clipMask\n      },\n      setClipMask: function(e) {\n        this._clipMask != (e = !!e) && (this._clipMask = e,\n        e && (this.setFillColor(null),\n          this.setStrokeColor(null)),\n          this._changed(257),\n        this._parent && this._parent._changed(2048))\n      },\n      getData: function() {\n        return this._data || (this._data = {}),\n          this._data\n      },\n      setData: function(e) {\n        this._data = e\n      },\n      getPosition: function(e) {\n        var t = e ? C : Q\n          , n = this._position || (this._position = this._getPositionFromBounds());\n        return new t(n.x,n.y,this,\"setPosition\")\n      },\n      setPosition: function() {\n        this.translate(C.read(arguments).subtract(this.getPosition(!0)))\n      },\n      _getPositionFromBounds: function(e) {\n        return this._pivot ? this._matrix._transformPoint(this._pivot) : (e || this.getBounds()).getCenter(!0)\n      },\n      getPivot: function() {\n        var e = this._pivot;\n        return e ? new Q(e.x,e.y,this,\"setPivot\") : null\n      },\n      setPivot: function() {\n        this._pivot = C.read(arguments, 0, {\n          clone: !0,\n          readNull: !0\n        }),\n          this._position = a\n      }\n    }, d.each({\n      getStrokeBounds: {\n        stroke: !0\n      },\n      getHandleBounds: {\n        handle: !0\n      },\n      getInternalBounds: {\n        internal: !0\n      }\n    }, function(e, t) {\n      this[t] = function(n) {\n        return this.getBounds(n, e)\n      }\n    }, {\n      beans: !0,\n      getBounds: function(e, t) {\n        var n = t || e instanceof le\n          , i = d.set({}, n ? t : e, this._boundsOptions);\n        (!i.stroke || this.getStrokeScaling()) && (i.cacheItem = this);\n        var r = this._getCachedBounds(n && e, i).rect;\n        return arguments.length ? r : new Me(r.x,r.y,r.width,r.height,this,\"setBounds\")\n      },\n      setBounds: function() {\n        var e = Y.read(arguments)\n          , t = this.getBounds()\n          , n = this._matrix\n          , i = new le\n          , r = e.getCenter();\n        i.translate(r),\n        (e.width != t.width || e.height != t.height) && (n.isInvertible() || (n.set(n._backup || new le().translate(n.getTranslation())),\n          t = this.getBounds()),\n          i.scale(t.width !== 0 ? e.width / t.width : 0, t.height !== 0 ? e.height / t.height : 0)),\n          r = t.getCenter(),\n          i.translate(-r.x, -r.y),\n          this.transform(i)\n      },\n      _getBounds: function(e, t) {\n        var n = this._children;\n        return !n || !n.length ? new Y : (oe._updateBoundsCache(this, t.cacheItem),\n          oe._getBounds(n, e, t))\n      },\n      _getBoundsCacheKey: function(e, t) {\n        return [e.stroke ? 1 : 0, e.handle ? 1 : 0, t ? 1 : 0].join(\"\")\n      },\n      _getCachedBounds: function(e, t, n) {\n        e = e && e._orNullIfIdentity();\n        var i = t.internal && !n\n          , r = t.cacheItem\n          , s = i ? null : this._matrix._orNullIfIdentity()\n          , u = r && (!e || e.equals(s)) && this._getBoundsCacheKey(t, i)\n          , o = this._bounds;\n        if (oe._updateBoundsCache(this._parent || this._symbol, r),\n        u && o && u in o) {\n          var l = o[u];\n          return {\n            rect: l.rect.clone(),\n            nonscaling: l.nonscaling\n          }\n        }\n        var f = this._getBounds(e || s, t)\n          , g = f.rect || f\n          , y = this._style\n          , _ = f.nonscaling || y.hasStroke() && !y.getStrokeScaling();\n        if (u) {\n          o || (this._bounds = o = {});\n          var l = o[u] = {\n            rect: g.clone(),\n            nonscaling: _,\n            internal: i\n          }\n        }\n        return {\n          rect: g,\n          nonscaling: _\n        }\n      },\n      _getStrokeMatrix: function(e, t) {\n        var n = this.getStrokeScaling() ? null : t && t.internal ? this : this._parent || this._symbol && this._symbol._item\n          , i = n ? n.getViewMatrix().invert() : e;\n        return i && i._shiftless()\n      },\n      statics: {\n        _updateBoundsCache: function(e, t) {\n          if (e && t) {\n            var n = t._id\n              , i = e._boundsCache = e._boundsCache || {\n              ids: {},\n              list: []\n            };\n            i.ids[n] || (i.list.push(t),\n              i.ids[n] = t)\n          }\n        },\n        _clearBoundsCache: function(e) {\n          var t = e._boundsCache;\n          if (t) {\n            e._bounds = e._position = e._boundsCache = a;\n            for (var n = 0, i = t.list, r = i.length; n < r; n++) {\n              var s = i[n];\n              s !== e && (s._bounds = s._position = a,\n              s._boundsCache && oe._clearBoundsCache(s))\n            }\n          }\n        },\n        _getBounds: function(e, t, n) {\n          var i = 1 / 0\n            , r = -i\n            , s = i\n            , u = r\n            , o = !1;\n          n = n || {};\n          for (var l = 0, f = e.length; l < f; l++) {\n            var g = e[l];\n            if (g._visible && !g.isEmpty(!0)) {\n              var y = g._getCachedBounds(t && t.appended(g._matrix), n, !0)\n                , _ = y.rect;\n              i = Math.min(_.x, i),\n                s = Math.min(_.y, s),\n                r = Math.max(_.x + _.width, r),\n                u = Math.max(_.y + _.height, u),\n              y.nonscaling && (o = !0)\n            }\n          }\n          return {\n            rect: isFinite(i) ? new Y(i,s,r - i,u - s) : new Y,\n            nonscaling: o\n          }\n        }\n      }\n    }), {\n      beans: !0,\n      _decompose: function() {\n        return this._applyMatrix ? null : this._decomposed || (this._decomposed = this._matrix.decompose())\n      },\n      getRotation: function() {\n        var e = this._decompose();\n        return e ? e.rotation : 0\n      },\n      setRotation: function(e) {\n        var t = this.getRotation();\n        if (t != null && e != null) {\n          var n = this._decomposed;\n          this.rotate(e - t),\n          n && (n.rotation = e,\n            this._decomposed = n)\n        }\n      },\n      getScaling: function() {\n        var e = this._decompose()\n          , t = e && e.scaling;\n        return new Q(t ? t.x : 1,t ? t.y : 1,this,\"setScaling\")\n      },\n      setScaling: function() {\n        var e = this.getScaling()\n          , t = C.read(arguments, 0, {\n          clone: !0,\n          readNull: !0\n        });\n        if (e && t && !e.equals(t)) {\n          var n = this.getRotation()\n            , i = this._decomposed\n            , r = new le\n            , s = O.isZero;\n          if (s(e.x) || s(e.y))\n            r.translate(i.translation),\n            n && r.rotate(n),\n              r.scale(t.x, t.y),\n              this._matrix.set(r);\n          else {\n            var u = this.getPosition(!0);\n            r.translate(u),\n            n && r.rotate(n),\n              r.scale(t.x / e.x, t.y / e.y),\n            n && r.rotate(-n),\n              r.translate(u.negate()),\n              this.transform(r)\n          }\n          i && (i.scaling = t,\n            this._decomposed = i)\n        }\n      },\n      getMatrix: function() {\n        return this._matrix\n      },\n      setMatrix: function() {\n        var e = this._matrix;\n        e.set.apply(e, arguments)\n      },\n      getGlobalMatrix: function(e) {\n        var t = this._globalMatrix;\n        if (t)\n          for (var n = this._parent, i = []; n; ) {\n            if (!n._globalMatrix) {\n              t = null;\n              for (var r = 0, s = i.length; r < s; r++)\n                i[r]._globalMatrix = null;\n              break\n            }\n            i.push(n),\n              n = n._parent\n          }\n        if (!t) {\n          t = this._globalMatrix = this._matrix.clone();\n          var n = this._parent;\n          n && t.prepend(n.getGlobalMatrix(!0))\n        }\n        return e ? t : t.clone()\n      },\n      getViewMatrix: function() {\n        return this.getGlobalMatrix().prepend(this.getView()._matrix)\n      },\n      getApplyMatrix: function() {\n        return this._applyMatrix\n      },\n      setApplyMatrix: function(e) {\n        (this._applyMatrix = this._canApplyMatrix && !!e) && this.transform(null, !0)\n      },\n      getTransformContent: \"#getApplyMatrix\",\n      setTransformContent: \"#setApplyMatrix\"\n    }, {\n      getProject: function() {\n        return this._project\n      },\n      _setProject: function(e, t) {\n        if (this._project !== e) {\n          this._project && this._installEvents(!1),\n            this._project = e;\n          for (var n = this._children, i = 0, r = n && n.length; i < r; i++)\n            n[i]._setProject(e);\n          t = !0\n        }\n        t && this._installEvents(!0)\n      },\n      getView: function() {\n        return this._project._view\n      },\n      _installEvents: function e(t) {\n        e.base.call(this, t);\n        for (var n = this._children, i = 0, r = n && n.length; i < r; i++)\n          n[i]._installEvents(t)\n      },\n      getLayer: function() {\n        for (var e = this; e = e._parent; )\n          if (e instanceof ct)\n            return e;\n        return null\n      },\n      getParent: function() {\n        return this._parent\n      },\n      setParent: function(e) {\n        return e.addChild(this)\n      },\n      _getOwner: \"#getParent\",\n      getChildren: function() {\n        return this._children\n      },\n      setChildren: function(e) {\n        this.removeChildren(),\n          this.addChildren(e)\n      },\n      getFirstChild: function() {\n        return this._children && this._children[0] || null\n      },\n      getLastChild: function() {\n        return this._children && this._children[this._children.length - 1] || null\n      },\n      getNextSibling: function() {\n        var e = this._getOwner();\n        return e && e._children[this._index + 1] || null\n      },\n      getPreviousSibling: function() {\n        var e = this._getOwner();\n        return e && e._children[this._index - 1] || null\n      },\n      getIndex: function() {\n        return this._index\n      },\n      equals: function(e) {\n        return e === this || e && this._class === e._class && this._style.equals(e._style) && this._matrix.equals(e._matrix) && this._locked === e._locked && this._visible === e._visible && this._blendMode === e._blendMode && this._opacity === e._opacity && this._clipMask === e._clipMask && this._guide === e._guide && this._equals(e) || !1\n      },\n      _equals: function(e) {\n        return d.equals(this._children, e._children)\n      },\n      clone: function(e) {\n        var t = new this.constructor(oe.NO_INSERT)\n          , n = this._children\n          , i = d.pick(e ? e.insert : a, e === a || e === !0)\n          , r = d.pick(e ? e.deep : a, !0);\n        n && t.copyAttributes(this),\n        (!n || r) && t.copyContent(this),\n        n || t.copyAttributes(this),\n        i && t.insertAbove(this);\n        var s = this._name\n          , u = this._parent;\n        if (s && u) {\n          for (var n = u._children, o = s, l = 1; n[s]; )\n            s = o + \" \" + l++;\n          s !== o && t.setName(s)\n        }\n        return t\n      },\n      copyContent: function(e) {\n        for (var t = e._children, n = 0, i = t && t.length; n < i; n++)\n          this.addChild(t[n].clone(!1), !0)\n      },\n      copyAttributes: function(e, t) {\n        this.setStyle(e._style);\n        for (var n = [\"_locked\", \"_visible\", \"_blendMode\", \"_opacity\", \"_clipMask\", \"_guide\"], i = 0, r = n.length; i < r; i++) {\n          var s = n[i];\n          e.hasOwnProperty(s) && (this[s] = e[s])\n        }\n        t || this._matrix.set(e._matrix, !0),\n          this.setApplyMatrix(e._applyMatrix),\n          this.setPivot(e._pivot),\n          this.setSelection(e._selection);\n        var u = e._data\n          , o = e._name;\n        this._data = u ? d.clone(u) : null,\n        o && this.setName(o)\n      },\n      rasterize: function(e, t) {\n        var n, i, r;\n        d.isPlainObject(e) ? (n = e.resolution,\n          i = e.insert,\n          r = e.raster) : (n = e,\n          i = t),\n        r || (r = new Pt(oe.NO_INSERT));\n        var s = this.getStrokeBounds()\n          , u = (n || this.getView().getResolution()) / 72\n          , o = s.getTopLeft().floor()\n          , l = s.getBottomRight().ceil()\n          , f = new J(l.subtract(o))\n          , g = f.multiply(u);\n        if (r.setSize(g, !0),\n          !g.isZero()) {\n          var y = r.getContext(!0)\n            , _ = new le().scale(u).translate(o.negate());\n          y.save(),\n            _.applyToContext(y),\n            this.draw(y, new d({\n              matrices: [_]\n            })),\n            y.restore()\n        }\n        return r._matrix.set(new le().translate(o.add(f.divide(2))).scale(1 / u)),\n        (i === a || i) && r.insertAbove(this),\n          r\n      },\n      contains: function() {\n        var e = this._matrix;\n        return e.isInvertible() && !!this._contains(e._inverseTransform(C.read(arguments)))\n      },\n      _contains: function(e) {\n        var t = this._children;\n        if (t) {\n          for (var n = t.length - 1; n >= 0; n--)\n            if (t[n].contains(e))\n              return !0;\n          return !1\n        }\n        return e.isInside(this.getInternalBounds())\n      },\n      isInside: function() {\n        return Y.read(arguments).contains(this.getBounds())\n      },\n      _asPathItem: function() {\n        return new ke.Rectangle({\n          rectangle: this.getInternalBounds(),\n          matrix: this._matrix,\n          insert: !1\n        })\n      },\n      intersects: function(e, t) {\n        return e instanceof oe ? this._asPathItem().getIntersections(e._asPathItem(), null, t, !0).length > 0 : !1\n      }\n    }, new function() {\n      function e() {\n        var i = arguments;\n        return this._hitTest(C.read(i), qe.getOptions(i))\n      }\n      function t() {\n        var i = arguments\n          , r = C.read(i)\n          , s = qe.getOptions(i)\n          , u = [];\n        return this._hitTest(r, new d({\n          all: u\n        },s)),\n          u\n      }\n      function n(i, r, s, u) {\n        var o = this._children;\n        if (o)\n          for (var l = o.length - 1; l >= 0; l--) {\n            var f = o[l]\n              , g = f !== u && f._hitTest(i, r, s);\n            if (g && !r.all)\n              return g\n          }\n        return null\n      }\n      return ye.inject({\n        hitTest: e,\n        hitTestAll: t,\n        _hitTest: n\n      }),\n        {\n          hitTest: e,\n          hitTestAll: t,\n          _hitTestChildren: n\n        }\n    }\n    , {\n      _hitTest: function(e, t, n) {\n        if (this._locked || !this._visible || this._guide && !t.guides || this.isEmpty())\n          return null;\n        var i = this._matrix\n          , r = n ? n.appended(i) : this.getGlobalMatrix().prepend(this.getView()._matrix)\n          , s = Math.max(t.tolerance, 1e-12)\n          , u = t._tolerancePadding = new J(ke._getStrokePadding(s, i._shiftless().invert()));\n        if (e = i._inverseTransform(e),\n        !e || !this._children && !this.getBounds({\n          internal: !0,\n          stroke: !0,\n          handle: !0\n        }).expand(u.multiply(2))._containsPoint(e))\n          return null;\n        var o = !(t.guides && !this._guide || t.selected && !this.isSelected() || t.type && t.type !== d.hyphenate(this._class) || t.class && !(this instanceof t.class)), l = t.match, f = this, g, y;\n        function _(m) {\n          return m && l && !l(m) && (m = null),\n          m && t.all && t.all.push(m),\n            m\n        }\n        function v(m, w) {\n          var E = w ? g[\"get\" + w]() : f.getPosition();\n          if (e.subtract(E).divide(u).length <= 1)\n            return new qe(m,f,{\n              name: w ? d.hyphenate(w) : m,\n              point: E\n            })\n        }\n        var b = t.position\n          , T = t.center\n          , x = t.bounds;\n        if (o && this._parent && (b || T || x)) {\n          if ((T || x) && (g = this.getInternalBounds()),\n            y = b && v(\"position\") || T && v(\"center\", \"Center\"),\n          !y && x)\n            for (var S = [\"TopLeft\", \"TopRight\", \"BottomLeft\", \"BottomRight\", \"LeftCenter\", \"TopCenter\", \"RightCenter\", \"BottomCenter\"], I = 0; I < 8 && !y; I++)\n              y = v(\"bounds\", S[I]);\n          y = _(y)\n        }\n        return y || (y = this._hitTestChildren(e, t, r) || o && _(this._hitTestSelf(e, t, r, this.getStrokeScaling() ? null : r._shiftless().invert())) || null),\n        y && y.point && (y.point = i.transform(y.point)),\n          y\n      },\n      _hitTestSelf: function(e, t) {\n        if (t.fill && this.hasFill() && this._contains(e))\n          return new qe(\"fill\",this)\n      },\n      matches: function(e, t) {\n        function n(u, o) {\n          for (var l in u)\n            if (u.hasOwnProperty(l)) {\n              var f = u[l]\n                , g = o[l];\n              if (d.isPlainObject(f) && d.isPlainObject(g)) {\n                if (!n(f, g))\n                  return !1\n              } else if (!d.equals(f, g))\n                return !1\n            }\n          return !0\n        }\n        var i = typeof e;\n        if (i === \"object\") {\n          for (var r in e)\n            if (e.hasOwnProperty(r) && !this.matches(r, e[r]))\n              return !1;\n          return !0\n        } else {\n          if (i === \"function\")\n            return e(this);\n          if (e === \"match\")\n            return t(this);\n          var s = /^(empty|editable)$/.test(e) ? this[\"is\" + d.capitalize(e)]() : e === \"type\" ? d.hyphenate(this._class) : this[e];\n          if (e === \"class\") {\n            if (typeof t == \"function\")\n              return this instanceof t;\n            s = this._class\n          }\n          if (typeof t == \"function\")\n            return !!t(s);\n          if (t) {\n            if (t.test)\n              return t.test(s);\n            if (d.isPlainObject(t))\n              return n(t, s)\n          }\n          return d.equals(s, t)\n        }\n      },\n      getItems: function(e) {\n        return oe._getItems(this, e, this._matrix)\n      },\n      getItem: function(e) {\n        return oe._getItems(this, e, this._matrix, null, !0)[0] || null\n      },\n      statics: {\n        _getItems: function e(t, n, i, r, s) {\n          if (!r) {\n            var u = typeof n == \"object\" && n\n              , o = u && u.overlapping\n              , l = u && u.inside\n              , f = o || l\n              , _ = f && Y.read([f]);\n            r = {\n              items: [],\n              recursive: u && u.recursive !== !1,\n              inside: !!l,\n              overlapping: !!o,\n              rect: _,\n              path: o && new ke.Rectangle({\n                rectangle: _,\n                insert: !1\n              })\n            },\n            u && (n = d.filter({}, n, {\n              recursive: !0,\n              inside: !0,\n              overlapping: !0\n            }))\n          }\n          var g = t._children\n            , y = r.items\n            , _ = r.rect;\n          i = _ && (i || new le);\n          for (var v = 0, b = g && g.length; v < b; v++) {\n            var T = g[v]\n              , x = i && i.appended(T._matrix)\n              , S = !0;\n            if (_) {\n              var f = T.getBounds(x);\n              if (!_.intersects(f))\n                continue;\n              _.contains(f) || r.overlapping && (f.contains(_) || r.path.intersects(T, x)) || (S = !1)\n            }\n            if (S && T.matches(n) && (y.push(T),\n              s) || (r.recursive !== !1 && e(T, n, x, r, s),\n            s && y.length > 0))\n              break\n          }\n          return y\n        }\n      }\n    }, {\n      importJSON: function(e) {\n        var t = d.importJSON(e, this);\n        return t !== this ? this.addChild(t) : t\n      },\n      addChild: function(e) {\n        return this.insertChild(a, e)\n      },\n      insertChild: function(e, t) {\n        var n = t ? this.insertChildren(e, [t]) : null;\n        return n && n[0]\n      },\n      addChildren: function(e) {\n        return this.insertChildren(this._children.length, e)\n      },\n      insertChildren: function(e, t) {\n        var n = this._children;\n        if (n && t && t.length > 0) {\n          t = d.slice(t);\n          for (var i = {}, r = t.length - 1; r >= 0; r--) {\n            var s = t[r]\n              , u = s && s._id;\n            !s || i[u] ? t.splice(r, 1) : (s._remove(!1, !0),\n              i[u] = !0)\n          }\n          d.splice(n, t, e, 0);\n          for (var o = this._project, l = o._changes, r = 0, f = t.length; r < f; r++) {\n            var s = t[r]\n              , g = s._name;\n            s._parent = this,\n              s._setProject(o, !0),\n            g && s.setName(g),\n            l && s._changed(5)\n          }\n          this._changed(11)\n        } else\n          t = null;\n        return t\n      },\n      _insertItem: \"#insertChild\",\n      _insertAt: function(e, t) {\n        var n = e && e._getOwner()\n          , i = e !== this && n ? this : null;\n        return i && (i._remove(!1, !0),\n          n._insertItem(e._index + t, i)),\n          i\n      },\n      insertAbove: function(e) {\n        return this._insertAt(e, 1)\n      },\n      insertBelow: function(e) {\n        return this._insertAt(e, 0)\n      },\n      sendToBack: function() {\n        var e = this._getOwner();\n        return e ? e._insertItem(0, this) : null\n      },\n      bringToFront: function() {\n        var e = this._getOwner();\n        return e ? e._insertItem(a, this) : null\n      },\n      appendTop: \"#addChild\",\n      appendBottom: function(e) {\n        return this.insertChild(0, e)\n      },\n      moveAbove: \"#insertAbove\",\n      moveBelow: \"#insertBelow\",\n      addTo: function(e) {\n        return e._insertItem(a, this)\n      },\n      copyTo: function(e) {\n        return this.clone(!1).addTo(e)\n      },\n      reduce: function(e) {\n        var t = this._children;\n        if (t && t.length === 1) {\n          var n = t[0].reduce(e);\n          return this._parent ? (n.insertAbove(this),\n            this.remove()) : n.remove(),\n            n\n        }\n        return this\n      },\n      _removeNamed: function() {\n        var e = this._getOwner();\n        if (e) {\n          var t = e._children\n            , n = e._namedChildren\n            , i = this._name\n            , r = n[i]\n            , s = r ? r.indexOf(this) : -1;\n          s !== -1 && (t[i] == this && delete t[i],\n            r.splice(s, 1),\n            r.length ? t[i] = r[0] : delete n[i])\n        }\n      },\n      _remove: function(e, t) {\n        var n = this._getOwner()\n          , i = this._project\n          , r = this._index;\n        return this._style && this._style._dispose(),\n          n ? (this._name && this._removeNamed(),\n          r != null && (i._activeLayer === this && (i._activeLayer = this.getNextSibling() || this.getPreviousSibling()),\n            d.splice(n._children, null, r, 1)),\n            this._installEvents(!1),\n          e && i._changes && this._changed(5),\n          t && n._changed(11, this),\n            this._parent = null,\n            !0) : !1\n      },\n      remove: function() {\n        return this._remove(!0, !0)\n      },\n      replaceWith: function(e) {\n        var t = e && e.insertBelow(this);\n        return t && this.remove(),\n          t\n      },\n      removeChildren: function(e, t) {\n        if (!this._children)\n          return null;\n        e = e || 0,\n          t = d.pick(t, this._children.length);\n        for (var n = d.splice(this._children, null, e, t - e), i = n.length - 1; i >= 0; i--)\n          n[i]._remove(!0, !1);\n        return n.length > 0 && this._changed(11),\n          n\n      },\n      clear: \"#removeChildren\",\n      reverseChildren: function() {\n        if (this._children) {\n          this._children.reverse();\n          for (var e = 0, t = this._children.length; e < t; e++)\n            this._children[e]._index = e;\n          this._changed(11)\n        }\n      },\n      isEmpty: function(e) {\n        var t = this._children\n          , n = t ? t.length : 0;\n        if (e) {\n          for (var i = 0; i < n; i++)\n            if (!t[i].isEmpty(e))\n              return !1;\n          return !0\n        }\n        return !n\n      },\n      isEditable: function() {\n        for (var e = this; e; ) {\n          if (!e._visible || e._locked)\n            return !1;\n          e = e._parent\n        }\n        return !0\n      },\n      hasFill: function() {\n        return this.getStyle().hasFill()\n      },\n      hasStroke: function() {\n        return this.getStyle().hasStroke()\n      },\n      hasShadow: function() {\n        return this.getStyle().hasShadow()\n      },\n      _getOrder: function(e) {\n        function t(u) {\n          var o = [];\n          do\n            o.unshift(u);\n          while (u = u._parent);\n          return o\n        }\n        for (var n = t(this), i = t(e), r = 0, s = Math.min(n.length, i.length); r < s; r++)\n          if (n[r] != i[r])\n            return n[r]._index < i[r]._index ? 1 : -1;\n        return 0\n      },\n      hasChildren: function() {\n        return this._children && this._children.length > 0\n      },\n      isInserted: function() {\n        return this._parent ? this._parent.isInserted() : !1\n      },\n      isAbove: function(e) {\n        return this._getOrder(e) === -1\n      },\n      isBelow: function(e) {\n        return this._getOrder(e) === 1\n      },\n      isParent: function(e) {\n        return this._parent === e\n      },\n      isChild: function(e) {\n        return e && e._parent === this\n      },\n      isDescendant: function(e) {\n        for (var t = this; t = t._parent; )\n          if (t === e)\n            return !0;\n        return !1\n      },\n      isAncestor: function(e) {\n        return e ? e.isDescendant(this) : !1\n      },\n      isSibling: function(e) {\n        return this._parent === e._parent\n      },\n      isGroupedWith: function(e) {\n        for (var t = this._parent; t; ) {\n          if (t._parent && /^(Group|Layer|CompoundPath)$/.test(t._class) && e.isDescendant(t))\n            return !0;\n          t = t._parent\n        }\n        return !1\n      }\n    }, d.each([\"rotate\", \"scale\", \"shear\", \"skew\"], function(e) {\n      var t = e === \"rotate\";\n      this[e] = function() {\n        var n = arguments\n          , i = (t ? d : C).read(n)\n          , r = C.read(n, 0, {\n          readNull: !0\n        });\n        return this.transform(new le()[e](i, r || this.getPosition(!0)))\n      }\n    }, {\n      translate: function() {\n        var e = new le;\n        return this.transform(e.translate.apply(e, arguments))\n      },\n      transform: function(e, t, n) {\n        var i = this._matrix\n          , r = e && !e.isIdentity()\n          , s = n && this._canApplyMatrix || this._applyMatrix && (r || !i.isIdentity() || t && this._children);\n        if (!r && !s)\n          return this;\n        if (r) {\n          !e.isInvertible() && i.isInvertible() && (i._backup = i.getValues()),\n            i.prepend(e, !0);\n          var u = this._style\n            , o = u.getFillColor(!0)\n            , l = u.getStrokeColor(!0);\n          o && o.transform(e),\n          l && l.transform(e)\n        }\n        if (s && (s = this._transformContent(i, t, n))) {\n          var f = this._pivot;\n          f && i._transformPoint(f, f, !0),\n            i.reset(!0),\n          n && this._canApplyMatrix && (this._applyMatrix = !0)\n        }\n        var g = this._bounds\n          , y = this._position;\n        (r || s) && this._changed(25);\n        var _ = r && g && e.decompose();\n        if (_ && _.skewing.isZero() && _.rotation % 90 === 0) {\n          for (var v in g) {\n            var b = g[v];\n            if (b.nonscaling)\n              delete g[v];\n            else if (s || !b.internal) {\n              var T = b.rect;\n              e._transformBounds(T, T)\n            }\n          }\n          this._bounds = g;\n          var x = g[this._getBoundsCacheKey(this._boundsOptions || {})];\n          x && (this._position = this._getPositionFromBounds(x.rect))\n        } else\n          r && y && this._pivot && (this._position = e._transformPoint(y, y));\n        return this\n      },\n      _transformContent: function(e, t, n) {\n        var i = this._children;\n        if (i) {\n          for (var r = 0, s = i.length; r < s; r++)\n            i[r].transform(e, t, n);\n          return !0\n        }\n      },\n      globalToLocal: function() {\n        return this.getGlobalMatrix(!0)._inverseTransform(C.read(arguments))\n      },\n      localToGlobal: function() {\n        return this.getGlobalMatrix(!0)._transformPoint(C.read(arguments))\n      },\n      parentToLocal: function() {\n        return this._matrix._inverseTransform(C.read(arguments))\n      },\n      localToParent: function() {\n        return this._matrix._transformPoint(C.read(arguments))\n      },\n      fitBounds: function(e, t) {\n        e = Y.read(arguments);\n        var n = this.getBounds()\n          , i = n.height / n.width\n          , r = e.height / e.width\n          , s = (t ? i > r : i < r) ? e.width / n.width : e.height / n.height\n          , u = new Y(new C,new J(n.width * s,n.height * s));\n        u.setCenter(e.getCenter()),\n          this.setBounds(u)\n      }\n    }), {\n      _setStyles: function(e, t, n) {\n        var i = this._style\n          , r = this._matrix;\n        if (i.hasFill() && (e.fillStyle = i.getFillColor().toCanvasStyle(e, r)),\n          i.hasStroke()) {\n          e.strokeStyle = i.getStrokeColor().toCanvasStyle(e, r),\n            e.lineWidth = i.getStrokeWidth();\n          var s = i.getStrokeJoin()\n            , u = i.getStrokeCap()\n            , o = i.getMiterLimit();\n          if (s && (e.lineJoin = s),\n          u && (e.lineCap = u),\n          o && (e.miterLimit = o),\n            ae.support.nativeDash) {\n            var l = i.getDashArray()\n              , f = i.getDashOffset();\n            l && l.length && (\"setLineDash\"in e ? (e.setLineDash(l),\n              e.lineDashOffset = f) : (e.mozDash = l,\n              e.mozDashOffset = f))\n          }\n        }\n        if (i.hasShadow()) {\n          var g = t.pixelRatio || 1\n            , y = n._shiftless().prepend(new le().scale(g, g))\n            , _ = y.transform(new C(i.getShadowBlur(),0))\n            , v = y.transform(this.getShadowOffset());\n          e.shadowColor = i.getShadowColor().toCanvasStyle(e),\n            e.shadowBlur = _.getLength(),\n            e.shadowOffsetX = v.x,\n            e.shadowOffsetY = v.y\n        }\n      },\n      draw: function(e, t, n) {\n        var i = this._updateVersion = this._project._updateVersion;\n        if (!(!this._visible || this._opacity === 0)) {\n          var r = t.matrices\n            , s = t.viewMatrix\n            , u = this._matrix\n            , o = r[r.length - 1].appended(u);\n          if (o.isInvertible()) {\n            s = s ? s.appended(o) : o,\n              r.push(o),\n            t.updateMatrix && (this._globalMatrix = o);\n            var l = this._blendMode, f = O.clamp(this._opacity, 0, 1), g = l === \"normal\", y = nn.nativeModes[l], _ = g && f === 1 || t.dontStart || t.clip || (y || g && f < 1) && this._canComposite(), v = t.pixelRatio || 1, b, T, x;\n            if (!_) {\n              var S = this.getStrokeBounds(s);\n              if (!S.width || !S.height) {\n                r.pop();\n                return\n              }\n              x = t.offset,\n                T = t.offset = S.getTopLeft().floor(),\n                b = e,\n                e = Je.getContext(S.getSize().ceil().add(1).multiply(v)),\n              v !== 1 && e.scale(v, v)\n            }\n            e.save();\n            var I = n ? n.appended(u) : this._canScaleStroke && !this.getStrokeScaling(!0) && s\n              , m = !_ && t.clipItem\n              , w = !I || m;\n            if (_ ? (e.globalAlpha = f,\n            y && (e.globalCompositeOperation = l)) : w && e.translate(-T.x, -T.y),\n            w && (_ ? u : s).applyToContext(e),\n            m && t.clipItem.draw(e, t.extend({\n              clip: !0\n            })),\n              I) {\n              e.setTransform(v, 0, 0, v, 0, 0);\n              var E = t.offset;\n              E && e.translate(-E.x, -E.y)\n            }\n            this._draw(e, t, s, I),\n              e.restore(),\n              r.pop(),\n            t.clip && !t.dontFinish && e.clip(this.getFillRule()),\n            _ || (nn.process(l, e, b, f, T.subtract(x).multiply(v)),\n              Je.release(e),\n              t.offset = x)\n          }\n        }\n      },\n      _isUpdated: function(e) {\n        var t = this._parent;\n        if (t instanceof ot)\n          return t._isUpdated(e);\n        var n = this._updateVersion === e;\n        return !n && t && t._visible && t._isUpdated(e) && (this._updateVersion = e,\n          n = !0),\n          n\n      },\n      _drawSelection: function(e, t, n, i, r) {\n        var s = this._selection\n          , u = s & 1\n          , o = s & 2 || u && this._selectBounds\n          , l = s & 4;\n        if (this._drawSelected || (u = !1),\n        (u || o || l) && this._isUpdated(r)) {\n          var f, g = this.getSelectedColor(!0) || (f = this.getLayer()) && f.getSelectedColor(!0), y = t.appended(this.getGlobalMatrix(!0)), _ = n / 2;\n          if (e.strokeStyle = e.fillStyle = g ? g.toCanvasStyle(e) : \"#009dec\",\n          u && this._drawSelected(e, y, i),\n            l) {\n            var v = this.getPosition(!0)\n              , b = this._parent\n              , T = b ? b.localToGlobal(v) : v\n              , x = T.x\n              , S = T.y;\n            e.beginPath(),\n              e.arc(x, S, _, 0, Math.PI * 2, !0),\n              e.stroke();\n            for (var I = [[0, -1], [1, 0], [0, 1], [-1, 0]], m = _, w = n + 1, E = 0; E < 4; E++) {\n              var A = I[E]\n                , N = A[0]\n                , L = A[1];\n              e.moveTo(x + N * m, S + L * m),\n                e.lineTo(x + N * w, S + L * w),\n                e.stroke()\n            }\n          }\n          if (o) {\n            var R = y._transformCorners(this.getInternalBounds());\n            e.beginPath();\n            for (var E = 0; E < 8; E++)\n              e[E ? \"lineTo\" : \"moveTo\"](R[E], R[++E]);\n            e.closePath(),\n              e.stroke();\n            for (var E = 0; E < 8; E++)\n              e.fillRect(R[E] - _, R[++E] - _, n, n)\n          }\n        }\n      },\n      _canComposite: function() {\n        return !1\n      }\n    }, d.each([\"down\", \"drag\", \"up\", \"move\"], function(e) {\n      this[\"removeOn\" + d.capitalize(e)] = function() {\n        var t = {};\n        return t[e] = !0,\n          this.removeOn(t)\n      }\n    }, {\n      removeOn: function(e) {\n        for (var t in e)\n          if (e[t]) {\n            var n = \"mouse\" + t\n              , i = this._project\n              , r = i._removeSets = i._removeSets || {};\n            r[n] = r[n] || {},\n              r[n][this._id] = this\n          }\n        return this\n      }\n    }), {\n      tween: function(e, t, n) {\n        n || (n = t,\n          t = e,\n          e = null,\n        n || (n = t,\n          t = null));\n        var i = n && n.easing\n          , r = n && n.start\n          , s = n != null && (typeof n == \"number\" ? n : n.duration)\n          , u = new Sn(this,e,t,s,i,r);\n        function o(l) {\n          u._handleFrame(l.time * 1e3),\n          u.running || this.off(\"frame\", o)\n        }\n        return s && this.on(\"frame\", o),\n          u\n      },\n      tweenTo: function(e, t) {\n        return this.tween(null, e, t)\n      },\n      tweenFrom: function(e, t) {\n        return this.tween(e, null, t)\n      }\n    })\n    , We = oe.extend({\n    _class: \"Group\",\n    _selectBounds: !1,\n    _selectChildren: !0,\n    _serializeFields: {\n      children: []\n    },\n    initialize: function(t) {\n      this._children = [],\n        this._namedChildren = {},\n      this._initialize(t) || this.addChildren(Array.isArray(t) ? t : arguments)\n    },\n    _changed: function e(t) {\n      e.base.call(this, t),\n      t & 2050 && (this._clipItem = a)\n    },\n    _getClipItem: function() {\n      var e = this._clipItem;\n      if (e === a) {\n        e = null;\n        for (var t = this._children, n = 0, i = t.length; n < i; n++)\n          if (t[n]._clipMask) {\n            e = t[n];\n            break\n          }\n        this._clipItem = e\n      }\n      return e\n    },\n    isClipped: function() {\n      return !!this._getClipItem()\n    },\n    setClipped: function(e) {\n      var t = this.getFirstChild();\n      t && t.setClipMask(e)\n    },\n    _getBounds: function e(t, n) {\n      var i = this._getClipItem();\n      return i ? i._getCachedBounds(i._matrix.prepended(t), d.set({}, n, {\n        stroke: !1\n      })) : e.base.call(this, t, n)\n    },\n    _hitTestChildren: function e(t, n, i) {\n      var r = this._getClipItem();\n      return (!r || r.contains(t)) && e.base.call(this, t, n, i, r)\n    },\n    _draw: function(e, t) {\n      var n = t.clip\n        , i = !n && this._getClipItem();\n      t = t.extend({\n        clipItem: i,\n        clip: !1\n      }),\n        n ? (e.beginPath(),\n          t.dontStart = t.dontFinish = !0) : i && i.draw(e, t.extend({\n          clip: !0\n        }));\n      for (var r = this._children, s = 0, u = r.length; s < u; s++) {\n        var o = r[s];\n        o !== i && o.draw(e, t)\n      }\n    }\n  })\n    , ct = We.extend({\n    _class: \"Layer\",\n    initialize: function() {\n      We.apply(this, arguments)\n    },\n    _getOwner: function() {\n      return this._parent || this._index != null && this._project\n    },\n    isInserted: function e() {\n      return this._parent ? e.base.call(this) : this._index != null\n    },\n    activate: function() {\n      this._project._activeLayer = this\n    },\n    _hitTestSelf: function() {}\n  })\n    , je = oe.extend({\n      _class: \"Shape\",\n      _applyMatrix: !1,\n      _canApplyMatrix: !1,\n      _canScaleStroke: !0,\n      _serializeFields: {\n        type: null,\n        size: null,\n        radius: null\n      },\n      initialize: function(t, n) {\n        this._initialize(t, n)\n      },\n      _equals: function(e) {\n        return this._type === e._type && this._size.equals(e._size) && d.equals(this._radius, e._radius)\n      },\n      copyContent: function(e) {\n        this.setType(e._type),\n          this.setSize(e._size),\n          this.setRadius(e._radius)\n      },\n      getType: function() {\n        return this._type\n      },\n      setType: function(e) {\n        this._type = e\n      },\n      getShape: \"#getType\",\n      setShape: \"#setType\",\n      getSize: function() {\n        var e = this._size;\n        return new ne(e.width,e.height,this,\"setSize\")\n      },\n      setSize: function() {\n        var e = J.read(arguments);\n        if (!this._size)\n          this._size = e.clone();\n        else if (!this._size.equals(e)) {\n          var t = this._type\n            , n = e.width\n            , i = e.height;\n          t === \"rectangle\" ? this._radius.set(J.min(this._radius, e.divide(2).abs())) : t === \"circle\" ? (n = i = (n + i) / 2,\n            this._radius = n / 2) : t === \"ellipse\" && this._radius._set(n / 2, i / 2),\n            this._size._set(n, i),\n            this._changed(9)\n        }\n      },\n      getRadius: function() {\n        var e = this._radius;\n        return this._type === \"circle\" ? e : new ne(e.width,e.height,this,\"setRadius\")\n      },\n      setRadius: function(e) {\n        var t = this._type;\n        if (t === \"circle\") {\n          if (e === this._radius)\n            return;\n          var n = e * 2;\n          this._radius = e,\n            this._size._set(n, n)\n        } else if (e = J.read(arguments),\n          !this._radius)\n          this._radius = e.clone();\n        else {\n          if (this._radius.equals(e))\n            return;\n          if (this._radius.set(e),\n          t === \"rectangle\") {\n            var n = J.max(this._size, e.multiply(2));\n            this._size.set(n)\n          } else\n            t === \"ellipse\" && this._size._set(e.width * 2, e.height * 2)\n        }\n        this._changed(9)\n      },\n      isEmpty: function() {\n        return !1\n      },\n      toPath: function(e) {\n        var t = new ke[d.capitalize(this._type)]({\n          center: new C,\n          size: this._size,\n          radius: this._radius,\n          insert: !1\n        });\n        return t.copyAttributes(this),\n        ae.settings.applyMatrix && t.setApplyMatrix(!0),\n        (e === a || e) && t.insertAbove(this),\n          t\n      },\n      toShape: \"#clone\",\n      _asPathItem: function() {\n        return this.toPath(!1)\n      },\n      _draw: function(e, t, n, i) {\n        var r = this._style\n          , s = r.hasFill()\n          , u = r.hasStroke()\n          , o = t.dontFinish || t.clip\n          , l = !i;\n        if (s || u || o) {\n          var f = this._type\n            , g = this._radius\n            , y = f === \"circle\";\n          if (t.dontStart || e.beginPath(),\n          l && y)\n            e.arc(0, 0, g, 0, Math.PI * 2, !0);\n          else {\n            var _ = y ? g : g.width\n              , v = y ? g : g.height\n              , b = this._size\n              , T = b.width\n              , x = b.height;\n            if (l && f === \"rectangle\" && _ === 0 && v === 0)\n              e.rect(-T / 2, -x / 2, T, x);\n            else {\n              var S = T / 2\n                , I = x / 2\n                , m = 1 - .5522847498307936\n                , w = _ * m\n                , E = v * m\n                , A = [-S, -I + v, -S, -I + E, -S + w, -I, -S + _, -I, S - _, -I, S - w, -I, S, -I + E, S, -I + v, S, I - v, S, I - E, S - w, I, S - _, I, -S + _, I, -S + w, I, -S, I - E, -S, I - v];\n              i && i.transform(A, A, 32),\n                e.moveTo(A[0], A[1]),\n                e.bezierCurveTo(A[2], A[3], A[4], A[5], A[6], A[7]),\n              S !== _ && e.lineTo(A[8], A[9]),\n                e.bezierCurveTo(A[10], A[11], A[12], A[13], A[14], A[15]),\n              I !== v && e.lineTo(A[16], A[17]),\n                e.bezierCurveTo(A[18], A[19], A[20], A[21], A[22], A[23]),\n              S !== _ && e.lineTo(A[24], A[25]),\n                e.bezierCurveTo(A[26], A[27], A[28], A[29], A[30], A[31])\n            }\n          }\n          e.closePath()\n        }\n        !o && (s || u) && (this._setStyles(e, t, n),\n        s && (e.fill(r.getFillRule()),\n          e.shadowColor = \"rgba(0,0,0,0)\"),\n        u && e.stroke())\n      },\n      _canComposite: function() {\n        return !(this.hasFill() && this.hasStroke())\n      },\n      _getBounds: function(e, t) {\n        var n = new Y(this._size).setCenter(0, 0)\n          , i = this._style\n          , r = t.stroke && i.hasStroke() && i.getStrokeWidth();\n        return e && (n = e._transformBounds(n)),\n          r ? n.expand(ke._getStrokePadding(r, this._getStrokeMatrix(e, t))) : n\n      }\n    }, new function() {\n      function e(n, i, r) {\n        var s = n._radius;\n        if (!s.isZero())\n          for (var u = n._size.divide(2), o = 1; o <= 4; o++) {\n            var l = new C(o > 1 && o < 4 ? -1 : 1,o > 2 ? -1 : 1)\n              , f = l.multiply(u)\n              , g = f.subtract(l.multiply(s))\n              , y = new Y(r ? f.add(l.multiply(r)) : f,g);\n            if (y.contains(i))\n              return {\n                point: g,\n                quadrant: o\n              }\n          }\n      }\n      function t(n, i, r, s) {\n        var u = n.divide(i);\n        return (!s || u.isInQuadrant(s)) && u.subtract(u.normalize()).multiply(i).divide(r).length <= 1\n      }\n      return {\n        _contains: function n(i) {\n          if (this._type === \"rectangle\") {\n            var r = e(this, i);\n            return r ? i.subtract(r.point).divide(this._radius).getLength() <= 1 : n.base.call(this, i)\n          } else\n            return i.divide(this.size).getLength() <= .5\n        },\n        _hitTestSelf: function n(i, r, s, u) {\n          var o = !1\n            , l = this._style\n            , f = r.stroke && l.hasStroke()\n            , g = r.fill && l.hasFill();\n          if (f || g) {\n            var y = this._type\n              , _ = this._radius\n              , v = f ? l.getStrokeWidth() / 2 : 0\n              , b = r._tolerancePadding.add(ke._getStrokePadding(v, !l.getStrokeScaling() && u));\n            if (y === \"rectangle\") {\n              var T = b.multiply(2)\n                , x = e(this, i, T);\n              if (x)\n                o = t(i.subtract(x.point), _, b, x.quadrant);\n              else {\n                var S = new Y(this._size).setCenter(0, 0)\n                  , I = S.expand(T)\n                  , m = S.expand(T.negate());\n                o = I._containsPoint(i) && !m._containsPoint(i)\n              }\n            } else\n              o = t(i, _, b)\n          }\n          return o ? new qe(f ? \"stroke\" : \"fill\",this) : n.base.apply(this, arguments)\n        }\n      }\n    }\n    , {\n      statics: new function() {\n        function e(t, n, i, r, s) {\n          var u = d.create(je.prototype);\n          return u._type = t,\n            u._size = i,\n            u._radius = r,\n            u._initialize(d.getNamed(s), n),\n            u\n        }\n        return {\n          Circle: function() {\n            var t = arguments\n              , n = C.readNamed(t, \"center\")\n              , i = d.readNamed(t, \"radius\");\n            return e(\"circle\", n, new J(i * 2), i, t)\n          },\n          Rectangle: function() {\n            var t = arguments\n              , n = Y.readNamed(t, \"rectangle\")\n              , i = J.min(J.readNamed(t, \"radius\"), n.getSize(!0).divide(2));\n            return e(\"rectangle\", n.getCenter(!0), n.getSize(!0), i, t)\n          },\n          Ellipse: function() {\n            var t = arguments\n              , n = je._readEllipse(t)\n              , i = n.radius;\n            return e(\"ellipse\", n.center, i.multiply(2), i, t)\n          },\n          _readEllipse: function(t) {\n            var n, i;\n            if (d.hasNamed(t, \"radius\"))\n              n = C.readNamed(t, \"center\"),\n                i = J.readNamed(t, \"radius\");\n            else {\n              var r = Y.readNamed(t, \"rectangle\");\n              n = r.getCenter(!0),\n                i = r.getSize(!0).divide(2)\n            }\n            return {\n              center: n,\n              radius: i\n            }\n          }\n        }\n      }\n    })\n    , Pt = oe.extend({\n    _class: \"Raster\",\n    _applyMatrix: !1,\n    _canApplyMatrix: !1,\n    _boundsOptions: {\n      stroke: !1,\n      handle: !1\n    },\n    _serializeFields: {\n      crossOrigin: null,\n      source: null\n    },\n    _prioritize: [\"crossOrigin\"],\n    _smoothing: \"low\",\n    beans: !0,\n    initialize: function(t, n) {\n      if (!this._initialize(t, n !== a && C.read(arguments))) {\n        var i, r = typeof t, s = r === \"string\" ? p.getElementById(t) : r === \"object\" ? t : null;\n        if (s && s !== oe.NO_INSERT) {\n          if (s.getContext || s.naturalHeight != null)\n            i = s;\n          else if (s) {\n            var u = J.read(arguments);\n            u.isZero() || (i = Je.getCanvas(u))\n          }\n        }\n        i ? this.setImage(i) : this.setSource(t)\n      }\n      this._size || (this._size = new J,\n        this._loaded = !1)\n    },\n    _equals: function(e) {\n      return this.getSource() === e.getSource()\n    },\n    copyContent: function(e) {\n      var t = e._image\n        , n = e._canvas;\n      if (t)\n        this._setImage(t);\n      else if (n) {\n        var i = Je.getCanvas(e._size);\n        i.getContext(\"2d\").drawImage(n, 0, 0),\n          this._setImage(i)\n      }\n      this._crossOrigin = e._crossOrigin\n    },\n    getSize: function() {\n      var e = this._size;\n      return new ne(e ? e.width : 0,e ? e.height : 0,this,\"setSize\")\n    },\n    setSize: function(e, t) {\n      var n = J.read(arguments);\n      if (n.equals(this._size))\n        t && this.clear();\n      else if (n.width > 0 && n.height > 0) {\n        var i = !t && this.getElement();\n        this._setImage(Je.getCanvas(n)),\n        i && this.getContext(!0).drawImage(i, 0, 0, n.width, n.height)\n      } else\n        this._canvas && Je.release(this._canvas),\n          this._size = n.clone()\n    },\n    getWidth: function() {\n      return this._size ? this._size.width : 0\n    },\n    setWidth: function(e) {\n      this.setSize(e, this.getHeight())\n    },\n    getHeight: function() {\n      return this._size ? this._size.height : 0\n    },\n    setHeight: function(e) {\n      this.setSize(this.getWidth(), e)\n    },\n    getLoaded: function() {\n      return this._loaded\n    },\n    isEmpty: function() {\n      var e = this._size;\n      return !e || e.width === 0 && e.height === 0\n    },\n    getResolution: function() {\n      var e = this._matrix\n        , t = new C(0,0).transform(e)\n        , n = new C(1,0).transform(e).subtract(t)\n        , i = new C(0,1).transform(e).subtract(t);\n      return new J(72 / n.getLength(),72 / i.getLength())\n    },\n    getPpi: \"#getResolution\",\n    getImage: function() {\n      return this._image\n    },\n    setImage: function(e) {\n      var t = this;\n      function n(i) {\n        var r = t.getView()\n          , s = i && i.type || \"load\";\n        r && t.responds(s) && (ae = r._scope,\n          t.emit(s, new Zt(i)))\n      }\n      this._setImage(e),\n        this._loaded ? setTimeout(n, 0) : e && tt.add(e, {\n          load: function(i) {\n            t._setImage(e),\n              n(i)\n          },\n          error: n\n        })\n    },\n    _setImage: function(e) {\n      this._canvas && Je.release(this._canvas),\n        e && e.getContext ? (this._image = null,\n          this._canvas = e,\n          this._loaded = !0) : (this._image = e,\n          this._canvas = null,\n          this._loaded = !!(e && e.src && e.complete)),\n        this._size = new J(e ? e.naturalWidth || e.width : 0,e ? e.naturalHeight || e.height : 0),\n        this._context = null,\n        this._changed(1033)\n    },\n    getCanvas: function() {\n      if (!this._canvas) {\n        var e = Je.getContext(this._size);\n        try {\n          this._image && e.drawImage(this._image, 0, 0),\n            this._canvas = e.canvas\n        } catch {\n          Je.release(e)\n        }\n      }\n      return this._canvas\n    },\n    setCanvas: \"#setImage\",\n    getContext: function(e) {\n      return this._context || (this._context = this.getCanvas().getContext(\"2d\")),\n      e && (this._image = null,\n        this._changed(1025)),\n        this._context\n    },\n    setContext: function(e) {\n      this._context = e\n    },\n    getSource: function() {\n      var e = this._image;\n      return e && e.src || this.toDataURL()\n    },\n    setSource: function(e) {\n      var t = new c.Image\n        , n = this._crossOrigin;\n      n && (t.crossOrigin = n),\n      e && (t.src = e),\n        this.setImage(t)\n    },\n    getCrossOrigin: function() {\n      var e = this._image;\n      return e && e.crossOrigin || this._crossOrigin || \"\"\n    },\n    setCrossOrigin: function(e) {\n      this._crossOrigin = e;\n      var t = this._image;\n      t && (t.crossOrigin = e)\n    },\n    getSmoothing: function() {\n      return this._smoothing\n    },\n    setSmoothing: function(e) {\n      this._smoothing = typeof e == \"string\" ? e : e ? \"low\" : \"off\",\n        this._changed(257)\n    },\n    getElement: function() {\n      return this._canvas || this._loaded && this._image\n    }\n  }, {\n    beans: !1,\n    getSubCanvas: function() {\n      var e = Y.read(arguments)\n        , t = Je.getContext(e.getSize());\n      return t.drawImage(this.getCanvas(), e.x, e.y, e.width, e.height, 0, 0, e.width, e.height),\n        t.canvas\n    },\n    getSubRaster: function() {\n      var e = Y.read(arguments)\n        , t = new Pt(oe.NO_INSERT);\n      return t._setImage(this.getSubCanvas(e)),\n        t.translate(e.getCenter().subtract(this.getSize().divide(2))),\n        t._matrix.prepend(this._matrix),\n        t.insertAbove(this),\n        t\n    },\n    toDataURL: function() {\n      var e = this._image\n        , t = e && e.src;\n      if (/^data:/.test(t))\n        return t;\n      var n = this.getCanvas();\n      return n ? n.toDataURL.apply(n, arguments) : null\n    },\n    drawImage: function(e) {\n      var t = C.read(arguments, 1);\n      this.getContext(!0).drawImage(e, t.x, t.y)\n    },\n    getAverageColor: function(e) {\n      var t, n;\n      if (e ? e instanceof Ft ? (n = e,\n        t = e.getBounds()) : typeof e == \"object\" && (\"width\"in e ? t = new Y(e) : \"x\"in e && (t = new Y(e.x - .5,e.y - .5,1,1))) : t = this.getBounds(),\n        !t)\n        return null;\n      var i = 32\n        , r = Math.min(t.width, i)\n        , s = Math.min(t.height, i)\n        , u = Pt._sampleContext;\n      u ? u.clearRect(0, 0, i + 1, i + 1) : u = Pt._sampleContext = Je.getContext(new J(i)),\n        u.save();\n      var o = new le().scale(r / t.width, s / t.height).translate(-t.x, -t.y);\n      o.applyToContext(u),\n      n && n.draw(u, new d({\n        clip: !0,\n        matrices: [o]\n      })),\n        this._matrix.applyToContext(u);\n      var l = this.getElement()\n        , f = this._size;\n      l && u.drawImage(l, -f.width / 2, -f.height / 2),\n        u.restore();\n      for (var g = u.getImageData(.5, .5, Math.ceil(r), Math.ceil(s)).data, y = [0, 0, 0], _ = 0, v = 0, b = g.length; v < b; v += 4) {\n        var T = g[v + 3];\n        _ += T,\n          T /= 255,\n          y[0] += g[v] * T,\n          y[1] += g[v + 1] * T,\n          y[2] += g[v + 2] * T\n      }\n      for (var v = 0; v < 3; v++)\n        y[v] /= _;\n      return _ ? Xe.read(y) : null\n    },\n    getPixel: function() {\n      var e = C.read(arguments)\n        , t = this.getContext().getImageData(e.x, e.y, 1, 1).data;\n      return new Xe(\"rgb\",[t[0] / 255, t[1] / 255, t[2] / 255],t[3] / 255)\n    },\n    setPixel: function() {\n      var e = arguments\n        , t = C.read(e)\n        , n = Xe.read(e)\n        , i = n._convert(\"rgb\")\n        , r = n._alpha\n        , s = this.getContext(!0)\n        , u = s.createImageData(1, 1)\n        , o = u.data;\n      o[0] = i[0] * 255,\n        o[1] = i[1] * 255,\n        o[2] = i[2] * 255,\n        o[3] = r != null ? r * 255 : 255,\n        s.putImageData(u, t.x, t.y)\n    },\n    clear: function() {\n      var e = this._size;\n      this.getContext(!0).clearRect(0, 0, e.width + 1, e.height + 1)\n    },\n    createImageData: function() {\n      var e = J.read(arguments);\n      return this.getContext().createImageData(e.width, e.height)\n    },\n    getImageData: function() {\n      var e = Y.read(arguments);\n      return e.isEmpty() && (e = new Y(this._size)),\n        this.getContext().getImageData(e.x, e.y, e.width, e.height)\n    },\n    putImageData: function(e) {\n      var t = C.read(arguments, 1);\n      this.getContext(!0).putImageData(e, t.x, t.y)\n    },\n    setImageData: function(e) {\n      this.setSize(e),\n        this.getContext(!0).putImageData(e, 0, 0)\n    },\n    _getBounds: function(e, t) {\n      var n = new Y(this._size).setCenter(0, 0);\n      return e ? e._transformBounds(n) : n\n    },\n    _hitTestSelf: function(e) {\n      if (this._contains(e)) {\n        var t = this;\n        return new qe(\"pixel\",t,{\n          offset: e.add(t._size.divide(2)).round(),\n          color: {\n            get: function() {\n              return t.getPixel(this.offset)\n            }\n          }\n        })\n      }\n    },\n    _draw: function(e, t, n) {\n      var i = this.getElement();\n      if (i && i.width > 0 && i.height > 0) {\n        e.globalAlpha = O.clamp(this._opacity, 0, 1),\n          this._setStyles(e, t, n);\n        var r = this._smoothing\n          , s = r === \"off\";\n        Ce.setPrefixed(e, s ? \"imageSmoothingEnabled\" : \"imageSmoothingQuality\", s ? !1 : r),\n          e.drawImage(i, -this._size.width / 2, -this._size.height / 2)\n      }\n    },\n    _canComposite: function() {\n      return !0\n    }\n  })\n    , ft = oe.extend({\n    _class: \"SymbolItem\",\n    _applyMatrix: !1,\n    _canApplyMatrix: !1,\n    _boundsOptions: {\n      stroke: !0\n    },\n    _serializeFields: {\n      symbol: null\n    },\n    initialize: function(t, n) {\n      this._initialize(t, n !== a && C.read(arguments, 1)) || this.setDefinition(t instanceof dt ? t : new dt(t))\n    },\n    _equals: function(e) {\n      return this._definition === e._definition\n    },\n    copyContent: function(e) {\n      this.setDefinition(e._definition)\n    },\n    getDefinition: function() {\n      return this._definition\n    },\n    setDefinition: function(e) {\n      this._definition = e,\n        this._changed(9)\n    },\n    getSymbol: \"#getDefinition\",\n    setSymbol: \"#setDefinition\",\n    isEmpty: function() {\n      return this._definition._item.isEmpty()\n    },\n    _getBounds: function(e, t) {\n      var n = this._definition._item;\n      return n._getCachedBounds(n._matrix.prepended(e), t)\n    },\n    _hitTestSelf: function(e, t, n) {\n      var i = t.extend({\n        all: !1\n      })\n        , r = this._definition._item._hitTest(e, i, n);\n      return r && (r.item = this),\n        r\n    },\n    _draw: function(e, t) {\n      this._definition._item.draw(e, t)\n    }\n  })\n    , dt = d.extend({\n    _class: \"SymbolDefinition\",\n    initialize: function(t, n) {\n      this._id = B.get(),\n        this.project = ae.project,\n      t && this.setItem(t, n)\n    },\n    _serialize: function(e, t) {\n      return t.add(this, function() {\n        return d.serialize([this._class, this._item], e, !1, t)\n      })\n    },\n    _changed: function(e) {\n      e & 8 && oe._clearBoundsCache(this),\n      e & 1 && this.project._changed(e)\n    },\n    getItem: function() {\n      return this._item\n    },\n    setItem: function(e, t) {\n      e._symbol && (e = e.clone()),\n      this._item && (this._item._symbol = null),\n        this._item = e,\n        e.remove(),\n        e.setSelected(!1),\n      t || e.setPosition(new C),\n        e._symbol = this,\n        this._changed(9)\n    },\n    getDefinition: \"#getItem\",\n    setDefinition: \"#setItem\",\n    place: function(e) {\n      return new ft(this,e)\n    },\n    clone: function() {\n      return new dt(this._item.clone(!1))\n    },\n    equals: function(e) {\n      return e === this || e && this._item.equals(e._item) || !1\n    }\n  })\n    , qe = d.extend({\n    _class: \"HitResult\",\n    initialize: function(t, n, i) {\n      this.type = t,\n        this.item = n,\n      i && this.inject(i)\n    },\n    statics: {\n      getOptions: function(e) {\n        var t = e && d.read(e);\n        return new d({\n          type: null,\n          tolerance: ae.settings.hitTolerance,\n          fill: !t,\n          stroke: !t,\n          segments: !t,\n          handles: !1,\n          ends: !1,\n          position: !1,\n          center: !1,\n          bounds: !1,\n          guides: !1,\n          selected: !1\n        },t)\n      }\n    }\n  })\n    , pe = d.extend({\n    _class: \"Segment\",\n    beans: !0,\n    _selection: 0,\n    initialize: function(t, n, i, r, s, u) {\n      var o = arguments.length, l, f, g, y;\n      o > 0 && (t == null || typeof t == \"object\" ? o === 1 && t && \"point\"in t ? (l = t.point,\n        f = t.handleIn,\n        g = t.handleOut,\n        y = t.selection) : (l = t,\n        f = n,\n        g = i,\n        y = r) : (l = [t, n],\n        f = i !== a ? [i, r] : null,\n        g = s !== a ? [s, u] : null)),\n        new Vt(l,this,\"_point\"),\n        new Vt(f,this,\"_handleIn\"),\n        new Vt(g,this,\"_handleOut\"),\n      y && this.setSelection(y)\n    },\n    _serialize: function(e, t) {\n      var n = this._point\n        , i = this._selection\n        , r = i || this.hasHandles() ? [n, this._handleIn, this._handleOut] : n;\n      return i && r.push(i),\n        d.serialize(r, e, !0, t)\n    },\n    _changed: function(e) {\n      var t = this._path;\n      if (t) {\n        var n = t._curves, i = this._index, r;\n        n && ((!e || e === this._point || e === this._handleIn) && (r = i > 0 ? n[i - 1] : t._closed ? n[n.length - 1] : null) && r._changed(),\n        (!e || e === this._point || e === this._handleOut) && (r = n[i]) && r._changed()),\n          t._changed(41)\n      }\n    },\n    getPoint: function() {\n      return this._point\n    },\n    setPoint: function() {\n      this._point.set(C.read(arguments))\n    },\n    getHandleIn: function() {\n      return this._handleIn\n    },\n    setHandleIn: function() {\n      this._handleIn.set(C.read(arguments))\n    },\n    getHandleOut: function() {\n      return this._handleOut\n    },\n    setHandleOut: function() {\n      this._handleOut.set(C.read(arguments))\n    },\n    hasHandles: function() {\n      return !this._handleIn.isZero() || !this._handleOut.isZero()\n    },\n    isSmooth: function() {\n      var e = this._handleIn\n        , t = this._handleOut;\n      return !e.isZero() && !t.isZero() && e.isCollinear(t)\n    },\n    clearHandles: function() {\n      this._handleIn._set(0, 0),\n        this._handleOut._set(0, 0)\n    },\n    getSelection: function() {\n      return this._selection\n    },\n    setSelection: function(e) {\n      var t = this._selection\n        , n = this._path;\n      this._selection = e = e || 0,\n      n && e !== t && (n._updateSelection(this, t, e),\n        n._changed(257))\n    },\n    _changeSelection: function(e, t) {\n      var n = this._selection;\n      this.setSelection(t ? n | e : n & ~e)\n    },\n    isSelected: function() {\n      return !!(this._selection & 7)\n    },\n    setSelected: function(e) {\n      this._changeSelection(7, e)\n    },\n    getIndex: function() {\n      return this._index !== a ? this._index : null\n    },\n    getPath: function() {\n      return this._path || null\n    },\n    getCurve: function() {\n      var e = this._path\n        , t = this._index;\n      return e ? (t > 0 && !e._closed && t === e._segments.length - 1 && t--,\n      e.getCurves()[t] || null) : null\n    },\n    getLocation: function() {\n      var e = this.getCurve();\n      return e ? new Ot(e,this === e._segment1 ? 0 : 1) : null\n    },\n    getNext: function() {\n      var e = this._path && this._path._segments;\n      return e && (e[this._index + 1] || this._path._closed && e[0]) || null\n    },\n    smooth: function(e, t, n) {\n      var i = e || {}\n        , r = i.type\n        , s = i.factor\n        , u = this.getPrevious()\n        , o = this.getNext()\n        , l = (u || this)._point\n        , f = this._point\n        , g = (o || this)._point\n        , y = l.getDistance(f)\n        , _ = f.getDistance(g);\n      if (!r || r === \"catmull-rom\") {\n        var v = s === a ? .5 : s\n          , b = Math.pow(y, v)\n          , T = b * b\n          , x = Math.pow(_, v)\n          , S = x * x;\n        if (!t && u) {\n          var I = 2 * S + 3 * x * b + T\n            , m = 3 * x * (x + b);\n          this.setHandleIn(m !== 0 ? new C((S * l._x + I * f._x - T * g._x) / m - f._x,(S * l._y + I * f._y - T * g._y) / m - f._y) : new C)\n        }\n        if (!n && o) {\n          var I = 2 * T + 3 * b * x + S\n            , m = 3 * b * (b + x);\n          this.setHandleOut(m !== 0 ? new C((T * g._x + I * f._x - S * l._x) / m - f._x,(T * g._y + I * f._y - S * l._y) / m - f._y) : new C)\n        }\n      } else if (r === \"geometric\") {\n        if (u && o) {\n          var w = l.subtract(g)\n            , E = s === a ? .4 : s\n            , A = E * y / (y + _);\n          t || this.setHandleIn(w.multiply(A)),\n          n || this.setHandleOut(w.multiply(A - E))\n        }\n      } else\n        throw new Error(\"Smoothing method '\" + r + \"' not supported.\")\n    },\n    getPrevious: function() {\n      var e = this._path && this._path._segments;\n      return e && (e[this._index - 1] || this._path._closed && e[e.length - 1]) || null\n    },\n    isFirst: function() {\n      return !this._index\n    },\n    isLast: function() {\n      var e = this._path;\n      return e && this._index === e._segments.length - 1 || !1\n    },\n    reverse: function() {\n      var e = this._handleIn\n        , t = this._handleOut\n        , n = e.clone();\n      e.set(t),\n        t.set(n)\n    },\n    reversed: function() {\n      return new pe(this._point,this._handleOut,this._handleIn)\n    },\n    remove: function() {\n      return this._path ? !!this._path.removeSegment(this._index) : !1\n    },\n    clone: function() {\n      return new pe(this._point,this._handleIn,this._handleOut)\n    },\n    equals: function(e) {\n      return e === this || e && this._class === e._class && this._point.equals(e._point) && this._handleIn.equals(e._handleIn) && this._handleOut.equals(e._handleOut) || !1\n    },\n    toString: function() {\n      var e = [\"point: \" + this._point];\n      return this._handleIn.isZero() || e.push(\"handleIn: \" + this._handleIn),\n      this._handleOut.isZero() || e.push(\"handleOut: \" + this._handleOut),\n      \"{ \" + e.join(\", \") + \" }\"\n    },\n    transform: function(e) {\n      this._transformCoordinates(e, new Array(6), !0),\n        this._changed()\n    },\n    interpolate: function(e, t, n) {\n      var i = 1 - n\n        , r = n\n        , s = e._point\n        , u = t._point\n        , o = e._handleIn\n        , l = t._handleIn\n        , f = t._handleOut\n        , g = e._handleOut;\n      this._point._set(i * s._x + r * u._x, i * s._y + r * u._y, !0),\n        this._handleIn._set(i * o._x + r * l._x, i * o._y + r * l._y, !0),\n        this._handleOut._set(i * g._x + r * f._x, i * g._y + r * f._y, !0),\n        this._changed()\n    },\n    _transformCoordinates: function(e, t, n) {\n      var i = this._point\n        , r = !n || !this._handleIn.isZero() ? this._handleIn : null\n        , s = !n || !this._handleOut.isZero() ? this._handleOut : null\n        , u = i._x\n        , o = i._y\n        , l = 2;\n      return t[0] = u,\n        t[1] = o,\n      r && (t[l++] = r._x + u,\n        t[l++] = r._y + o),\n      s && (t[l++] = s._x + u,\n        t[l++] = s._y + o),\n      e && (e._transformCoordinates(t, t, l / 2),\n        u = t[0],\n        o = t[1],\n        n ? (i._x = u,\n          i._y = o,\n          l = 2,\n        r && (r._x = t[l++] - u,\n          r._y = t[l++] - o),\n        s && (s._x = t[l++] - u,\n          s._y = t[l++] - o)) : (r || (t[l++] = u,\n          t[l++] = o),\n        s || (t[l++] = u,\n          t[l++] = o))),\n        t\n    }\n  })\n    , Vt = C.extend({\n    initialize: function(t, n, i) {\n      var r, s, u;\n      if (!t)\n        r = s = 0;\n      else if ((r = t[0]) !== a)\n        s = t[1];\n      else {\n        var o = t;\n        (r = o.x) === a && (o = C.read(arguments),\n          r = o.x),\n          s = o.y,\n          u = o.selected\n      }\n      this._x = r,\n        this._y = s,\n        this._owner = n,\n        n[i] = this,\n      u && this.setSelected(!0)\n    },\n    _set: function(e, t) {\n      return this._x = e,\n        this._y = t,\n        this._owner._changed(this),\n        this\n    },\n    getX: function() {\n      return this._x\n    },\n    setX: function(e) {\n      this._x = e,\n        this._owner._changed(this)\n    },\n    getY: function() {\n      return this._y\n    },\n    setY: function(e) {\n      this._y = e,\n        this._owner._changed(this)\n    },\n    isZero: function() {\n      var e = O.isZero;\n      return e(this._x) && e(this._y)\n    },\n    isSelected: function() {\n      return !!(this._owner._selection & this._getSelection())\n    },\n    setSelected: function(e) {\n      this._owner._changeSelection(this._getSelection(), e)\n    },\n    _getSelection: function() {\n      var e = this._owner;\n      return this === e._point ? 1 : this === e._handleIn ? 2 : this === e._handleOut ? 4 : 0\n    }\n  })\n    , re = d.extend({\n      _class: \"Curve\",\n      beans: !0,\n      initialize: function(t, n, i, r, s, u, o, l) {\n        var f = arguments.length, g, y, _, v, b, T;\n        f === 3 ? (this._path = t,\n          g = n,\n          y = i) : f ? f === 1 ? \"segment1\"in t ? (g = new pe(t.segment1),\n          y = new pe(t.segment2)) : \"point1\"in t ? (_ = t.point1,\n          b = t.handle1,\n          T = t.handle2,\n          v = t.point2) : Array.isArray(t) && (_ = [t[0], t[1]],\n          v = [t[6], t[7]],\n          b = [t[2] - t[0], t[3] - t[1]],\n          T = [t[4] - t[6], t[5] - t[7]]) : f === 2 ? (g = new pe(t),\n          y = new pe(n)) : f === 4 ? (_ = t,\n          b = n,\n          T = i,\n          v = r) : f === 8 && (_ = [t, n],\n          v = [o, l],\n          b = [i - t, r - n],\n          T = [s - o, u - l]) : (g = new pe,\n          y = new pe),\n          this._segment1 = g || new pe(_,null,b),\n          this._segment2 = y || new pe(v,T,null)\n      },\n      _serialize: function(e, t) {\n        return d.serialize(this.hasHandles() ? [this.getPoint1(), this.getHandle1(), this.getHandle2(), this.getPoint2()] : [this.getPoint1(), this.getPoint2()], e, !0, t)\n      },\n      _changed: function() {\n        this._length = this._bounds = a\n      },\n      clone: function() {\n        return new re(this._segment1,this._segment2)\n      },\n      toString: function() {\n        var e = [\"point1: \" + this._segment1._point];\n        return this._segment1._handleOut.isZero() || e.push(\"handle1: \" + this._segment1._handleOut),\n        this._segment2._handleIn.isZero() || e.push(\"handle2: \" + this._segment2._handleIn),\n          e.push(\"point2: \" + this._segment2._point),\n        \"{ \" + e.join(\", \") + \" }\"\n      },\n      classify: function() {\n        return re.classify(this.getValues())\n      },\n      remove: function() {\n        var e = !1;\n        if (this._path) {\n          var t = this._segment2\n            , n = t._handleOut;\n          e = t.remove(),\n          e && this._segment1._handleOut.set(n)\n        }\n        return e\n      },\n      getPoint1: function() {\n        return this._segment1._point\n      },\n      setPoint1: function() {\n        this._segment1._point.set(C.read(arguments))\n      },\n      getPoint2: function() {\n        return this._segment2._point\n      },\n      setPoint2: function() {\n        this._segment2._point.set(C.read(arguments))\n      },\n      getHandle1: function() {\n        return this._segment1._handleOut\n      },\n      setHandle1: function() {\n        this._segment1._handleOut.set(C.read(arguments))\n      },\n      getHandle2: function() {\n        return this._segment2._handleIn\n      },\n      setHandle2: function() {\n        this._segment2._handleIn.set(C.read(arguments))\n      },\n      getSegment1: function() {\n        return this._segment1\n      },\n      getSegment2: function() {\n        return this._segment2\n      },\n      getPath: function() {\n        return this._path\n      },\n      getIndex: function() {\n        return this._segment1._index\n      },\n      getNext: function() {\n        var e = this._path && this._path._curves;\n        return e && (e[this._segment1._index + 1] || this._path._closed && e[0]) || null\n      },\n      getPrevious: function() {\n        var e = this._path && this._path._curves;\n        return e && (e[this._segment1._index - 1] || this._path._closed && e[e.length - 1]) || null\n      },\n      isFirst: function() {\n        return !this._segment1._index\n      },\n      isLast: function() {\n        var e = this._path;\n        return e && this._segment1._index === e._curves.length - 1 || !1\n      },\n      isSelected: function() {\n        return this.getPoint1().isSelected() && this.getHandle1().isSelected() && this.getHandle2().isSelected() && this.getPoint2().isSelected()\n      },\n      setSelected: function(e) {\n        this.getPoint1().setSelected(e),\n          this.getHandle1().setSelected(e),\n          this.getHandle2().setSelected(e),\n          this.getPoint2().setSelected(e)\n      },\n      getValues: function(e) {\n        return re.getValues(this._segment1, this._segment2, e)\n      },\n      getPoints: function() {\n        for (var e = this.getValues(), t = [], n = 0; n < 8; n += 2)\n          t.push(new C(e[n],e[n + 1]));\n        return t\n      }\n    }, {\n      getLength: function() {\n        return this._length == null && (this._length = re.getLength(this.getValues(), 0, 1)),\n          this._length\n      },\n      getArea: function() {\n        return re.getArea(this.getValues())\n      },\n      getLine: function() {\n        return new Se(this._segment1._point,this._segment2._point)\n      },\n      getPart: function(e, t) {\n        return new re(re.getPart(this.getValues(), e, t))\n      },\n      getPartLength: function(e, t) {\n        return re.getLength(this.getValues(), e, t)\n      },\n      divideAt: function(e) {\n        return this.divideAtTime(e && e.curve === this ? e.time : this.getTimeAt(e))\n      },\n      divideAtTime: function(e, t) {\n        var n = 1e-8\n          , i = 1 - n\n          , r = null;\n        if (e >= n && e <= i) {\n          var s = re.subdivide(this.getValues(), e)\n            , u = s[0]\n            , o = s[1]\n            , l = t || this.hasHandles()\n            , f = this._segment1\n            , g = this._segment2\n            , y = this._path;\n          l && (f._handleOut._set(u[2] - u[0], u[3] - u[1]),\n            g._handleIn._set(o[4] - o[6], o[5] - o[7]));\n          var _ = u[6]\n            , v = u[7]\n            , b = new pe(new C(_,v),l && new C(u[4] - _,u[5] - v),l && new C(o[2] - _,o[3] - v));\n          y ? (y.insert(f._index + 1, b),\n            r = this.getNext()) : (this._segment2 = b,\n            this._changed(),\n            r = new re(b,g))\n        }\n        return r\n      },\n      splitAt: function(e) {\n        var t = this._path;\n        return t ? t.splitAt(e) : null\n      },\n      splitAtTime: function(e) {\n        return this.splitAt(this.getLocationAtTime(e))\n      },\n      divide: function(e, t) {\n        return this.divideAtTime(e === a ? .5 : t ? e : this.getTimeAt(e))\n      },\n      split: function(e, t) {\n        return this.splitAtTime(e === a ? .5 : t ? e : this.getTimeAt(e))\n      },\n      reversed: function() {\n        return new re(this._segment2.reversed(),this._segment1.reversed())\n      },\n      clearHandles: function() {\n        this._segment1._handleOut._set(0, 0),\n          this._segment2._handleIn._set(0, 0)\n      },\n      statics: {\n        getValues: function(e, t, n, i) {\n          var r = e._point\n            , s = e._handleOut\n            , u = t._handleIn\n            , o = t._point\n            , l = r.x\n            , f = r.y\n            , g = o.x\n            , y = o.y\n            , _ = i ? [l, f, l, f, g, y, g, y] : [l, f, l + s._x, f + s._y, g + u._x, y + u._y, g, y];\n          return n && n._transformCoordinates(_, _, 4),\n            _\n        },\n        subdivide: function(e, t) {\n          var n = e[0]\n            , i = e[1]\n            , r = e[2]\n            , s = e[3]\n            , u = e[4]\n            , o = e[5]\n            , l = e[6]\n            , f = e[7];\n          t === a && (t = .5);\n          var g = 1 - t\n            , y = g * n + t * r\n            , _ = g * i + t * s\n            , v = g * r + t * u\n            , b = g * s + t * o\n            , T = g * u + t * l\n            , x = g * o + t * f\n            , S = g * y + t * v\n            , I = g * _ + t * b\n            , m = g * v + t * T\n            , w = g * b + t * x\n            , E = g * S + t * m\n            , A = g * I + t * w;\n          return [[n, i, y, _, S, I, E, A], [E, A, m, w, T, x, l, f]]\n        },\n        getMonoCurves: function(e, t) {\n          var n = []\n            , i = t ? 0 : 1\n            , r = e[i + 0]\n            , s = e[i + 2]\n            , u = e[i + 4]\n            , o = e[i + 6];\n          if (r >= s == s >= u && s >= u == u >= o || re.isStraight(e))\n            n.push(e);\n          else {\n            var l = 3 * (s - u) - r + o\n              , f = 2 * (r + u) - 4 * s\n              , g = s - r\n              , y = 1e-8\n              , _ = 1 - y\n              , v = []\n              , b = O.solveQuadratic(l, f, g, v, y, _);\n            if (!b)\n              n.push(e);\n            else {\n              v.sort();\n              var T = v[0]\n                , x = re.subdivide(e, T);\n              n.push(x[0]),\n              b > 1 && (T = (v[1] - T) / (1 - T),\n                x = re.subdivide(x[1], T),\n                n.push(x[0])),\n                n.push(x[1])\n            }\n          }\n          return n\n        },\n        solveCubic: function(e, t, n, i, r, s) {\n          var u = e[t]\n            , o = e[t + 2]\n            , l = e[t + 4]\n            , f = e[t + 6]\n            , g = 0;\n          if (!(u < n && f < n && o < n && l < n || u > n && f > n && o > n && l > n)) {\n            var y = 3 * (o - u)\n              , _ = 3 * (l - o) - y\n              , v = f - u - y - _;\n            g = O.solveCubic(v, _, y, u - n, i, r, s)\n          }\n          return g\n        },\n        getTimeOf: function(e, t) {\n          var n = new C(e[0],e[1])\n            , i = new C(e[6],e[7])\n            , r = 1e-12\n            , s = 1e-7\n            , u = t.isClose(n, r) ? 0 : t.isClose(i, r) ? 1 : null;\n          if (u === null)\n            for (var o = [t.x, t.y], l = [], f = 0; f < 2; f++)\n              for (var g = re.solveCubic(e, f, o[f], l, 0, 1), y = 0; y < g; y++) {\n                var _ = l[y];\n                if (t.isClose(re.getPoint(e, _), s))\n                  return _\n              }\n          return t.isClose(n, s) ? 0 : t.isClose(i, s) ? 1 : null\n        },\n        getNearestTime: function(e, t) {\n          if (re.isStraight(e)) {\n            var n = e[0]\n              , i = e[1]\n              , r = e[6]\n              , s = e[7]\n              , u = r - n\n              , o = s - i\n              , l = u * u + o * o;\n            if (l === 0)\n              return 0;\n            var f = ((t.x - n) * u + (t.y - i) * o) / l;\n            return f < 1e-12 ? 0 : f > .999999999999 ? 1 : re.getTimeOf(e, new C(n + f * u,i + f * o))\n          }\n          var g = 100\n            , y = 1 / 0\n            , _ = 0;\n          function v(x) {\n            if (x >= 0 && x <= 1) {\n              var S = t.getDistance(re.getPoint(e, x), !0);\n              if (S < y)\n                return y = S,\n                  _ = x,\n                  !0\n            }\n          }\n          for (var b = 0; b <= g; b++)\n            v(b / g);\n          for (var T = 1 / (g * 2); T > 1e-8; )\n            !v(_ - T) && !v(_ + T) && (T /= 2);\n          return _\n        },\n        getPart: function(e, t, n) {\n          var i = t > n;\n          if (i) {\n            var r = t;\n            t = n,\n              n = r\n          }\n          return t > 0 && (e = re.subdivide(e, t)[1]),\n          n < 1 && (e = re.subdivide(e, (n - t) / (1 - t))[0]),\n            i ? [e[6], e[7], e[4], e[5], e[2], e[3], e[0], e[1]] : e\n        },\n        isFlatEnough: function(e, t) {\n          var n = e[0]\n            , i = e[1]\n            , r = e[2]\n            , s = e[3]\n            , u = e[4]\n            , o = e[5]\n            , l = e[6]\n            , f = e[7]\n            , g = 3 * r - 2 * n - l\n            , y = 3 * s - 2 * i - f\n            , _ = 3 * u - 2 * l - n\n            , v = 3 * o - 2 * f - i;\n          return Math.max(g * g, _ * _) + Math.max(y * y, v * v) <= 16 * t * t\n        },\n        getArea: function(e) {\n          var t = e[0]\n            , n = e[1]\n            , i = e[2]\n            , r = e[3]\n            , s = e[4]\n            , u = e[5]\n            , o = e[6]\n            , l = e[7];\n          return 3 * ((l - n) * (i + s) - (o - t) * (r + u) + r * (t - s) - i * (n - u) + l * (s + t / 3) - o * (u + n / 3)) / 20\n        },\n        getBounds: function(e) {\n          for (var t = e.slice(0, 2), n = t.slice(), i = [0, 0], r = 0; r < 2; r++)\n            re._addBounds(e[r], e[r + 2], e[r + 4], e[r + 6], r, 0, t, n, i);\n          return new Y(t[0],t[1],n[0] - t[0],n[1] - t[1])\n        },\n        _addBounds: function(e, t, n, i, r, s, u, o, l) {\n          function f(E, A) {\n            var N = E - A\n              , L = E + A;\n            N < u[r] && (u[r] = N),\n            L > o[r] && (o[r] = L)\n          }\n          s /= 2;\n          var g = u[r] + s\n            , y = o[r] - s;\n          if (e < g || t < g || n < g || i < g || e > y || t > y || n > y || i > y)\n            if (t < e != t < i && n < e != n < i)\n              f(e, 0),\n                f(i, 0);\n            else {\n              var _ = 3 * (t - n) - e + i\n                , v = 2 * (e + n) - 4 * t\n                , b = t - e\n                , T = O.solveQuadratic(_, v, b, l)\n                , x = 1e-8\n                , S = 1 - x;\n              f(i, 0);\n              for (var I = 0; I < T; I++) {\n                var m = l[I]\n                  , w = 1 - m;\n                x <= m && m <= S && f(w * w * w * e + 3 * w * w * m * t + 3 * w * m * m * n + m * m * m * i, s)\n              }\n            }\n        }\n      }\n    }, d.each([\"getBounds\", \"getStrokeBounds\", \"getHandleBounds\"], function(e) {\n      this[e] = function() {\n        this._bounds || (this._bounds = {});\n        var t = this._bounds[e];\n        return t || (t = this._bounds[e] = ke[e]([this._segment1, this._segment2], !1, this._path)),\n          t.clone()\n      }\n    }, {}), d.each({\n      isStraight: function(e, t, n, i) {\n        if (t.isZero() && n.isZero())\n          return !0;\n        var r = i.subtract(e);\n        if (r.isZero())\n          return !1;\n        if (r.isCollinear(t) && r.isCollinear(n)) {\n          var s = new Se(e,i)\n            , u = 1e-7;\n          if (s.getDistance(e.add(t)) < u && s.getDistance(i.add(n)) < u) {\n            var o = r.dot(r)\n              , l = r.dot(t) / o\n              , f = r.dot(n) / o;\n            return l >= 0 && l <= 1 && f <= 0 && f >= -1\n          }\n        }\n        return !1\n      },\n      isLinear: function(e, t, n, i) {\n        var r = i.subtract(e).divide(3);\n        return t.equals(r) && n.negate().equals(r)\n      }\n    }, function(e, t) {\n      this[t] = function(n) {\n        var i = this._segment1\n          , r = this._segment2;\n        return e(i._point, i._handleOut, r._handleIn, r._point, n)\n      }\n        ,\n        this.statics[t] = function(n, i) {\n          var r = n[0]\n            , s = n[1]\n            , u = n[6]\n            , o = n[7];\n          return e(new C(r,s), new C(n[2] - r,n[3] - s), new C(n[4] - u,n[5] - o), new C(u,o), i)\n        }\n    }, {\n      statics: {},\n      hasHandles: function() {\n        return !this._segment1._handleOut.isZero() || !this._segment2._handleIn.isZero()\n      },\n      hasLength: function(e) {\n        return (!this.getPoint1().equals(this.getPoint2()) || this.hasHandles()) && this.getLength() > (e || 0)\n      },\n      isCollinear: function(e) {\n        return e && this.isStraight() && e.isStraight() && this.getLine().isCollinear(e.getLine())\n      },\n      isHorizontal: function() {\n        return this.isStraight() && Math.abs(this.getTangentAtTime(.5).y) < 1e-8\n      },\n      isVertical: function() {\n        return this.isStraight() && Math.abs(this.getTangentAtTime(.5).x) < 1e-8\n      }\n    }), {\n      beans: !1,\n      getLocationAt: function(e, t) {\n        return this.getLocationAtTime(t ? e : this.getTimeAt(e))\n      },\n      getLocationAtTime: function(e) {\n        return e != null && e >= 0 && e <= 1 ? new Ot(this,e) : null\n      },\n      getTimeAt: function(e, t) {\n        return re.getTimeAt(this.getValues(), e, t)\n      },\n      getParameterAt: \"#getTimeAt\",\n      getTimesWithTangent: function() {\n        var e = C.read(arguments);\n        return e.isZero() ? [] : re.getTimesWithTangent(this.getValues(), e)\n      },\n      getOffsetAtTime: function(e) {\n        return this.getPartLength(0, e)\n      },\n      getLocationOf: function() {\n        return this.getLocationAtTime(this.getTimeOf(C.read(arguments)))\n      },\n      getOffsetOf: function() {\n        var e = this.getLocationOf.apply(this, arguments);\n        return e ? e.getOffset() : null\n      },\n      getTimeOf: function() {\n        return re.getTimeOf(this.getValues(), C.read(arguments))\n      },\n      getParameterOf: \"#getTimeOf\",\n      getNearestLocation: function() {\n        var e = C.read(arguments)\n          , t = this.getValues()\n          , n = re.getNearestTime(t, e)\n          , i = re.getPoint(t, n);\n        return new Ot(this,n,i,null,e.getDistance(i))\n      },\n      getNearestPoint: function() {\n        var e = this.getNearestLocation.apply(this, arguments);\n        return e && e.getPoint()\n      }\n    }, new function() {\n      var e = [\"getPoint\", \"getTangent\", \"getNormal\", \"getWeightedTangent\", \"getWeightedNormal\", \"getCurvature\"];\n      return d.each(e, function(t) {\n        this[t + \"At\"] = function(n, i) {\n          var r = this.getValues();\n          return re[t](r, i ? n : re.getTimeAt(r, n))\n        }\n          ,\n          this[t + \"AtTime\"] = function(n) {\n            return re[t](this.getValues(), n)\n          }\n      }, {\n        statics: {\n          _evaluateMethods: e\n        }\n      })\n    }\n    , new function() {\n      function e(i) {\n        var r = i[0]\n          , s = i[1]\n          , u = i[2]\n          , o = i[3]\n          , l = i[4]\n          , f = i[5]\n          , g = i[6]\n          , y = i[7]\n          , _ = 9 * (u - l) + 3 * (g - r)\n          , v = 6 * (r + l) - 12 * u\n          , b = 3 * (u - r)\n          , T = 9 * (o - f) + 3 * (y - s)\n          , x = 6 * (s + f) - 12 * o\n          , S = 3 * (o - s);\n        return function(I) {\n          var m = (_ * I + v) * I + b\n            , w = (T * I + x) * I + S;\n          return Math.sqrt(m * m + w * w)\n        }\n      }\n      function t(i, r) {\n        return Math.max(2, Math.min(16, Math.ceil(Math.abs(r - i) * 32)))\n      }\n      function n(i, r, s, u) {\n        if (r == null || r < 0 || r > 1)\n          return null;\n        var o = i[0]\n          , l = i[1]\n          , f = i[2]\n          , g = i[3]\n          , y = i[4]\n          , _ = i[5]\n          , v = i[6]\n          , b = i[7]\n          , T = O.isZero;\n        T(f - o) && T(g - l) && (f = o,\n          g = l),\n        T(y - v) && T(_ - b) && (y = v,\n          _ = b);\n        var x = 3 * (f - o), S = 3 * (y - f) - x, I = v - o - x - S, m = 3 * (g - l), w = 3 * (_ - g) - m, E = b - l - m - w, A, N;\n        if (s === 0)\n          A = r === 0 ? o : r === 1 ? v : ((I * r + S) * r + x) * r + o,\n            N = r === 0 ? l : r === 1 ? b : ((E * r + w) * r + m) * r + l;\n        else {\n          var L = 1e-8\n            , R = 1 - L;\n          if (r < L ? (A = x,\n            N = m) : r > R ? (A = 3 * (v - y),\n            N = 3 * (b - _)) : (A = (3 * I * r + 2 * S) * r + x,\n            N = (3 * E * r + 2 * w) * r + m),\n            u) {\n            A === 0 && N === 0 && (r < L || r > R) && (A = y - f,\n              N = _ - g);\n            var D = Math.sqrt(A * A + N * N);\n            D && (A /= D,\n              N /= D)\n          }\n          if (s === 3) {\n            var y = 6 * I * r + 2 * S\n              , _ = 6 * E * r + 2 * w\n              , V = Math.pow(A * A + N * N, 3 / 2);\n            A = V !== 0 ? (A * _ - N * y) / V : 0,\n              N = 0\n          }\n        }\n        return s === 2 ? new C(N,-A) : new C(A,N)\n      }\n      return {\n        statics: {\n          classify: function(i) {\n            var r = i[0]\n              , s = i[1]\n              , u = i[2]\n              , o = i[3]\n              , l = i[4]\n              , f = i[5]\n              , g = i[6]\n              , y = i[7]\n              , _ = r * (y - f) + s * (l - g) + g * f - y * l\n              , v = u * (s - y) + o * (g - r) + r * y - s * g\n              , b = l * (o - s) + f * (r - u) + u * s - o * r\n              , T = 3 * b\n              , x = T - v\n              , S = x - v + _\n              , I = Math.sqrt(S * S + x * x + T * T)\n              , m = I !== 0 ? 1 / I : 0\n              , w = O.isZero\n              , E = \"serpentine\";\n            S *= m,\n              x *= m,\n              T *= m;\n            function A(D, V, z) {\n              var G = V !== a\n                , H = G && V > 0 && V < 1\n                , K = G && z > 0 && z < 1;\n              return G && (!(H || K) || D === \"loop\" && !(H && K)) && (D = \"arch\",\n                H = K = !1),\n                {\n                  type: D,\n                  roots: H || K ? H && K ? V < z ? [V, z] : [z, V] : [H ? V : z] : null\n                }\n            }\n            if (w(S))\n              return w(x) ? A(w(T) ? \"line\" : \"quadratic\") : A(E, T / (3 * x));\n            var N = 3 * x * x - 4 * S * T;\n            if (w(N))\n              return A(\"cusp\", x / (2 * S));\n            var L = N > 0 ? Math.sqrt(N / 3) : Math.sqrt(-N)\n              , R = 2 * S;\n            return A(N > 0 ? E : \"loop\", (x + L) / R, (x - L) / R)\n          },\n          getLength: function(i, r, s, u) {\n            if (r === a && (r = 0),\n            s === a && (s = 1),\n              re.isStraight(i)) {\n              var o = i;\n              s < 1 && (o = re.subdivide(o, s)[0],\n                r /= s),\n              r > 0 && (o = re.subdivide(o, r)[1]);\n              var l = o[6] - o[0]\n                , f = o[7] - o[1];\n              return Math.sqrt(l * l + f * f)\n            }\n            return O.integrate(u || e(i), r, s, t(r, s))\n          },\n          getTimeAt: function(i, r, s) {\n            if (s === a && (s = r < 0 ? 1 : 0),\n            r === 0)\n              return s;\n            var u = Math.abs\n              , o = 1e-12\n              , l = r > 0\n              , f = l ? s : 0\n              , g = l ? 1 : s\n              , y = e(i)\n              , _ = re.getLength(i, f, g, y)\n              , v = u(r) - _;\n            if (u(v) < o)\n              return l ? g : f;\n            if (v > o)\n              return null;\n            var b = r / _\n              , T = 0;\n            function x(S) {\n              return T += O.integrate(y, s, S, t(s, S)),\n                s = S,\n              T - r\n            }\n            return O.findRoot(x, y, s + b, f, g, 32, 1e-12)\n          },\n          getPoint: function(i, r) {\n            return n(i, r, 0, !1)\n          },\n          getTangent: function(i, r) {\n            return n(i, r, 1, !0)\n          },\n          getWeightedTangent: function(i, r) {\n            return n(i, r, 1, !1)\n          },\n          getNormal: function(i, r) {\n            return n(i, r, 2, !0)\n          },\n          getWeightedNormal: function(i, r) {\n            return n(i, r, 2, !1)\n          },\n          getCurvature: function(i, r) {\n            return n(i, r, 3, !1).x\n          },\n          getPeaks: function(i) {\n            var r = i[0]\n              , s = i[1]\n              , u = i[2]\n              , o = i[3]\n              , l = i[4]\n              , f = i[5]\n              , g = i[6]\n              , y = i[7]\n              , _ = -r + 3 * u - 3 * l + g\n              , v = 3 * r - 6 * u + 3 * l\n              , b = -3 * r + 3 * u\n              , T = -s + 3 * o - 3 * f + y\n              , x = 3 * s - 6 * o + 3 * f\n              , S = -3 * s + 3 * o\n              , I = 1e-8\n              , m = 1 - I\n              , w = [];\n            return O.solveCubic(9 * (_ * _ + T * T), 9 * (_ * v + x * T), 2 * (v * v + x * x) + 3 * (b * _ + S * T), b * v + x * S, w, I, m),\n              w.sort()\n          }\n        }\n      }\n    }\n    , new function() {\n      function e(v, b, T, x, S, I, m) {\n        var w = !m && T.getPrevious() === S\n          , E = !m && T !== S && T.getNext() === S\n          , A = 1e-8\n          , N = 1 - A;\n        if (x !== null && x >= (w ? A : 0) && x <= (E ? N : 1) && I !== null && I >= (E ? A : 0) && I <= (w ? N : 1)) {\n          var L = new Ot(T,x,null,m)\n            , R = new Ot(S,I,null,m);\n          L._intersection = R,\n            R._intersection = L,\n          (!b || b(L)) && Ot.insert(v, L, !0)\n        }\n      }\n      function t(v, b, T, x, S, I, m, w, E, A, N, L, R) {\n        if (++E >= 4096 || ++w >= 40)\n          return E;\n        var D = 1e-9, V = b[0], z = b[1], G = b[6], H = b[7], K = Se.getSignedDistance, $ = K(V, z, G, H, b[2], b[3]), W = K(V, z, G, H, b[4], b[5]), te = $ * W > 0 ? 3 / 4 : 4 / 9, se = te * Math.min(0, $, W), ue = te * Math.max(0, $, W), Ie = K(V, z, G, H, v[0], v[1]), Ee = K(V, z, G, H, v[2], v[3]), de = K(V, z, G, H, v[4], v[5]), ve = K(V, z, G, H, v[6], v[7]), Oe = n(Ie, Ee, de, ve), Te = Oe[0], Ge = Oe[1], Re, xe;\n        if ($ === 0 && W === 0 && Ie === 0 && Ee === 0 && de === 0 && ve === 0 || (Re = i(Te, Ge, se, ue)) == null || (xe = i(Te.reverse(), Ge.reverse(), se, ue)) == null)\n          return E;\n        var ze = A + (N - A) * Re\n          , De = A + (N - A) * xe;\n        if (Math.max(R - L, De - ze) < D) {\n          var _t = (ze + De) / 2\n            , gt = (L + R) / 2;\n          e(S, I, m ? x : T, m ? gt : _t, m ? T : x, m ? _t : gt)\n        } else {\n          v = re.getPart(v, Re, xe);\n          var Et = R - L;\n          if (xe - Re > .8)\n            if (De - ze > Et) {\n              var nt = re.subdivide(v, .5)\n                , _t = (ze + De) / 2;\n              E = t(b, nt[0], x, T, S, I, !m, w, E, L, R, ze, _t),\n                E = t(b, nt[1], x, T, S, I, !m, w, E, L, R, _t, De)\n            } else {\n              var nt = re.subdivide(b, .5)\n                , gt = (L + R) / 2;\n              E = t(nt[0], v, x, T, S, I, !m, w, E, L, gt, ze, De),\n                E = t(nt[1], v, x, T, S, I, !m, w, E, gt, R, ze, De)\n            }\n          else\n            Et === 0 || Et >= D ? E = t(b, v, x, T, S, I, !m, w, E, L, R, ze, De) : E = t(v, b, T, x, S, I, m, w, E, ze, De, L, R)\n        }\n        return E\n      }\n      function n(v, b, T, x) {\n        var S = [0, v], I = [1 / 3, b], m = [2 / 3, T], w = [1, x], E = b - (2 * v + x) / 3, A = T - (v + 2 * x) / 3, N;\n        if (E * A < 0)\n          N = [[S, I, w], [S, m, w]];\n        else {\n          var L = E / A;\n          N = [L >= 2 ? [S, I, w] : L <= .5 ? [S, m, w] : [S, I, m, w], [S, w]]\n        }\n        return (E || A) < 0 ? N.reverse() : N\n      }\n      function i(v, b, T, x) {\n        return v[0][1] < T ? r(v, !0, T) : b[0][1] > x ? r(b, !1, x) : v[0][0]\n      }\n      function r(v, b, T) {\n        for (var x = v[0][0], S = v[0][1], I = 1, m = v.length; I < m; I++) {\n          var w = v[I][0]\n            , E = v[I][1];\n          if (b ? E >= T : E <= T)\n            return E === T ? w : x + (T - S) * (w - x) / (E - S);\n          x = w,\n            S = E\n        }\n        return null\n      }\n      function s(v, b, T, x, S) {\n        var I = O.isZero;\n        if (I(x) && I(S)) {\n          var m = re.getTimeOf(v, new C(b,T));\n          return m === null ? [] : [m]\n        }\n        for (var w = Math.atan2(-S, x), E = Math.sin(w), A = Math.cos(w), N = [], L = [], R = 0; R < 8; R += 2) {\n          var D = v[R] - b\n            , V = v[R + 1] - T;\n          N.push(D * A - V * E, D * E + V * A)\n        }\n        return re.solveCubic(N, 1, 0, L, 0, 1),\n          L\n      }\n      function u(v, b, T, x, S, I, m) {\n        for (var w = b[0], E = b[1], A = b[6], N = b[7], L = s(v, w, E, A - w, N - E), R = 0, D = L.length; R < D; R++) {\n          var V = L[R]\n            , z = re.getPoint(v, V)\n            , G = re.getTimeOf(b, z);\n          G !== null && e(S, I, m ? x : T, m ? G : V, m ? T : x, m ? V : G)\n        }\n      }\n      function o(v, b, T, x, S, I) {\n        var m = Se.intersect(v[0], v[1], v[6], v[7], b[0], b[1], b[6], b[7]);\n        m && e(S, I, T, re.getTimeOf(v, m), x, re.getTimeOf(b, m))\n      }\n      function l(v, b, T, x, S, I) {\n        var m = 1e-12\n          , w = Math.min\n          , E = Math.max;\n        if (E(v[0], v[2], v[4], v[6]) + m > w(b[0], b[2], b[4], b[6]) && w(v[0], v[2], v[4], v[6]) - m < E(b[0], b[2], b[4], b[6]) && E(v[1], v[3], v[5], v[7]) + m > w(b[1], b[3], b[5], b[7]) && w(v[1], v[3], v[5], v[7]) - m < E(b[1], b[3], b[5], b[7])) {\n          var A = y(v, b);\n          if (A)\n            for (var N = 0; N < 2; N++) {\n              var L = A[N];\n              e(S, I, T, L[0], x, L[1], !0)\n            }\n          else {\n            var R = re.isStraight(v)\n              , D = re.isStraight(b)\n              , V = R && D\n              , z = R && !D\n              , G = S.length;\n            if ((V ? o : R || D ? u : t)(z ? b : v, z ? v : b, z ? x : T, z ? T : x, S, I, z, 0, 0, 0, 1, 0, 1),\n            !V || S.length === G)\n              for (var N = 0; N < 4; N++) {\n                var H = N >> 1\n                  , K = N & 1\n                  , $ = H * 6\n                  , W = K * 6\n                  , te = new C(v[$],v[$ + 1])\n                  , se = new C(b[W],b[W + 1]);\n                te.isClose(se, m) && e(S, I, T, H, x, K)\n              }\n          }\n        }\n        return S\n      }\n      function f(v, b, T, x) {\n        var S = re.classify(v);\n        if (S.type === \"loop\") {\n          var I = S.roots;\n          e(T, x, b, I[0], b, I[1])\n        }\n        return T\n      }\n      function g(v, b, T, x, S, I) {\n        var m = 1e-7\n          , w = !b;\n        w && (b = v);\n        for (var E = v.length, A = b.length, N = new Array(E), L = w ? N : new Array(A), R = [], D = 0; D < E; D++)\n          N[D] = v[D].getValues(x);\n        if (!w)\n          for (var D = 0; D < A; D++)\n            L[D] = b[D].getValues(S);\n        for (var V = q.findCurveBoundsCollisions(N, L, m), z = 0; z < E; z++) {\n          var G = v[z]\n            , H = N[z];\n          w && f(H, G, R, T);\n          var K = V[z];\n          if (K)\n            for (var $ = 0; $ < K.length; $++) {\n              if (I && R.length)\n                return R;\n              var W = K[$];\n              if (!w || W > z) {\n                var te = b[W]\n                  , se = L[W];\n                l(H, se, G, te, R, T)\n              }\n            }\n        }\n        return R\n      }\n      function y(v, b) {\n        function T(ve) {\n          var Oe = ve[6] - ve[0]\n            , Te = ve[7] - ve[1];\n          return Oe * Oe + Te * Te\n        }\n        var x = Math.abs\n          , S = Se.getDistance\n          , I = 1e-8\n          , m = 1e-7\n          , w = re.isStraight(v)\n          , E = re.isStraight(b)\n          , A = w && E\n          , N = T(v) < T(b)\n          , L = N ? b : v\n          , R = N ? v : b\n          , D = L[0]\n          , V = L[1]\n          , z = L[6] - D\n          , G = L[7] - V;\n        if (S(D, V, z, G, R[0], R[1], !0) < m && S(D, V, z, G, R[6], R[7], !0) < m)\n          !A && S(D, V, z, G, L[2], L[3], !0) < m && S(D, V, z, G, L[4], L[5], !0) < m && S(D, V, z, G, R[2], R[3], !0) < m && S(D, V, z, G, R[4], R[5], !0) < m && (w = E = A = !0);\n        else if (A)\n          return null;\n        if (w ^ E)\n          return null;\n        for (var H = [v, b], K = [], $ = 0; $ < 4 && K.length < 2; $++) {\n          var W = $ & 1\n            , te = W ^ 1\n            , se = $ >> 1\n            , ue = re.getTimeOf(H[W], new C(H[te][se ? 6 : 0],H[te][se ? 7 : 1]));\n          if (ue != null) {\n            var Ie = W ? [se, ue] : [ue, se];\n            (!K.length || x(Ie[0] - K[0][0]) > I && x(Ie[1] - K[0][1]) > I) && K.push(Ie)\n          }\n          if ($ > 2 && !K.length)\n            break\n        }\n        if (K.length !== 2)\n          K = null;\n        else if (!A) {\n          var Ee = re.getPart(v, K[0][0], K[1][0])\n            , de = re.getPart(b, K[0][1], K[1][1]);\n          (x(de[2] - Ee[2]) > m || x(de[3] - Ee[3]) > m || x(de[4] - Ee[4]) > m || x(de[5] - Ee[5]) > m) && (K = null)\n        }\n        return K\n      }\n      function _(v, b) {\n        var T = v[0]\n          , x = v[1]\n          , S = v[2]\n          , I = v[3]\n          , m = v[4]\n          , w = v[5]\n          , E = v[6]\n          , A = v[7]\n          , N = b.normalize()\n          , L = N.x\n          , R = N.y\n          , D = 3 * E - 9 * m + 9 * S - 3 * T\n          , V = 3 * A - 9 * w + 9 * I - 3 * x\n          , z = 6 * m - 12 * S + 6 * T\n          , G = 6 * w - 12 * I + 6 * x\n          , H = 3 * S - 3 * T\n          , K = 3 * I - 3 * x\n          , $ = 2 * D * R - 2 * V * L\n          , W = [];\n        if (Math.abs($) < O.CURVETIME_EPSILON) {\n          var te = D * K - V * H\n            , $ = D * G - V * z;\n          if ($ != 0) {\n            var se = -te / $;\n            se >= 0 && se <= 1 && W.push(se)\n          }\n        } else {\n          var ue = (z * z - 4 * D * H) * R * R + (-2 * z * G + 4 * V * H + 4 * D * K) * L * R + (G * G - 4 * V * K) * L * L\n            , Ie = z * R - G * L;\n          if (ue >= 0 && $ != 0) {\n            var Ee = Math.sqrt(ue)\n              , de = -(Ie + Ee) / $\n              , ve = (-Ie + Ee) / $;\n            de >= 0 && de <= 1 && W.push(de),\n            ve >= 0 && ve <= 1 && W.push(ve)\n          }\n        }\n        return W\n      }\n      return {\n        getIntersections: function(v) {\n          var b = this.getValues()\n            , T = v && v !== this && v.getValues();\n          return T ? l(b, T, this, v, []) : f(b, this, [])\n        },\n        statics: {\n          getOverlaps: y,\n          getIntersections: g,\n          getCurveLineIntersections: s,\n          getTimesWithTangent: _\n        }\n      }\n    }\n  )\n    , Ot = d.extend({\n      _class: \"CurveLocation\",\n      initialize: function(t, n, i, r, s) {\n        if (n >= .99999999) {\n          var u = t.getNext();\n          u && (n = 0,\n            t = u)\n        }\n        this._setCurve(t),\n          this._time = n,\n          this._point = i || t.getPointAtTime(n),\n          this._overlap = r,\n          this._distance = s,\n          this._intersection = this._next = this._previous = null\n      },\n      _setPath: function(e) {\n        this._path = e,\n          this._version = e ? e._version : 0\n      },\n      _setCurve: function(e) {\n        this._setPath(e._path),\n          this._curve = e,\n          this._segment = null,\n          this._segment1 = e._segment1,\n          this._segment2 = e._segment2\n      },\n      _setSegment: function(e) {\n        var t = e.getCurve();\n        t ? this._setCurve(t) : (this._setPath(e._path),\n          this._segment1 = e,\n          this._segment2 = null),\n          this._segment = e,\n          this._time = e === this._segment1 ? 0 : 1,\n          this._point = e._point.clone()\n      },\n      getSegment: function() {\n        var e = this._segment;\n        if (!e) {\n          var t = this.getCurve()\n            , n = this.getTime();\n          n === 0 ? e = t._segment1 : n === 1 ? e = t._segment2 : n != null && (e = t.getPartLength(0, n) < t.getPartLength(n, 1) ? t._segment1 : t._segment2),\n            this._segment = e\n        }\n        return e\n      },\n      getCurve: function() {\n        var e = this._path\n          , t = this;\n        e && e._version !== this._version && (this._time = this._offset = this._curveOffset = this._curve = null);\n        function n(i) {\n          var r = i && i.getCurve();\n          if (r && (t._time = r.getTimeOf(t._point)) != null)\n            return t._setCurve(r),\n              r\n        }\n        return this._curve || n(this._segment) || n(this._segment1) || n(this._segment2.getPrevious())\n      },\n      getPath: function() {\n        var e = this.getCurve();\n        return e && e._path\n      },\n      getIndex: function() {\n        var e = this.getCurve();\n        return e && e.getIndex()\n      },\n      getTime: function() {\n        var e = this.getCurve()\n          , t = this._time;\n        return e && t == null ? this._time = e.getTimeOf(this._point) : t\n      },\n      getParameter: \"#getTime\",\n      getPoint: function() {\n        return this._point\n      },\n      getOffset: function() {\n        var e = this._offset;\n        if (e == null) {\n          e = 0;\n          var t = this.getPath()\n            , n = this.getIndex();\n          if (t && n != null)\n            for (var i = t.getCurves(), r = 0; r < n; r++)\n              e += i[r].getLength();\n          this._offset = e += this.getCurveOffset()\n        }\n        return e\n      },\n      getCurveOffset: function() {\n        var e = this._curveOffset;\n        if (e == null) {\n          var t = this.getCurve()\n            , n = this.getTime();\n          this._curveOffset = e = n != null && t && t.getPartLength(0, n)\n        }\n        return e\n      },\n      getIntersection: function() {\n        return this._intersection\n      },\n      getDistance: function() {\n        return this._distance\n      },\n      divide: function() {\n        var e = this.getCurve()\n          , t = e && e.divideAtTime(this.getTime());\n        return t && this._setSegment(t._segment1),\n          t\n      },\n      split: function() {\n        var e = this.getCurve()\n          , t = e._path\n          , n = e && e.splitAtTime(this.getTime());\n        return n && this._setSegment(t.getLastSegment()),\n          n\n      },\n      equals: function(e, t) {\n        var n = this === e;\n        if (!n && e instanceof Ot) {\n          var i = this.getCurve()\n            , r = e.getCurve()\n            , s = i._path\n            , u = r._path;\n          if (s === u) {\n            var o = Math.abs\n              , l = 1e-7\n              , f = o(this.getOffset() - e.getOffset())\n              , g = !t && this._intersection\n              , y = !t && e._intersection;\n            n = (f < l || s && o(s.getLength() - f) < l) && (!g && !y || g && y && g.equals(y, !0))\n          }\n        }\n        return n\n      },\n      toString: function() {\n        var e = []\n          , t = this.getPoint()\n          , n = k.instance;\n        t && e.push(\"point: \" + t);\n        var i = this.getIndex();\n        i != null && e.push(\"index: \" + i);\n        var r = this.getTime();\n        return r != null && e.push(\"time: \" + n.number(r)),\n        this._distance != null && e.push(\"distance: \" + n.number(this._distance)),\n        \"{ \" + e.join(\", \") + \" }\"\n      },\n      isTouching: function() {\n        var e = this._intersection;\n        if (e && this.getTangent().isCollinear(e.getTangent())) {\n          var t = this.getCurve()\n            , n = e.getCurve();\n          return !(t.isStraight() && n.isStraight() && t.getLine().intersect(n.getLine()))\n        }\n        return !1\n      },\n      isCrossing: function() {\n        var e = this._intersection;\n        if (!e)\n          return !1;\n        var t = this.getTime()\n          , n = e.getTime()\n          , i = 1e-8\n          , r = 1 - i\n          , s = t >= i && t <= r\n          , u = n >= i && n <= r;\n        if (s && u)\n          return !this.isTouching();\n        var o = this.getCurve()\n          , l = o && t < i ? o.getPrevious() : o\n          , f = e.getCurve()\n          , g = f && n < i ? f.getPrevious() : f;\n        if (t > r && (o = o.getNext()),\n        n > r && (f = f.getNext()),\n        !l || !o || !g || !f)\n          return !1;\n        var y = [];\n        function _(L, R) {\n          var D = L.getValues()\n            , V = re.classify(D).roots || re.getPeaks(D)\n            , z = V.length\n            , G = re.getLength(D, R && z ? V[z - 1] : 0, !R && z ? V[0] : 1);\n          y.push(z ? G : G / 32)\n        }\n        function v(L, R, D) {\n          return R < D ? L > R && L < D : L > R || L < D\n        }\n        s || (_(l, !0),\n          _(o, !1)),\n        u || (_(g, !0),\n          _(f, !1));\n        var b = this.getPoint()\n          , T = Math.min.apply(Math, y)\n          , x = s ? o.getTangentAtTime(t) : o.getPointAt(T).subtract(b)\n          , S = s ? x.negate() : l.getPointAt(-T).subtract(b)\n          , I = u ? f.getTangentAtTime(n) : f.getPointAt(T).subtract(b)\n          , m = u ? I.negate() : g.getPointAt(-T).subtract(b)\n          , w = S.getAngle()\n          , E = x.getAngle()\n          , A = m.getAngle()\n          , N = I.getAngle();\n        return !!(s ? v(w, A, N) ^ v(E, A, N) && v(w, N, A) ^ v(E, N, A) : v(A, w, E) ^ v(N, w, E) && v(A, E, w) ^ v(N, E, w))\n      },\n      hasOverlap: function() {\n        return !!this._overlap\n      }\n    }, d.each(re._evaluateMethods, function(e) {\n      var t = e + \"At\";\n      this[e] = function() {\n        var n = this.getCurve()\n          , i = this.getTime();\n        return i != null && n && n[t](i, !0)\n      }\n    }, {\n      preserve: !0\n    }), new function() {\n      function e(t, n, i) {\n        var r = t.length\n          , s = 0\n          , u = r - 1;\n        function o(b, T) {\n          for (var x = b + T; x >= -1 && x <= r; x += T) {\n            var S = t[(x % r + r) % r];\n            if (!n.getPoint().isClose(S.getPoint(), 1e-7))\n              break;\n            if (n.equals(S))\n              return S\n          }\n          return null\n        }\n        for (; s <= u; ) {\n          var l = s + u >>> 1, f = t[l], g;\n          if (i && (g = n.equals(f) ? f : o(l, -1) || o(l, 1)))\n            return n._overlap && (g._overlap = g._intersection._overlap = !0),\n              g;\n          var y = n.getPath()\n            , _ = f.getPath()\n            , v = y !== _ ? y._id - _._id : n.getIndex() + n.getTime() - (f.getIndex() + f.getTime());\n          v < 0 ? u = l - 1 : s = l + 1\n        }\n        return t.splice(s, 0, n),\n          n\n      }\n      return {\n        statics: {\n          insert: e,\n          expand: function(t) {\n            for (var n = t.slice(), i = t.length - 1; i >= 0; i--)\n              e(n, t[i]._intersection, !1);\n            return n\n          }\n        }\n      }\n    }\n  )\n    , Ft = oe.extend({\n    _class: \"PathItem\",\n    _selectBounds: !1,\n    _canScaleStroke: !0,\n    beans: !0,\n    initialize: function() {},\n    statics: {\n      create: function(e) {\n        var t, n, i;\n        if (d.isPlainObject(e) ? (n = e.segments,\n          t = e.pathData) : Array.isArray(e) ? n = e : typeof e == \"string\" && (t = e),\n          n) {\n          var r = n[0];\n          i = r && Array.isArray(r[0])\n        } else\n          t && (i = (t.match(/m/gi) || []).length > 1 || /z\\s*\\S+/i.test(t));\n        var s = i ? ot : ke;\n        return new s(e)\n      }\n    },\n    _asPathItem: function() {\n      return this\n    },\n    isClockwise: function() {\n      return this.getArea() >= 0\n    },\n    setClockwise: function(e) {\n      this.isClockwise() != (e = !!e) && this.reverse()\n    },\n    setPathData: function(e) {\n      var t = e && e.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), n, i = !1, r, s, u = new C, o = new C;\n      function l(m, w) {\n        var E = +n[m];\n        return i && (E += u[w]),\n          E\n      }\n      function f(m) {\n        return new C(l(m, \"x\"),l(m + 1, \"y\"))\n      }\n      this.clear();\n      for (var g = 0, y = t && t.length; g < y; g++) {\n        var _ = t[g]\n          , v = _[0]\n          , b = v.toLowerCase();\n        n = _.match(/[+-]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][+-]?\\d+)?/g);\n        var T = n && n.length;\n        switch (i = v === b,\n        r === \"z\" && !/[mz]/.test(b) && this.moveTo(u),\n          b) {\n          case \"m\":\n          case \"l\":\n            for (var x = b === \"m\", S = 0; S < T; S += 2)\n              this[x ? \"moveTo\" : \"lineTo\"](u = f(S)),\n              x && (o = u,\n                x = !1);\n            s = u;\n            break;\n          case \"h\":\n          case \"v\":\n            var I = b === \"h\" ? \"x\" : \"y\";\n            u = u.clone();\n            for (var S = 0; S < T; S++)\n              u[I] = l(S, I),\n                this.lineTo(u);\n            s = u;\n            break;\n          case \"c\":\n            for (var S = 0; S < T; S += 6)\n              this.cubicCurveTo(f(S), s = f(S + 2), u = f(S + 4));\n            break;\n          case \"s\":\n            for (var S = 0; S < T; S += 4)\n              this.cubicCurveTo(/[cs]/.test(r) ? u.multiply(2).subtract(s) : u, s = f(S), u = f(S + 2)),\n                r = b;\n            break;\n          case \"q\":\n            for (var S = 0; S < T; S += 4)\n              this.quadraticCurveTo(s = f(S), u = f(S + 2));\n            break;\n          case \"t\":\n            for (var S = 0; S < T; S += 2)\n              this.quadraticCurveTo(s = /[qt]/.test(r) ? u.multiply(2).subtract(s) : u, u = f(S)),\n                r = b;\n            break;\n          case \"a\":\n            for (var S = 0; S < T; S += 7)\n              this.arcTo(u = f(S + 5), new J(+n[S],+n[S + 1]), +n[S + 2], +n[S + 4], +n[S + 3]);\n            break;\n          case \"z\":\n            this.closePath(1e-12),\n              u = o;\n            break\n        }\n        r = b\n      }\n    },\n    _canComposite: function() {\n      return !(this.hasFill() && this.hasStroke())\n    },\n    _contains: function(e) {\n      var t = e.isInside(this.getBounds({\n        internal: !0,\n        handle: !0\n      })) ? this._getWinding(e) : {};\n      return t.onPath || !!(this.getFillRule() === \"evenodd\" ? t.windingL & 1 || t.windingR & 1 : t.winding)\n    },\n    getIntersections: function(e, t, n, i) {\n      var r = this === e || !e\n        , s = this._matrix._orNullIfIdentity()\n        , u = r ? s : (n || e._matrix)._orNullIfIdentity();\n      return r || this.getBounds(s).intersects(e.getBounds(u), 1e-12) ? re.getIntersections(this.getCurves(), !r && e.getCurves(), t, s, u, i) : []\n    },\n    getCrossings: function(e) {\n      return this.getIntersections(e, function(t) {\n        return t.isCrossing()\n      })\n    },\n    getNearestLocation: function() {\n      for (var e = C.read(arguments), t = this.getCurves(), n = 1 / 0, i = null, r = 0, s = t.length; r < s; r++) {\n        var u = t[r].getNearestLocation(e);\n        u._distance < n && (n = u._distance,\n          i = u)\n      }\n      return i\n    },\n    getNearestPoint: function() {\n      var e = this.getNearestLocation.apply(this, arguments);\n      return e && e.getPoint()\n    },\n    interpolate: function(e, t, n) {\n      var i = !this._children\n        , r = i ? \"_segments\" : \"_children\"\n        , s = e[r]\n        , u = t[r]\n        , o = this[r];\n      if (!s || !u || s.length !== u.length)\n        throw new Error(\"Invalid operands in interpolate() call: \" + e + \", \" + t);\n      var l = o.length\n        , f = u.length;\n      if (l < f)\n        for (var g = i ? pe : ke, y = l; y < f; y++)\n          this.add(new g);\n      else\n        l > f && this[i ? \"removeSegments\" : \"removeChildren\"](f, l);\n      for (var y = 0; y < f; y++)\n        o[y].interpolate(s[y], u[y], n);\n      i && (this.setClosed(e._closed),\n        this._changed(9))\n    },\n    compare: function(e) {\n      var t = !1;\n      if (e) {\n        var n = this._children || [this]\n          , i = e._children ? e._children.slice() : [e]\n          , r = n.length\n          , s = i.length\n          , u = []\n          , o = 0;\n        t = !0;\n        for (var l = q.findItemBoundsCollisions(n, i, O.GEOMETRIC_EPSILON), f = r - 1; f >= 0 && t; f--) {\n          var g = n[f];\n          t = !1;\n          var y = l[f];\n          if (y)\n            for (var _ = y.length - 1; _ >= 0 && !t; _--)\n              g.compare(i[y[_]]) && (u[y[_]] || (u[y[_]] = !0,\n                o++),\n                t = !0)\n        }\n        t = t && o === s\n      }\n      return t\n    }\n  })\n    , ke = Ft.extend({\n      _class: \"Path\",\n      _serializeFields: {\n        segments: [],\n        closed: !1\n      },\n      initialize: function(t) {\n        this._closed = !1,\n          this._segments = [],\n          this._version = 0;\n        var n = arguments\n          , i = Array.isArray(t) ? typeof t[0] == \"object\" ? t : n : t && t.size === a && (t.x !== a || t.point !== a) ? n : null;\n        i && i.length > 0 ? this.setSegments(i) : (this._curves = a,\n          this._segmentSelection = 0,\n        !i && typeof t == \"string\" && (this.setPathData(t),\n          t = null)),\n          this._initialize(!i && t)\n      },\n      _equals: function(e) {\n        return this._closed === e._closed && d.equals(this._segments, e._segments)\n      },\n      copyContent: function(e) {\n        this.setSegments(e._segments),\n          this._closed = e._closed\n      },\n      _changed: function e(t) {\n        if (e.base.call(this, t),\n        t & 8) {\n          if (this._length = this._area = a,\n          t & 32)\n            this._version++;\n          else if (this._curves)\n            for (var n = 0, i = this._curves.length; n < i; n++)\n              this._curves[n]._changed()\n        } else\n          t & 64 && (this._bounds = a)\n      },\n      getStyle: function() {\n        var e = this._parent;\n        return (e instanceof ot ? e : this)._style\n      },\n      getSegments: function() {\n        return this._segments\n      },\n      setSegments: function(e) {\n        var t = this.isFullySelected()\n          , n = e && e.length;\n        if (this._segments.length = 0,\n          this._segmentSelection = 0,\n          this._curves = a,\n          n) {\n          var i = e[n - 1];\n          typeof i == \"boolean\" && (this.setClosed(i),\n            n--),\n            this._add(pe.readList(e, 0, {}, n))\n        }\n        t && this.setFullySelected(!0)\n      },\n      getFirstSegment: function() {\n        return this._segments[0]\n      },\n      getLastSegment: function() {\n        return this._segments[this._segments.length - 1]\n      },\n      getCurves: function() {\n        var e = this._curves\n          , t = this._segments;\n        if (!e) {\n          var n = this._countCurves();\n          e = this._curves = new Array(n);\n          for (var i = 0; i < n; i++)\n            e[i] = new re(this,t[i],t[i + 1] || t[0])\n        }\n        return e\n      },\n      getFirstCurve: function() {\n        return this.getCurves()[0]\n      },\n      getLastCurve: function() {\n        var e = this.getCurves();\n        return e[e.length - 1]\n      },\n      isClosed: function() {\n        return this._closed\n      },\n      setClosed: function(e) {\n        if (this._closed != (e = !!e)) {\n          if (this._closed = e,\n            this._curves) {\n            var t = this._curves.length = this._countCurves();\n            e && (this._curves[t - 1] = new re(this,this._segments[t - 1],this._segments[0]))\n          }\n          this._changed(41)\n        }\n      }\n    }, {\n      beans: !0,\n      getPathData: function(e, t) {\n        var n = this._segments, i = n.length, r = new k(t), s = new Array(6), u = !0, o, l, f, g, y, _, v, b, T = [];\n        function x(I, m) {\n          if (I._transformCoordinates(e, s),\n            o = s[0],\n            l = s[1],\n            u)\n            T.push(\"M\" + r.pair(o, l)),\n              u = !1;\n          else if (y = s[2],\n            _ = s[3],\n          y === o && _ === l && v === f && b === g) {\n            if (!m) {\n              var w = o - f\n                , E = l - g;\n              T.push(w === 0 ? \"v\" + r.number(E) : E === 0 ? \"h\" + r.number(w) : \"l\" + r.pair(w, E))\n            }\n          } else\n            T.push(\"c\" + r.pair(v - f, b - g) + \" \" + r.pair(y - f, _ - g) + \" \" + r.pair(o - f, l - g));\n          f = o,\n            g = l,\n            v = s[4],\n            b = s[5]\n        }\n        if (!i)\n          return \"\";\n        for (var S = 0; S < i; S++)\n          x(n[S]);\n        return this._closed && i > 0 && (x(n[0], !0),\n          T.push(\"z\")),\n          T.join(\"\")\n      },\n      isEmpty: function() {\n        return !this._segments.length\n      },\n      _transformContent: function(e) {\n        for (var t = this._segments, n = new Array(6), i = 0, r = t.length; i < r; i++)\n          t[i]._transformCoordinates(e, n, !0);\n        return !0\n      },\n      _add: function(e, u) {\n        for (var n = this._segments, i = this._curves, r = e.length, s = u == null, u = s ? n.length : u, o = 0; o < r; o++) {\n          var l = e[o];\n          l._path && (l = e[o] = l.clone()),\n            l._path = this,\n            l._index = u + o,\n          l._selection && this._updateSelection(l, 0, l._selection)\n        }\n        if (s)\n          d.push(n, e);\n        else {\n          n.splice.apply(n, [u, 0].concat(e));\n          for (var o = u + r, f = n.length; o < f; o++)\n            n[o]._index = o\n        }\n        if (i) {\n          var g = this._countCurves()\n            , y = u > 0 && u + r - 1 === g ? u - 1 : u\n            , _ = y\n            , v = Math.min(y + r, g);\n          e._curves && (i.splice.apply(i, [y, 0].concat(e._curves)),\n            _ += e._curves.length);\n          for (var o = _; o < v; o++)\n            i.splice(o, 0, new re(this,null,null));\n          this._adjustCurves(y, v)\n        }\n        return this._changed(41),\n          e\n      },\n      _adjustCurves: function(e, t) {\n        for (var n = this._segments, i = this._curves, r, s = e; s < t; s++)\n          r = i[s],\n            r._path = this,\n            r._segment1 = n[s],\n            r._segment2 = n[s + 1] || n[0],\n            r._changed();\n        (r = i[this._closed && !e ? n.length - 1 : e - 1]) && (r._segment2 = n[e] || n[0],\n          r._changed()),\n        (r = i[t]) && (r._segment1 = n[t],\n          r._changed())\n      },\n      _countCurves: function() {\n        var e = this._segments.length;\n        return !this._closed && e > 0 ? e - 1 : e\n      },\n      add: function(e) {\n        var t = arguments;\n        return t.length > 1 && typeof e != \"number\" ? this._add(pe.readList(t)) : this._add([pe.read(t)])[0]\n      },\n      insert: function(e, t) {\n        var n = arguments;\n        return n.length > 2 && typeof t != \"number\" ? this._add(pe.readList(n, 1), e) : this._add([pe.read(n, 1)], e)[0]\n      },\n      addSegment: function() {\n        return this._add([pe.read(arguments)])[0]\n      },\n      insertSegment: function(e) {\n        return this._add([pe.read(arguments, 1)], e)[0]\n      },\n      addSegments: function(e) {\n        return this._add(pe.readList(e))\n      },\n      insertSegments: function(e, t) {\n        return this._add(pe.readList(t), e)\n      },\n      removeSegment: function(e) {\n        return this.removeSegments(e, e + 1)[0] || null\n      },\n      removeSegments: function(e, t, n) {\n        e = e || 0,\n          t = d.pick(t, this._segments.length);\n        var i = this._segments\n          , r = this._curves\n          , s = i.length\n          , u = i.splice(e, t - e)\n          , o = u.length;\n        if (!o)\n          return u;\n        for (var l = 0; l < o; l++) {\n          var f = u[l];\n          f._selection && this._updateSelection(f, f._selection, 0),\n            f._index = f._path = null\n        }\n        for (var l = e, g = i.length; l < g; l++)\n          i[l]._index = l;\n        if (r) {\n          for (var y = e > 0 && t === s + (this._closed ? 1 : 0) ? e - 1 : e, r = r.splice(y, o), l = r.length - 1; l >= 0; l--)\n            r[l]._path = null;\n          n && (u._curves = r.slice(1)),\n            this._adjustCurves(y, y)\n        }\n        return this._changed(41),\n          u\n      },\n      clear: \"#removeSegments\",\n      hasHandles: function() {\n        for (var e = this._segments, t = 0, n = e.length; t < n; t++)\n          if (e[t].hasHandles())\n            return !0;\n        return !1\n      },\n      clearHandles: function() {\n        for (var e = this._segments, t = 0, n = e.length; t < n; t++)\n          e[t].clearHandles()\n      },\n      getLength: function() {\n        if (this._length == null) {\n          for (var e = this.getCurves(), t = 0, n = 0, i = e.length; n < i; n++)\n            t += e[n].getLength();\n          this._length = t\n        }\n        return this._length\n      },\n      getArea: function() {\n        var e = this._area;\n        if (e == null) {\n          var t = this._segments\n            , n = this._closed;\n          e = 0;\n          for (var i = 0, r = t.length; i < r; i++) {\n            var s = i + 1 === r;\n            e += re.getArea(re.getValues(t[i], t[s ? 0 : i + 1], null, s && !n))\n          }\n          this._area = e\n        }\n        return e\n      },\n      isFullySelected: function() {\n        var e = this._segments.length;\n        return this.isSelected() && e > 0 && this._segmentSelection === e * 7\n      },\n      setFullySelected: function(e) {\n        e && this._selectSegments(!0),\n          this.setSelected(e)\n      },\n      setSelection: function e(t) {\n        t & 1 || this._selectSegments(!1),\n          e.base.call(this, t)\n      },\n      _selectSegments: function(e) {\n        var t = this._segments\n          , n = t.length\n          , i = e ? 7 : 0;\n        this._segmentSelection = i * n;\n        for (var r = 0; r < n; r++)\n          t[r]._selection = i\n      },\n      _updateSelection: function(e, t, n) {\n        e._selection = n;\n        var i = this._segmentSelection += n - t;\n        i > 0 && this.setSelected(!0)\n      },\n      divideAt: function(e) {\n        var t = this.getLocationAt(e), n;\n        return t && (n = t.getCurve().divideAt(t.getCurveOffset())) ? n._segment1 : null\n      },\n      splitAt: function(e) {\n        var t = this.getLocationAt(e)\n          , n = t && t.index\n          , i = t && t.time\n          , r = 1e-8\n          , s = 1 - r;\n        i > s && (n++,\n          i = 0);\n        var u = this.getCurves();\n        if (n >= 0 && n < u.length) {\n          i >= r && u[n++].divideAtTime(i);\n          var o = this.removeSegments(n, this._segments.length, !0), l;\n          return this._closed ? (this.setClosed(!1),\n            l = this) : (l = new ke(oe.NO_INSERT),\n            l.insertAbove(this),\n            l.copyAttributes(this)),\n            l._add(o, 0),\n            this.addSegment(o[0]),\n            l\n        }\n        return null\n      },\n      split: function(e, t) {\n        var n, i = t === a ? e : (n = this.getCurves()[e]) && n.getLocationAtTime(t);\n        return i != null ? this.splitAt(i) : null\n      },\n      join: function(e, t) {\n        var n = t || 0;\n        if (e && e !== this) {\n          var i = e._segments\n            , r = this.getLastSegment()\n            , s = e.getLastSegment();\n          if (!s)\n            return this;\n          r && r._point.isClose(s._point, n) && e.reverse();\n          var u = e.getFirstSegment();\n          if (r && r._point.isClose(u._point, n))\n            r.setHandleOut(u._handleOut),\n              this._add(i.slice(1));\n          else {\n            var o = this.getFirstSegment();\n            o && o._point.isClose(u._point, n) && e.reverse(),\n              s = e.getLastSegment(),\n              o && o._point.isClose(s._point, n) ? (o.setHandleIn(s._handleIn),\n                this._add(i.slice(0, i.length - 1), 0)) : this._add(i.slice())\n          }\n          e._closed && this._add([i[0]]),\n            e.remove()\n        }\n        var l = this.getFirstSegment()\n          , f = this.getLastSegment();\n        return l !== f && l._point.isClose(f._point, n) && (l.setHandleIn(f._handleIn),\n          f.remove(),\n          this.setClosed(!0)),\n          this\n      },\n      reduce: function(e) {\n        for (var t = this.getCurves(), n = e && e.simplify, i = n ? 1e-7 : 0, r = t.length - 1; r >= 0; r--) {\n          var s = t[r];\n          !s.hasHandles() && (!s.hasLength(i) || n && s.isCollinear(s.getNext())) && s.remove()\n        }\n        return this\n      },\n      reverse: function() {\n        this._segments.reverse();\n        for (var e = 0, t = this._segments.length; e < t; e++) {\n          var n = this._segments[e]\n            , i = n._handleIn;\n          n._handleIn = n._handleOut,\n            n._handleOut = i,\n            n._index = e\n        }\n        this._curves = null,\n          this._changed(9)\n      },\n      flatten: function(e) {\n        for (var t = new kt(this,e || .25,256,!0), n = t.parts, i = n.length, r = [], s = 0; s < i; s++)\n          r.push(new pe(n[s].curve.slice(0, 2)));\n        !this._closed && i > 0 && r.push(new pe(n[i - 1].curve.slice(6))),\n          this.setSegments(r)\n      },\n      simplify: function(e) {\n        var t = new yn(this).fit(e || 2.5);\n        return t && this.setSegments(t),\n          !!t\n      },\n      smooth: function(e) {\n        var t = this\n          , n = e || {}\n          , i = n.type || \"asymmetric\"\n          , r = this._segments\n          , s = r.length\n          , u = this._closed;\n        function o(Te, Ge) {\n          var Re = Te && Te.index;\n          if (Re != null) {\n            var xe = Te.path;\n            if (xe && xe !== t)\n              throw new Error(Te._class + \" \" + Re + \" of \" + xe + \" is not part of \" + t);\n            Ge && Te instanceof re && Re++\n          } else\n            Re = typeof Te == \"number\" ? Te : Ge;\n          return Math.min(Re < 0 && u ? Re % s : Re < 0 ? Re + s : Re, s - 1)\n        }\n        var l = u && n.from === a && n.to === a\n          , f = o(n.from, 0)\n          , g = o(n.to, s - 1);\n        if (f > g)\n          if (u)\n            f -= s;\n          else {\n            var y = f;\n            f = g,\n              g = y\n          }\n        if (/^(?:asymmetric|continuous)$/.test(i)) {\n          var _ = i === \"asymmetric\"\n            , v = Math.min\n            , b = g - f + 1\n            , T = b - 1\n            , x = l ? v(b, 4) : 1\n            , S = x\n            , I = x\n            , m = [];\n          if (u || (S = v(1, f),\n            I = v(1, s - g - 1)),\n            T += S + I,\n          T <= 1)\n            return;\n          for (var w = 0, E = f - S; w <= T; w++,\n            E++)\n            m[w] = r[(E < 0 ? E + s : E) % s]._point;\n          for (var A = m[0]._x + 2 * m[1]._x, N = m[0]._y + 2 * m[1]._y, L = 2, R = T - 1, D = [A], V = [N], z = [L], G = [], H = [], w = 1; w < T; w++) {\n            var K = w < R\n              , $ = K || _ ? 1 : 2\n              , W = K ? 4 : _ ? 2 : 7\n              , te = K ? 4 : _ ? 3 : 8\n              , se = K ? 2 : _ ? 0 : 1\n              , ue = $ / L;\n            L = z[w] = W - ue,\n              A = D[w] = te * m[w]._x + se * m[w + 1]._x - ue * A,\n              N = V[w] = te * m[w]._y + se * m[w + 1]._y - ue * N\n          }\n          G[R] = D[R] / z[R],\n            H[R] = V[R] / z[R];\n          for (var w = T - 2; w >= 0; w--)\n            G[w] = (D[w] - G[w + 1]) / z[w],\n              H[w] = (V[w] - H[w + 1]) / z[w];\n          G[T] = (3 * m[T]._x - G[R]) / 2,\n            H[T] = (3 * m[T]._y - H[R]) / 2;\n          for (var w = S, Ie = T - I, E = f; w <= Ie; w++,\n            E++) {\n            var Ee = r[E < 0 ? E + s : E]\n              , de = Ee._point\n              , ve = G[w] - de._x\n              , Oe = H[w] - de._y;\n            (l || w < Ie) && Ee.setHandleOut(ve, Oe),\n            (l || w > S) && Ee.setHandleIn(-ve, -Oe)\n          }\n        } else\n          for (var w = f; w <= g; w++)\n            r[w < 0 ? w + s : w].smooth(n, !l && w === f, !l && w === g)\n      },\n      toShape: function(e) {\n        if (!this._closed)\n          return null;\n        var t = this._segments, n, i, r, s;\n        function u(_, v) {\n          var b = t[_]\n            , T = b.getNext()\n            , x = t[v]\n            , S = x.getNext();\n          return b._handleOut.isZero() && T._handleIn.isZero() && x._handleOut.isZero() && S._handleIn.isZero() && T._point.subtract(b._point).isCollinear(S._point.subtract(x._point))\n        }\n        function o(_) {\n          var v = t[_]\n            , b = v.getPrevious()\n            , T = v.getNext();\n          return b._handleOut.isZero() && v._handleIn.isZero() && v._handleOut.isZero() && T._handleIn.isZero() && v._point.subtract(b._point).isOrthogonal(T._point.subtract(v._point))\n        }\n        function l(_) {\n          var v = t[_]\n            , b = v.getNext()\n            , T = v._handleOut\n            , x = b._handleIn\n            , S = .5522847498307936;\n          if (T.isOrthogonal(x)) {\n            var I = v._point\n              , m = b._point\n              , w = new Se(I,T,!0).intersect(new Se(m,x,!0), !0);\n            return w && O.isZero(T.getLength() / w.subtract(I).getLength() - S) && O.isZero(x.getLength() / w.subtract(m).getLength() - S)\n          }\n          return !1\n        }\n        function f(_, v) {\n          return t[_]._point.getDistance(t[v]._point)\n        }\n        if (!this.hasHandles() && t.length === 4 && u(0, 2) && u(1, 3) && o(1) ? (n = je.Rectangle,\n          i = new J(f(0, 3),f(0, 1)),\n          s = t[1]._point.add(t[2]._point).divide(2)) : t.length === 8 && l(0) && l(2) && l(4) && l(6) && u(1, 5) && u(3, 7) ? (n = je.Rectangle,\n          i = new J(f(1, 6),f(0, 3)),\n          r = i.subtract(new J(f(0, 7),f(1, 2))).divide(2),\n          s = t[3]._point.add(t[4]._point).divide(2)) : t.length === 4 && l(0) && l(1) && l(2) && l(3) && (O.isZero(f(0, 2) - f(1, 3)) ? (n = je.Circle,\n          r = f(0, 2) / 2) : (n = je.Ellipse,\n          r = new J(f(2, 0) / 2,f(3, 1) / 2)),\n          s = t[1]._point),\n          n) {\n          var g = this.getPosition(!0)\n            , y = new n({\n            center: g,\n            size: i,\n            radius: r,\n            insert: !1\n          });\n          return y.copyAttributes(this, !0),\n            y._matrix.prepend(this._matrix),\n            y.rotate(s.subtract(g).getAngle() + 90),\n          (e === a || e) && y.insertAbove(this),\n            y\n        }\n        return null\n      },\n      toPath: \"#clone\",\n      compare: function e(t) {\n        if (!t || t instanceof ot)\n          return e.base.call(this, t);\n        var n = this.getCurves()\n          , i = t.getCurves()\n          , r = n.length\n          , s = i.length;\n        if (!r || !s)\n          return r == s;\n        for (var u = n[0].getValues(), o = [], l = 0, f, g = 0, y, _ = 0; _ < s; _++) {\n          var x = i[_].getValues();\n          o.push(x);\n          var v = re.getOverlaps(u, x);\n          if (v) {\n            f = !_ && v[0][0] > 0 ? s - 1 : _,\n              y = v[0][1];\n            break\n          }\n        }\n        for (var b = Math.abs, T = 1e-8, x = o[f], S; u && x; ) {\n          var v = re.getOverlaps(u, x);\n          if (v) {\n            var I = v[0][0];\n            if (b(I - g) < T) {\n              g = v[1][0],\n              g === 1 && (u = ++l < r ? n[l].getValues() : null,\n                g = 0);\n              var m = v[0][1];\n              if (b(m - y) < T) {\n                if (S || (S = [f, m]),\n                  y = v[1][1],\n                y === 1 && (++f >= s && (f = 0),\n                  x = o[f] || i[f].getValues(),\n                  y = 0),\n                  !u)\n                  return S[0] === f && S[1] === y;\n                continue\n              }\n            }\n          }\n          break\n        }\n        return !1\n      },\n      _hitTestSelf: function(e, t, n, i) {\n        var r = this, s = this.getStyle(), u = this._segments, o = u.length, l = this._closed, f = t._tolerancePadding, g = f, y, _, v, b, T, x, S = t.stroke && s.hasStroke(), I = t.fill && s.hasFill(), m = t.curves, w = S ? s.getStrokeWidth() / 2 : I && t.tolerance > 0 || m ? 0 : null;\n        w !== null && (w > 0 ? (y = s.getStrokeJoin(),\n          _ = s.getStrokeCap(),\n          v = s.getMiterLimit(),\n          g = g.add(ke._getStrokePadding(w, i))) : y = _ = \"round\");\n        function E(G, H) {\n          return e.subtract(G).divide(H).length <= 1\n        }\n        function A(G, H, K) {\n          if (!t.selected || H.isSelected()) {\n            var $ = G._point;\n            if (H !== $ && (H = H.add($)),\n              E(H, g))\n              return new qe(K,r,{\n                segment: G,\n                point: H\n              })\n          }\n        }\n        function N(G, H) {\n          return (H || t.segments) && A(G, G._point, \"segment\") || !H && t.handles && (A(G, G._handleIn, \"handle-in\") || A(G, G._handleOut, \"handle-out\"))\n        }\n        function L(G) {\n          b.add(G)\n        }\n        function R(G) {\n          var H = l || G._index > 0 && G._index < o - 1;\n          if ((H ? y : _) === \"round\")\n            return E(G._point, g);\n          if (b = new ke({\n            internal: !0,\n            closed: !0\n          }),\n            H ? G.isSmooth() || ke._addBevelJoin(G, y, w, v, null, i, L, !0) : _ === \"square\" && ke._addSquareCap(G, _, w, null, i, L, !0),\n            !b.isEmpty()) {\n            var K;\n            return b.contains(e) || (K = b.getNearestLocation(e)) && E(K.getPoint(), f)\n          }\n        }\n        if (t.ends && !t.segments && !l) {\n          if (x = N(u[0], !0) || N(u[o - 1], !0))\n            return x\n        } else if (t.segments || t.handles) {\n          for (var D = 0; D < o; D++)\n            if (x = N(u[D]))\n              return x\n        }\n        if (w !== null) {\n          if (T = this.getNearestLocation(e),\n            T) {\n            var V = T.getTime();\n            V === 0 || V === 1 && o > 1 ? R(T.getSegment()) || (T = null) : E(T.getPoint(), g) || (T = null)\n          }\n          if (!T && y === \"miter\" && o > 1)\n            for (var D = 0; D < o; D++) {\n              var z = u[D];\n              if (e.getDistance(z._point) <= v * w && R(z)) {\n                T = z.getLocation();\n                break\n              }\n            }\n        }\n        return !T && I && this._contains(e) || T && !S && !m ? new qe(\"fill\",this) : T ? new qe(S ? \"stroke\" : \"curve\",this,{\n          location: T,\n          point: T.getPoint()\n        }) : null\n      }\n    }, d.each(re._evaluateMethods, function(e) {\n      this[e + \"At\"] = function(t) {\n        var n = this.getLocationAt(t);\n        return n && n[e]()\n      }\n    }, {\n      beans: !1,\n      getLocationOf: function() {\n        for (var e = C.read(arguments), t = this.getCurves(), n = 0, i = t.length; n < i; n++) {\n          var r = t[n].getLocationOf(e);\n          if (r)\n            return r\n        }\n        return null\n      },\n      getOffsetOf: function() {\n        var e = this.getLocationOf.apply(this, arguments);\n        return e ? e.getOffset() : null\n      },\n      getLocationAt: function(e) {\n        if (typeof e == \"number\") {\n          for (var t = this.getCurves(), n = 0, i = 0, r = t.length; i < r; i++) {\n            var s = n\n              , u = t[i];\n            if (n += u.getLength(),\n            n > e)\n              return u.getLocationAt(e - s)\n          }\n          if (t.length > 0 && e <= this.getLength())\n            return new Ot(t[t.length - 1],1)\n        } else if (e && e.getPath && e.getPath() === this)\n          return e;\n        return null\n      },\n      getOffsetsWithTangent: function() {\n        var e = C.read(arguments);\n        if (e.isZero())\n          return [];\n        for (var t = [], n = 0, i = this.getCurves(), r = 0, s = i.length; r < s; r++) {\n          for (var u = i[r], o = u.getTimesWithTangent(e), l = 0, f = o.length; l < f; l++) {\n            var g = n + u.getOffsetAtTime(o[l]);\n            t.indexOf(g) < 0 && t.push(g)\n          }\n          n += u.length\n        }\n        return t\n      }\n    }), new function() {\n      function e(n, i, r, s) {\n        if (s <= 0)\n          return;\n        var u = s / 2, o = s - 2, l = u - 1, f = new Array(6), g, y;\n        function _(I) {\n          var m = f[I]\n            , w = f[I + 1];\n          (g != m || y != w) && (n.beginPath(),\n            n.moveTo(g, y),\n            n.lineTo(m, w),\n            n.stroke(),\n            n.beginPath(),\n            n.arc(m, w, u, 0, Math.PI * 2, !0),\n            n.fill())\n        }\n        for (var v = 0, b = i.length; v < b; v++) {\n          var T = i[v]\n            , x = T._selection;\n          if (T._transformCoordinates(r, f),\n            g = f[0],\n            y = f[1],\n          x & 2 && _(2),\n          x & 4 && _(4),\n            n.fillRect(g - u, y - u, s, s),\n          o > 0 && !(x & 1)) {\n            var S = n.fillStyle;\n            n.fillStyle = \"#ffffff\",\n              n.fillRect(g - l, y - l, o, o),\n              n.fillStyle = S\n          }\n        }\n      }\n      function t(n, i, r) {\n        var s = i._segments, u = s.length, o = new Array(6), l = !0, f, g, y, _, v, b, T, x;\n        function S(m) {\n          if (r)\n            m._transformCoordinates(r, o),\n              f = o[0],\n              g = o[1];\n          else {\n            var w = m._point;\n            f = w._x,\n              g = w._y\n          }\n          if (l)\n            n.moveTo(f, g),\n              l = !1;\n          else {\n            if (r)\n              v = o[2],\n                b = o[3];\n            else {\n              var E = m._handleIn;\n              v = f + E._x,\n                b = g + E._y\n            }\n            v === f && b === g && T === y && x === _ ? n.lineTo(f, g) : n.bezierCurveTo(T, x, v, b, f, g)\n          }\n          if (y = f,\n            _ = g,\n            r)\n            T = o[4],\n              x = o[5];\n          else {\n            var E = m._handleOut;\n            T = y + E._x,\n              x = _ + E._y\n          }\n        }\n        for (var I = 0; I < u; I++)\n          S(s[I]);\n        i._closed && u > 0 && S(s[0])\n      }\n      return {\n        _draw: function(n, i, r, s) {\n          var u = i.dontStart\n            , o = i.dontFinish || i.clip\n            , l = this.getStyle()\n            , f = l.hasFill()\n            , g = l.hasStroke()\n            , y = l.getDashArray()\n            , _ = !ae.support.nativeDash && g && y && y.length;\n          u || n.beginPath(),\n          (f || g && !_ || o) && (t(n, this, s),\n          this._closed && n.closePath());\n          function v(m) {\n            return y[(m % _ + _) % _]\n          }\n          if (!o && (f || g) && (this._setStyles(n, i, r),\n          f && (n.fill(l.getFillRule()),\n            n.shadowColor = \"rgba(0,0,0,0)\"),\n            g)) {\n            if (_) {\n              u || n.beginPath();\n              for (var b = new kt(this,.25,32,!1,s), T = b.length, x = -l.getDashOffset(), S, I = 0; x > 0; )\n                x -= v(I--) + v(I--);\n              for (; x < T; )\n                S = x + v(I++),\n                (x > 0 || S > 0) && b.drawPart(n, Math.max(x, 0), Math.max(S, 0)),\n                  x = S + v(I++)\n            }\n            n.stroke()\n          }\n        },\n        _drawSelected: function(n, i) {\n          n.beginPath(),\n            t(n, this, i),\n            n.stroke(),\n            e(n, this._segments, i, ae.settings.handleSize)\n        }\n      }\n    }\n    , new function() {\n      function e(t) {\n        var n = t._segments;\n        if (!n.length)\n          throw new Error(\"Use a moveTo() command first\");\n        return n[n.length - 1]\n      }\n      return {\n        moveTo: function() {\n          var t = this._segments;\n          t.length === 1 && this.removeSegment(0),\n          t.length || this._add([new pe(C.read(arguments))])\n        },\n        moveBy: function() {\n          throw new Error(\"moveBy() is unsupported on Path items.\")\n        },\n        lineTo: function() {\n          this._add([new pe(C.read(arguments))])\n        },\n        cubicCurveTo: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = C.read(t)\n            , s = e(this);\n          s.setHandleOut(n.subtract(s._point)),\n            this._add([new pe(r,i.subtract(r))])\n        },\n        quadraticCurveTo: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = e(this)._point;\n          this.cubicCurveTo(n.add(r.subtract(n).multiply(1 / 3)), n.add(i.subtract(n).multiply(1 / 3)), i)\n        },\n        curveTo: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = d.pick(d.read(t), .5)\n            , s = 1 - r\n            , u = e(this)._point\n            , o = n.subtract(u.multiply(s * s)).subtract(i.multiply(r * r)).divide(2 * r * s);\n          if (o.isNaN())\n            throw new Error(\"Cannot put a curve through points with parameter = \" + r);\n          this.quadraticCurveTo(o, i)\n        },\n        arcTo: function() {\n          var t = arguments, n = Math.abs, i = Math.sqrt, r = e(this), s = r._point, u = C.read(t), o, l = d.peek(t), f = d.pick(l, !0), g, y, _, v;\n          if (typeof f == \"boolean\")\n            var b = s.add(u).divide(2)\n              , o = b.add(b.subtract(s).rotate(f ? -90 : 90));\n          else if (d.remain(t) <= 2)\n            o = u,\n              u = C.read(t);\n          else if (!s.equals(u)) {\n            var T = J.read(t)\n              , x = O.isZero;\n            if (x(T.width) || x(T.height))\n              return this.lineTo(u);\n            var S = d.read(t)\n              , f = !!d.read(t)\n              , I = !!d.read(t)\n              , b = s.add(u).divide(2)\n              , m = s.subtract(b).rotate(-S)\n              , w = m.x\n              , E = m.y\n              , A = n(T.width)\n              , N = n(T.height)\n              , L = A * A\n              , R = N * N\n              , D = w * w\n              , V = E * E\n              , z = i(D / L + V / R);\n            if (z > 1 && (A *= z,\n              N *= z,\n              L = A * A,\n              R = N * N),\n              z = (L * R - L * V - R * D) / (L * V + R * D),\n            n(z) < 1e-12 && (z = 0),\n            z < 0)\n              throw new Error(\"Cannot create an arc with the given arguments\");\n            g = new C(A * E / N,-N * w / A).multiply((I === f ? -1 : 1) * i(z)).rotate(S).add(b),\n              v = new le().translate(g).rotate(S).scale(A, N),\n              _ = v._inverseTransform(s),\n              y = _.getDirectedAngle(v._inverseTransform(u)),\n              !f && y > 0 ? y -= 360 : f && y < 0 && (y += 360)\n          }\n          if (o) {\n            var G = new Se(s.add(o).divide(2),o.subtract(s).rotate(90),!0)\n              , H = new Se(o.add(u).divide(2),u.subtract(o).rotate(90),!0)\n              , K = new Se(s,u)\n              , $ = K.getSide(o);\n            if (g = G.intersect(H, !0),\n              !g) {\n              if (!$)\n                return this.lineTo(u);\n              throw new Error(\"Cannot create an arc with the given arguments\")\n            }\n            _ = s.subtract(g),\n              y = _.getDirectedAngle(u.subtract(g));\n            var W = K.getSide(g, !0);\n            W === 0 ? y = $ * n(y) : $ === W && (y += y < 0 ? 360 : -360)\n          }\n          if (y) {\n            for (var te = 1e-5, se = n(y), ue = se >= 360 ? 4 : Math.ceil((se - te) / 90), Ie = y / ue, Ee = Ie * Math.PI / 360, de = 4 / 3 * Math.sin(Ee) / (1 + Math.cos(Ee)), ve = [], Oe = 0; Oe <= ue; Oe++) {\n              var m = u\n                , Te = null;\n              if (Oe < ue && (Te = _.rotate(90).multiply(de),\n                v ? (m = v._transformPoint(_),\n                  Te = v._transformPoint(_.add(Te)).subtract(m)) : m = g.add(_)),\n                !Oe)\n                r.setHandleOut(Te);\n              else {\n                var Ge = _.rotate(-90).multiply(de);\n                v && (Ge = v._transformPoint(_.add(Ge)).subtract(m)),\n                  ve.push(new pe(m,Ge,Te))\n              }\n              _ = _.rotate(Ie)\n            }\n            this._add(ve)\n          }\n        },\n        lineBy: function() {\n          var t = C.read(arguments)\n            , n = e(this)._point;\n          this.lineTo(n.add(t))\n        },\n        curveBy: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = d.read(t)\n            , s = e(this)._point;\n          this.curveTo(s.add(n), s.add(i), r)\n        },\n        cubicCurveBy: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = C.read(t)\n            , s = e(this)._point;\n          this.cubicCurveTo(s.add(n), s.add(i), s.add(r))\n        },\n        quadraticCurveBy: function() {\n          var t = arguments\n            , n = C.read(t)\n            , i = C.read(t)\n            , r = e(this)._point;\n          this.quadraticCurveTo(r.add(n), r.add(i))\n        },\n        arcBy: function() {\n          var t = arguments\n            , n = e(this)._point\n            , i = n.add(C.read(t))\n            , r = d.pick(d.peek(t), !0);\n          typeof r == \"boolean\" ? this.arcTo(i, r) : this.arcTo(i, n.add(C.read(t)))\n        },\n        closePath: function(t) {\n          this.setClosed(!0),\n            this.join(this, t)\n        }\n      }\n    }\n    , {\n      _getBounds: function(e, t) {\n        var n = t.handle ? \"getHandleBounds\" : t.stroke ? \"getStrokeBounds\" : \"getBounds\";\n        return ke[n](this._segments, this._closed, this, e, t)\n      },\n      statics: {\n        getBounds: function(e, t, n, i, r, s) {\n          var u = e[0];\n          if (!u)\n            return new Y;\n          var o = new Array(6)\n            , l = u._transformCoordinates(i, new Array(6))\n            , f = l.slice(0, 2)\n            , g = f.slice()\n            , y = new Array(2);\n          function _(T) {\n            T._transformCoordinates(i, o);\n            for (var x = 0; x < 2; x++)\n              re._addBounds(l[x], l[x + 4], o[x + 2], o[x], x, s ? s[x] : 0, f, g, y);\n            var S = l;\n            l = o,\n              o = S\n          }\n          for (var v = 1, b = e.length; v < b; v++)\n            _(e[v]);\n          return t && _(u),\n            new Y(f[0],f[1],g[0] - f[0],g[1] - f[1])\n        },\n        getStrokeBounds: function(e, t, n, i, r) {\n          var s = n.getStyle()\n            , u = s.hasStroke()\n            , o = s.getStrokeWidth()\n            , l = u && n._getStrokeMatrix(i, r)\n            , f = u && ke._getStrokePadding(o, l)\n            , g = ke.getBounds(e, t, n, i, r, f);\n          if (!u)\n            return g;\n          var y = o / 2\n            , _ = s.getStrokeJoin()\n            , v = s.getStrokeCap()\n            , b = s.getMiterLimit()\n            , T = new Y(new J(f));\n          function x(A) {\n            g = g.include(A)\n          }\n          function S(A) {\n            g = g.unite(T.setCenter(A._point.transform(i)))\n          }\n          function I(A, N) {\n            N === \"round\" || A.isSmooth() ? S(A) : ke._addBevelJoin(A, N, y, b, i, l, x)\n          }\n          function m(A, N) {\n            N === \"round\" ? S(A) : ke._addSquareCap(A, N, y, i, l, x)\n          }\n          var w = e.length - (t ? 0 : 1);\n          if (w > 0) {\n            for (var E = 1; E < w; E++)\n              I(e[E], _);\n            t ? I(e[0], _) : (m(e[0], v),\n              m(e[e.length - 1], v))\n          }\n          return g\n        },\n        _getStrokePadding: function(e, t) {\n          if (!t)\n            return [e, e];\n          var n = new C(e,0).transform(t)\n            , i = new C(0,e).transform(t)\n            , r = n.getAngleInRadians()\n            , s = n.getLength()\n            , u = i.getLength()\n            , o = Math.sin(r)\n            , l = Math.cos(r)\n            , f = Math.tan(r)\n            , g = Math.atan2(u * f, s)\n            , y = Math.atan2(u, f * s);\n          return [Math.abs(s * Math.cos(g) * l + u * Math.sin(g) * o), Math.abs(u * Math.sin(y) * l + s * Math.cos(y) * o)]\n        },\n        _addBevelJoin: function(e, t, n, i, r, s, u, o) {\n          var l = e.getCurve()\n            , f = l.getPrevious()\n            , g = l.getPoint1().transform(r)\n            , y = f.getNormalAtTime(1).multiply(n).transform(s)\n            , _ = l.getNormalAtTime(0).multiply(n).transform(s)\n            , v = y.getDirectedAngle(_);\n          if ((v < 0 || v >= 180) && (y = y.negate(),\n            _ = _.negate()),\n          o && u(g),\n            u(g.add(y)),\n          t === \"miter\") {\n            var b = new Se(g.add(y),new C(-y.y,y.x),!0).intersect(new Se(g.add(_),new C(-_.y,_.x),!0), !0);\n            b && g.getDistance(b) <= i * n && u(b)\n          }\n          u(g.add(_))\n        },\n        _addSquareCap: function(e, t, n, i, r, s, u) {\n          var o = e._point.transform(i)\n            , l = e.getLocation()\n            , f = l.getNormal().multiply(l.getTime() === 0 ? n : -n).transform(r);\n          t === \"square\" && (u && (s(o.subtract(f)),\n            s(o.add(f))),\n            o = o.add(f.rotate(-90))),\n            s(o.add(f)),\n            s(o.subtract(f))\n        },\n        getHandleBounds: function(e, t, n, i, r) {\n          var s = n.getStyle(), u = r.stroke && s.hasStroke(), o, l;\n          if (u) {\n            var f = n._getStrokeMatrix(i, r)\n              , g = s.getStrokeWidth() / 2\n              , y = g;\n            s.getStrokeJoin() === \"miter\" && (y = g * s.getMiterLimit()),\n            s.getStrokeCap() === \"square\" && (y = Math.max(y, g * Math.SQRT2)),\n              o = ke._getStrokePadding(g, f),\n              l = ke._getStrokePadding(y, f)\n          }\n          for (var _ = new Array(6), v = 1 / 0, b = -v, T = v, x = b, S = 0, I = e.length; S < I; S++) {\n            var m = e[S];\n            m._transformCoordinates(i, _);\n            for (var w = 0; w < 6; w += 2) {\n              var E = w ? o : l\n                , A = E ? E[0] : 0\n                , N = E ? E[1] : 0\n                , L = _[w]\n                , R = _[w + 1]\n                , D = L - A\n                , V = L + A\n                , z = R - N\n                , G = R + N;\n              D < v && (v = D),\n              V > b && (b = V),\n              z < T && (T = z),\n              G > x && (x = G)\n            }\n          }\n          return new Y(v,T,b - v,x - T)\n        }\n      }\n    });\n  ke.inject({\n    statics: new function() {\n      var e = .5522847498307936\n        , t = [new pe([-1, 0],[0, e],[0, -e]), new pe([0, -1],[-e, 0],[e, 0]), new pe([1, 0],[0, -e],[0, e]), new pe([0, 1],[e, 0],[-e, 0])];\n      function n(r, s, u) {\n        var o = d.getNamed(u)\n          , l = new ke(o && (o.insert == !0 ? oe.INSERT : o.insert == !1 ? oe.NO_INSERT : null));\n        return l._add(r),\n          l._closed = s,\n          l.set(o, oe.INSERT)\n      }\n      function i(r, s, u) {\n        for (var o = new Array(4), l = 0; l < 4; l++) {\n          var f = t[l];\n          o[l] = new pe(f._point.multiply(s).add(r),f._handleIn.multiply(s),f._handleOut.multiply(s))\n        }\n        return n(o, !0, u)\n      }\n      return {\n        Line: function() {\n          var r = arguments;\n          return n([new pe(C.readNamed(r, \"from\")), new pe(C.readNamed(r, \"to\"))], !1, r)\n        },\n        Circle: function() {\n          var r = arguments\n            , s = C.readNamed(r, \"center\")\n            , u = d.readNamed(r, \"radius\");\n          return i(s, new J(u), r)\n        },\n        Rectangle: function() {\n          var r = arguments, s = Y.readNamed(r, \"rectangle\"), u = J.readNamed(r, \"radius\", 0, {\n            readNull: !0\n          }), o = s.getBottomLeft(!0), l = s.getTopLeft(!0), f = s.getTopRight(!0), g = s.getBottomRight(!0), y;\n          if (!u || u.isZero())\n            y = [new pe(o), new pe(l), new pe(f), new pe(g)];\n          else {\n            u = J.min(u, s.getSize(!0).divide(2));\n            var _ = u.width\n              , v = u.height\n              , b = _ * e\n              , T = v * e;\n            y = [new pe(o.add(_, 0),null,[-b, 0]), new pe(o.subtract(0, v),[0, T]), new pe(l.add(0, v),null,[0, -T]), new pe(l.add(_, 0),[-b, 0],null), new pe(f.subtract(_, 0),null,[b, 0]), new pe(f.add(0, v),[0, -T],null), new pe(g.subtract(0, v),null,[0, T]), new pe(g.subtract(_, 0),[b, 0])]\n          }\n          return n(y, !0, r)\n        },\n        RoundRectangle: \"#Rectangle\",\n        Ellipse: function() {\n          var r = arguments\n            , s = je._readEllipse(r);\n          return i(s.center, s.radius, r)\n        },\n        Oval: \"#Ellipse\",\n        Arc: function() {\n          var r = arguments\n            , s = C.readNamed(r, \"from\")\n            , u = C.readNamed(r, \"through\")\n            , o = C.readNamed(r, \"to\")\n            , l = d.getNamed(r)\n            , f = new ke(l && l.insert == !1 && oe.NO_INSERT);\n          return f.moveTo(s),\n            f.arcTo(u, o),\n            f.set(l)\n        },\n        RegularPolygon: function() {\n          for (var r = arguments, s = C.readNamed(r, \"center\"), u = d.readNamed(r, \"sides\"), o = d.readNamed(r, \"radius\"), l = 360 / u, f = u % 3 === 0, g = new C(0,f ? -o : o), y = f ? -1 : .5, _ = new Array(u), v = 0; v < u; v++)\n            _[v] = new pe(s.add(g.rotate((v + y) * l)));\n          return n(_, !0, r)\n        },\n        Star: function() {\n          for (var r = arguments, s = C.readNamed(r, \"center\"), u = d.readNamed(r, \"points\") * 2, o = d.readNamed(r, \"radius1\"), l = d.readNamed(r, \"radius2\"), f = 360 / u, g = new C(0,-1), y = new Array(u), _ = 0; _ < u; _++)\n            y[_] = new pe(s.add(g.rotate(f * _).multiply(_ % 2 ? l : o)));\n          return n(y, !0, r)\n        }\n      }\n    }\n  });\n  var ot = Ft.extend({\n      _class: \"CompoundPath\",\n      _serializeFields: {\n        children: []\n      },\n      beans: !0,\n      initialize: function(t) {\n        this._children = [],\n          this._namedChildren = {},\n        this._initialize(t) || (typeof t == \"string\" ? this.setPathData(t) : this.addChildren(Array.isArray(t) ? t : arguments))\n      },\n      insertChildren: function e(t, n) {\n        var i = n\n          , r = i[0];\n        r && typeof r[0] == \"number\" && (i = [i]);\n        for (var s = n.length - 1; s >= 0; s--) {\n          var u = i[s];\n          i === n && !(u instanceof ke) && (i = d.slice(i)),\n            Array.isArray(u) ? i[s] = new ke({\n              segments: u,\n              insert: !1\n            }) : u instanceof ot && (i.splice.apply(i, [s, 1].concat(u.removeChildren())),\n              u.remove())\n        }\n        return e.base.call(this, t, i)\n      },\n      reduce: function e(t) {\n        for (var n = this._children, i = n.length - 1; i >= 0; i--) {\n          var r = n[i].reduce(t);\n          r.isEmpty() && r.remove()\n        }\n        if (!n.length) {\n          var r = new ke(oe.NO_INSERT);\n          return r.copyAttributes(this),\n            r.insertAbove(this),\n            this.remove(),\n            r\n        }\n        return e.base.call(this)\n      },\n      isClosed: function() {\n        for (var e = this._children, t = 0, n = e.length; t < n; t++)\n          if (!e[t]._closed)\n            return !1;\n        return !0\n      },\n      setClosed: function(e) {\n        for (var t = this._children, n = 0, i = t.length; n < i; n++)\n          t[n].setClosed(e)\n      },\n      getFirstSegment: function() {\n        var e = this.getFirstChild();\n        return e && e.getFirstSegment()\n      },\n      getLastSegment: function() {\n        var e = this.getLastChild();\n        return e && e.getLastSegment()\n      },\n      getCurves: function() {\n        for (var e = this._children, t = [], n = 0, i = e.length; n < i; n++)\n          d.push(t, e[n].getCurves());\n        return t\n      },\n      getFirstCurve: function() {\n        var e = this.getFirstChild();\n        return e && e.getFirstCurve()\n      },\n      getLastCurve: function() {\n        var e = this.getLastChild();\n        return e && e.getLastCurve()\n      },\n      getArea: function() {\n        for (var e = this._children, t = 0, n = 0, i = e.length; n < i; n++)\n          t += e[n].getArea();\n        return t\n      },\n      getLength: function() {\n        for (var e = this._children, t = 0, n = 0, i = e.length; n < i; n++)\n          t += e[n].getLength();\n        return t\n      },\n      getPathData: function(e, t) {\n        for (var n = this._children, i = [], r = 0, s = n.length; r < s; r++) {\n          var u = n[r]\n            , o = u._matrix;\n          i.push(u.getPathData(e && !o.isIdentity() ? e.appended(o) : e, t))\n        }\n        return i.join(\"\")\n      },\n      _hitTestChildren: function e(t, n, i) {\n        return e.base.call(this, t, n.class === ke || n.type === \"path\" ? n : d.set({}, n, {\n          fill: !1\n        }), i)\n      },\n      _draw: function(e, t, n, i) {\n        var r = this._children;\n        if (r.length) {\n          t = t.extend({\n            dontStart: !0,\n            dontFinish: !0\n          }),\n            e.beginPath();\n          for (var s = 0, u = r.length; s < u; s++)\n            r[s].draw(e, t, i);\n          if (!t.clip) {\n            this._setStyles(e, t, n);\n            var o = this._style;\n            o.hasFill() && (e.fill(o.getFillRule()),\n              e.shadowColor = \"rgba(0,0,0,0)\"),\n            o.hasStroke() && e.stroke()\n          }\n        }\n      },\n      _drawSelected: function(e, t, n) {\n        for (var i = this._children, r = 0, s = i.length; r < s; r++) {\n          var u = i[r]\n            , o = u._matrix;\n          n[u._id] || u._drawSelected(e, o.isIdentity() ? t : t.appended(o))\n        }\n      }\n    }, new function() {\n      function e(t, n) {\n        var i = t._children;\n        if (n && !i.length)\n          throw new Error(\"Use a moveTo() command first\");\n        return i[i.length - 1]\n      }\n      return d.each([\"lineTo\", \"cubicCurveTo\", \"quadraticCurveTo\", \"curveTo\", \"arcTo\", \"lineBy\", \"cubicCurveBy\", \"quadraticCurveBy\", \"curveBy\", \"arcBy\"], function(t) {\n        this[t] = function() {\n          var n = e(this, !0);\n          n[t].apply(n, arguments)\n        }\n      }, {\n        moveTo: function() {\n          var t = e(this)\n            , n = t && t.isEmpty() ? t : new ke(oe.NO_INSERT);\n          n !== t && this.addChild(n),\n            n.moveTo.apply(n, arguments)\n        },\n        moveBy: function() {\n          var t = e(this, !0)\n            , n = t && t.getLastSegment()\n            , i = C.read(arguments);\n          this.moveTo(n ? i.add(n._point) : i)\n        },\n        closePath: function(t) {\n          e(this, !0).closePath(t)\n        }\n      })\n    }\n    , d.each([\"reverse\", \"flatten\", \"simplify\", \"smooth\"], function(e) {\n      this[e] = function(t) {\n        for (var n = this._children, i, r = 0, s = n.length; r < s; r++)\n          i = n[r][e](t) || i;\n        return i\n      }\n    }, {}));\n  Ft.inject(new function() {\n      var e = Math.min\n        , t = Math.max\n        , n = Math.abs\n        , i = {\n        unite: {\n          1: !0,\n          2: !0\n        },\n        intersect: {\n          2: !0\n        },\n        subtract: {\n          1: !0\n        },\n        exclude: {\n          1: !0,\n          \"-1\": !0\n        }\n      };\n      function r(S) {\n        return S._children || [S]\n      }\n      function s(S, I) {\n        var m = S.clone(!1).reduce({\n          simplify: !0\n        }).transform(null, !0, !0);\n        if (I) {\n          for (var w = r(m), E = 0, A = w.length; E < A; E++) {\n            var S = w[E];\n            !S._closed && !S.isEmpty() && (S.closePath(1e-12),\n              S.getFirstSegment().setHandleIn(0, 0),\n              S.getLastSegment().setHandleOut(0, 0))\n          }\n          m = m.resolveCrossings().reorient(m.getFillRule() === \"nonzero\", !0)\n        }\n        return m\n      }\n      function u(S, I, m, w, E) {\n        var A = new ot(oe.NO_INSERT);\n        return A.addChildren(S, !0),\n          A = A.reduce({\n            simplify: I\n          }),\n        E && E.insert == !1 || A.insertAbove(w && m.isSibling(w) && m.getIndex() < w.getIndex() ? w : m),\n          A.copyAttributes(m, !0),\n          A\n      }\n      function o(S) {\n        return S.hasOverlap() || S.isCrossing()\n      }\n      function l(S, I, m, w) {\n        if (w && (w.trace == !1 || w.stroke) && /^(subtract|intersect)$/.test(m))\n          return f(S, I, m);\n        var E = s(S, !0)\n          , A = I && S !== I && s(I, !0)\n          , N = i[m];\n        N[m] = !0,\n        A && (N.subtract || N.exclude) ^ (A.isClockwise() ^ E.isClockwise()) && A.reverse();\n        var L = v(Ot.expand(E.getIntersections(A, o))), R = r(E), D = A && r(A), V = [], z = [], G;\n        function H(Te) {\n          for (var Ge = 0, Re = Te.length; Ge < Re; Ge++) {\n            var xe = Te[Ge];\n            d.push(V, xe._segments),\n              d.push(z, xe.getCurves()),\n              xe._overlapsOnly = !0\n          }\n        }\n        function K(Te) {\n          for (var Ge = [], Re = 0, xe = Te && Te.length; Re < xe; Re++)\n            Ge.push(z[Te[Re]]);\n          return Ge\n        }\n        if (L.length) {\n          H(R),\n          D && H(D);\n          for (var $ = new Array(z.length), W = 0, te = z.length; W < te; W++)\n            $[W] = z[W].getValues();\n          for (var se = q.findCurveBoundsCollisions($, $, 0, !0), ue = {}, W = 0; W < z.length; W++) {\n            var Ie = z[W]\n              , Ee = Ie._path._id\n              , de = ue[Ee] = ue[Ee] || {};\n            de[Ie.getIndex()] = {\n              hor: K(se[W].hor),\n              ver: K(se[W].ver)\n            }\n          }\n          for (var W = 0, te = L.length; W < te; W++)\n            T(L[W]._segment, E, A, ue, N);\n          for (var W = 0, te = V.length; W < te; W++) {\n            var ve = V[W]\n              , Oe = ve._intersection;\n            ve._winding || T(ve, E, A, ue, N),\n            Oe && Oe._overlap || (ve._path._overlapsOnly = !1)\n          }\n          G = x(V, N)\n        } else\n          G = _(D ? R.concat(D) : R.slice(), function(Te) {\n            return !!N[Te]\n          });\n        return u(G, !0, S, I, w)\n      }\n      function f(S, I, m) {\n        var w = s(S)\n          , E = s(I)\n          , A = w.getIntersections(E, o)\n          , N = m === \"subtract\"\n          , L = m === \"divide\"\n          , R = {}\n          , D = [];\n        function V(H) {\n          if (!R[H._id] && (L || E.contains(H.getPointAt(H.getLength() / 2)) ^ N))\n            return D.unshift(H),\n              R[H._id] = !0\n        }\n        for (var z = A.length - 1; z >= 0; z--) {\n          var G = A[z].split();\n          G && (V(G) && G.getFirstSegment().setHandleIn(0, 0),\n            w.getLastSegment().setHandleOut(0, 0))\n        }\n        return V(w),\n          u(D, !1, S, I)\n      }\n      function g(S, I) {\n        for (var m = S; m; ) {\n          if (m === I)\n            return;\n          m = m._previous\n        }\n        for (; S._next && S._next !== I; )\n          S = S._next;\n        if (!S._next) {\n          for (; I._previous; )\n            I = I._previous;\n          S._next = I,\n            I._previous = S\n        }\n      }\n      function y(S) {\n        for (var I = S.length - 1; I >= 0; I--)\n          S[I].clearHandles()\n      }\n      function _(S, I, m) {\n        var w = S && S.length;\n        if (w) {\n          var E = d.each(S, function(se, ue) {\n            this[se._id] = {\n              container: null,\n              winding: se.isClockwise() ? 1 : -1,\n              index: ue\n            }\n          }, {})\n            , A = S.slice().sort(function(se, ue) {\n            return n(ue.getArea()) - n(se.getArea())\n          })\n            , N = A[0]\n            , L = q.findItemBoundsCollisions(A, null, O.GEOMETRIC_EPSILON);\n          m == null && (m = N.isClockwise());\n          for (var R = 0; R < w; R++) {\n            var D = A[R]\n              , V = E[D._id]\n              , z = 0\n              , G = L[R];\n            if (G) {\n              for (var H = null, K = G.length - 1; K >= 0; K--)\n                if (G[K] < R) {\n                  H = H || D.getInteriorPoint();\n                  var $ = A[G[K]];\n                  if ($.contains(H)) {\n                    var W = E[$._id];\n                    z = W.winding,\n                      V.winding += z,\n                      V.container = W.exclude ? W.container : $;\n                    break\n                  }\n                }\n            }\n            if (I(V.winding) === I(z))\n              V.exclude = !0,\n                S[V.index] = null;\n            else {\n              var te = V.container;\n              D.setClockwise(te ? !te.isClockwise() : m)\n            }\n          }\n        }\n        return S\n      }\n      function v(S, I, m) {\n        var w = I && [], E = 1e-8, A = 1 - E, N = !1, L = m || [], R = m && {}, D, V, z;\n        function G(Ge) {\n          return Ge._path._id + \".\" + Ge._segment1._index\n        }\n        for (var H = (m && m.length) - 1; H >= 0; H--) {\n          var K = m[H];\n          K._path && (R[G(K)] = !0)\n        }\n        for (var H = S.length - 1; H >= 0; H--) {\n          var $ = S[H], W = $._time, te = W, se = I && !I($), K = $._curve, ue;\n          if (K && (K !== V ? (N = !K.hasHandles() || R && R[G(K)],\n            D = [],\n            z = null,\n            V = K) : z >= E && (W /= z)),\n            se) {\n            D && D.push($);\n            continue\n          } else\n            I && w.unshift($);\n          if (z = te,\n          W < E)\n            ue = K._segment1;\n          else if (W > A)\n            ue = K._segment2;\n          else {\n            var Ie = K.divideAtTime(W, !0);\n            N && L.push(K, Ie),\n              ue = Ie._segment1;\n            for (var Ee = D.length - 1; Ee >= 0; Ee--) {\n              var de = D[Ee];\n              de._time = (de._time - W) / (1 - W)\n            }\n          }\n          $._setSegment(ue);\n          var ve = ue._intersection\n            , Oe = $._intersection;\n          if (ve) {\n            g(ve, Oe);\n            for (var Te = ve; Te; )\n              g(Te._intersection, ve),\n                Te = Te._next\n          } else\n            ue._intersection = Oe\n        }\n        return m || y(L),\n        w || S\n      }\n      function b(S, I, m, w, E) {\n        var A = Array.isArray(I) ? I : I[m ? \"hor\" : \"ver\"], N = m ? 1 : 0, L = N ^ 1, R = [S.x, S.y], D = R[N], V = R[L], z = 1e-9, G = 1e-6, H = D - z, K = D + z, $ = 0, W = 0, te = 0, se = 0, ue = !1, Ie = !1, Ee = 1, de = [], ve, Oe;\n        function Te(Ye) {\n          var ut = Ye[L + 0]\n            , st = Ye[L + 6];\n          if (!(V < e(ut, st) || V > t(ut, st))) {\n            var vt = Ye[N + 0]\n              , Ht = Ye[N + 2]\n              , fn = Ye[N + 4]\n              , jt = Ye[N + 6];\n            if (ut === st) {\n              (vt < K && jt > H || jt < K && vt > H) && (ue = !0);\n              return\n            }\n            var Yt = V === ut ? 0 : V === st || H > t(vt, Ht, fn, jt) || K < e(vt, Ht, fn, jt) ? 1 : re.solveCubic(Ye, L, V, de, 0, 1) > 0 ? de[0] : 1\n              , Dt = Yt === 0 ? vt : Yt === 1 ? jt : re.getPoint(Ye, Yt)[m ? \"y\" : \"x\"]\n              , Ct = ut > st ? 1 : -1\n              , Tn = ve[L] > ve[L + 6] ? 1 : -1\n              , $t = ve[N + 6];\n            return V !== ut ? (Dt < H ? te += Ct : Dt > K ? se += Ct : ue = !0,\n            Dt > D - G && Dt < D + G && (Ee /= 2)) : (Ct !== Tn ? vt < H ? te += Ct : vt > K && (se += Ct) : vt != $t && ($t < K && Dt > K ? (se += Ct,\n              ue = !0) : $t > H && Dt < H && (te += Ct,\n              ue = !0)),\n              Ee /= 4),\n              ve = Ye,\n            !E && Dt > H && Dt < K && re.getTangent(Ye, Yt)[m ? \"x\" : \"y\"] === 0 && b(S, I, !m, w, !0)\n          }\n        }\n        function Ge(Ye) {\n          var ut = Ye[L + 0]\n            , st = Ye[L + 2]\n            , vt = Ye[L + 4]\n            , Ht = Ye[L + 6];\n          if (V <= t(ut, st, vt, Ht) && V >= e(ut, st, vt, Ht)) {\n            for (var fn = Ye[N + 0], jt = Ye[N + 2], Yt = Ye[N + 4], Dt = Ye[N + 6], Ct = H > t(fn, jt, Yt, Dt) || K < e(fn, jt, Yt, Dt) ? [Ye] : re.getMonoCurves(Ye, m), Tn, $t = 0, Oi = Ct.length; $t < Oi; $t++)\n              if (Tn = Te(Ct[$t]))\n                return Tn\n          }\n        }\n        for (var Re = 0, xe = A.length; Re < xe; Re++) {\n          var ze = A[Re], De = ze._path, _t = ze.getValues(), gt;\n          if ((!Re || A[Re - 1]._path !== De) && (ve = null,\n          De._closed || (Oe = re.getValues(De.getLastCurve().getSegment2(), ze.getSegment1(), null, !w),\n          Oe[L] !== Oe[L + 6] && (ve = Oe)),\n            !ve)) {\n            ve = _t;\n            for (var Et = De.getLastCurve(); Et && Et !== ze; ) {\n              var nt = Et.getValues();\n              if (nt[L] !== nt[L + 6]) {\n                ve = nt;\n                break\n              }\n              Et = Et.getPrevious()\n            }\n          }\n          if (gt = Ge(_t))\n            return gt;\n          if (Re + 1 === xe || A[Re + 1]._path !== De) {\n            if (Oe && (gt = Ge(Oe)))\n              return gt;\n            ue && !te && !se && (te = se = De.isClockwise(w) ^ m ? 1 : -1),\n              $ += te,\n              W += se,\n              te = se = 0,\n            ue && (Ie = !0,\n              ue = !1),\n              Oe = null\n          }\n        }\n        return $ = n($),\n          W = n(W),\n          {\n            winding: t($, W),\n            windingL: $,\n            windingR: W,\n            quality: Ee,\n            onPath: Ie\n          }\n      }\n      function T(S, I, m, w, E) {\n        var A = [], N = S, L = 0, z;\n        do {\n          var R = S.getCurve();\n          if (R) {\n            var D = R.getLength();\n            A.push({\n              segment: S,\n              curve: R,\n              length: D\n            }),\n              L += D\n          }\n          S = S.getNext()\n        } while (S && !S._intersection && S !== N);\n        for (var V = [.5, .25, .75], z = {\n          winding: 0,\n          quality: -1\n        }, G = .001, H = 1 - G, K = 0; K < V.length && z.quality < .5; K++)\n          for (var D = L * V[K], $ = 0, W = A.length; $ < W; $++) {\n            var te = A[$]\n              , se = te.length;\n            if (D <= se) {\n              var R = te.curve\n                , ue = R._path\n                , Ie = ue._parent\n                , Ee = Ie instanceof ot ? Ie : ue\n                , de = O.clamp(R.getTimeAt(D), G, H)\n                , ve = R.getPointAtTime(de)\n                , Oe = n(R.getTangentAtTime(de).y) < Math.SQRT1_2\n                , Te = null;\n              if (E.subtract && m) {\n                var Ge = Ee === I ? m : I\n                  , Re = Ge._getWinding(ve, Oe, !0);\n                if (Ee === I && Re.winding || Ee === m && !Re.winding) {\n                  if (Re.quality < 1)\n                    continue;\n                  Te = {\n                    winding: 0,\n                    quality: 1\n                  }\n                }\n              }\n              Te = Te || b(ve, w[ue._id][R.getIndex()], Oe, !0),\n              Te.quality > z.quality && (z = Te);\n              break\n            }\n            D -= se\n          }\n        for (var $ = A.length - 1; $ >= 0; $--)\n          A[$].segment._winding = z\n      }\n      function x(S, I) {\n        var m = [], w;\n        function E(xe) {\n          var ze;\n          return !!(xe && !xe._visited && (!I || I[(ze = xe._winding || {}).winding] && !(I.unite && ze.winding === 2 && ze.windingL && ze.windingR)))\n        }\n        function A(xe) {\n          if (xe) {\n            for (var ze = 0, De = w.length; ze < De; ze++)\n              if (xe === w[ze])\n                return !0\n          }\n          return !1\n        }\n        function N(xe) {\n          for (var ze = xe._segments, De = 0, _t = ze.length; De < _t; De++)\n            ze[De]._visited = !0\n        }\n        function L(xe, ze) {\n          var De = xe._intersection\n            , _t = De\n            , gt = [];\n          ze && (w = [xe]);\n          function Et(nt, Ye) {\n            for (; nt && nt !== Ye; ) {\n              var ut = nt._segment\n                , st = ut && ut._path;\n              if (st) {\n                var vt = ut.getNext() || st.getFirstSegment()\n                  , Ht = vt._intersection;\n                ut !== xe && (A(ut) || A(vt) || vt && E(ut) && (E(vt) || Ht && E(Ht._segment))) && gt.push(ut),\n                ze && w.push(ut)\n              }\n              nt = nt._next\n            }\n          }\n          if (De) {\n            for (Et(De); De && De._previous; )\n              De = De._previous;\n            Et(De, _t)\n          }\n          return gt\n        }\n        S.sort(function(xe, ze) {\n          var De = xe._intersection\n            , _t = ze._intersection\n            , gt = !!(De && De._overlap)\n            , Et = !!(_t && _t._overlap)\n            , nt = xe._path\n            , Ye = ze._path;\n          return gt ^ Et ? gt ? 1 : -1 : !De ^ !_t ? De ? 1 : -1 : nt !== Ye ? nt._id - Ye._id : xe._index - ze._index\n        });\n        for (var R = 0, D = S.length; R < D; R++) {\n          var V = S[R], z = E(V), G = null, H = !1, K = !0, $ = [], W, te, se;\n          if (z && V._path._overlapsOnly) {\n            var ue = V._path\n              , Ie = V._intersection._segment._path;\n            ue.compare(Ie) && (ue.getArea() && m.push(ue.clone(!1)),\n              N(ue),\n              N(Ie),\n              z = !1)\n          }\n          for (; z; ) {\n            var Ee = !G\n              , de = L(V, Ee)\n              , ve = de.shift()\n              , H = !Ee && (A(V) || A(ve))\n              , Oe = !H && ve;\n            if (Ee && (G = new ke(oe.NO_INSERT),\n              W = null),\n              H) {\n              (V.isFirst() || V.isLast()) && (K = V._path._closed),\n                V._visited = !0;\n              break\n            }\n            if (Oe && W && ($.push(W),\n              W = null),\n            W || (Oe && de.push(V),\n              W = {\n                start: G._segments.length,\n                crossings: de,\n                visited: te = [],\n                handleIn: se\n              }),\n            Oe && (V = ve),\n              !E(V)) {\n              G.removeSegments(W.start);\n              for (var Te = 0, Ge = te.length; Te < Ge; Te++)\n                te[Te]._visited = !1;\n              te.length = 0;\n              do\n                V = W && W.crossings.shift(),\n                (!V || !V._path) && (V = null,\n                  W = $.pop(),\n                W && (te = W.visited,\n                  se = W.handleIn));\n              while (W && !E(V));\n              if (!V)\n                break\n            }\n            var Re = V.getNext();\n            G.add(new pe(V._point,se,Re && V._handleOut)),\n              V._visited = !0,\n              te.push(V),\n              V = Re || V._path.getFirstSegment(),\n              se = Re && Re._handleIn\n          }\n          H && (K && (G.getFirstSegment().setHandleIn(se),\n            G.setClosed(K)),\n          G.getArea() !== 0 && m.push(G))\n        }\n        return m\n      }\n      return {\n        _getWinding: function(S, I, m) {\n          return b(S, this.getCurves(), I, m)\n        },\n        unite: function(S, I) {\n          return l(this, S, \"unite\", I)\n        },\n        intersect: function(S, I) {\n          return l(this, S, \"intersect\", I)\n        },\n        subtract: function(S, I) {\n          return l(this, S, \"subtract\", I)\n        },\n        exclude: function(S, I) {\n          return l(this, S, \"exclude\", I)\n        },\n        divide: function(S, I) {\n          return I && (I.trace == !1 || I.stroke) ? f(this, S, \"divide\") : u([this.subtract(S, I), this.intersect(S, I)], !0, this, S, I)\n        },\n        resolveCrossings: function() {\n          var S = this._children\n            , I = S || [this];\n          function m(W, te) {\n            var se = W && W._intersection;\n            return se && se._overlap && se._path === te\n          }\n          var w = !1\n            , E = !1\n            , A = this.getIntersections(null, function(W) {\n            return W.hasOverlap() && (w = !0) || W.isCrossing() && (E = !0)\n          })\n            , N = w && E && [];\n          if (A = Ot.expand(A),\n            w)\n            for (var L = v(A, function(W) {\n              return W.hasOverlap()\n            }, N), R = L.length - 1; R >= 0; R--) {\n              var D = L[R]\n                , V = D._path\n                , z = D._segment\n                , G = z.getPrevious()\n                , H = z.getNext();\n              m(G, V) && m(H, V) && (z.remove(),\n                G._handleOut._set(0, 0),\n                H._handleIn._set(0, 0),\n              G !== z && !G.getCurve().hasLength() && (H._handleIn.set(G._handleIn),\n                G.remove()))\n            }\n          E && (v(A, w && function(W) {\n            var te = W.getCurve()\n              , se = W.getSegment()\n              , ue = W._intersection\n              , Ie = ue._curve\n              , Ee = ue._segment;\n            if (te && Ie && te._path && Ie._path)\n              return !0;\n            se && (se._intersection = null),\n            Ee && (Ee._intersection = null)\n          }\n            , N),\n          N && y(N),\n            I = x(d.each(I, function(W) {\n              d.push(this, W._segments)\n            }, [])));\n          var K = I.length, $;\n          return K > 1 && S ? (I !== S && this.setChildren(I),\n            $ = this) : K === 1 && !S && (I[0] !== this && this.setSegments(I[0].removeSegments()),\n            $ = this),\n          $ || ($ = new ot(oe.NO_INSERT),\n            $.addChildren(I),\n            $ = $.reduce(),\n            $.copyAttributes(this),\n            this.replaceWith($)),\n            $\n        },\n        reorient: function(S, I) {\n          var m = this._children;\n          return m && m.length ? this.setChildren(_(this.removeChildren(), function(w) {\n            return !!(S ? w : w & 1)\n          }, I)) : I !== a && this.setClockwise(I),\n            this\n        },\n        getInteriorPoint: function() {\n          var S = this.getBounds()\n            , I = S.getCenter(!0);\n          if (!this.contains(I)) {\n            for (var m = this.getCurves(), w = I.y, E = [], A = [], N = 0, L = m.length; N < L; N++) {\n              var R = m[N].getValues()\n                , D = R[1]\n                , V = R[3]\n                , z = R[5]\n                , G = R[7];\n              if (w >= e(D, V, z, G) && w <= t(D, V, z, G))\n                for (var H = re.getMonoCurves(R), K = 0, $ = H.length; K < $; K++) {\n                  var W = H[K]\n                    , te = W[1]\n                    , se = W[7];\n                  if (te !== se && (w >= te && w <= se || w >= se && w <= te)) {\n                    var ue = w === te ? W[0] : w === se ? W[6] : re.solveCubic(W, 1, w, A, 0, 1) === 1 ? re.getPoint(W, A[0]).x : (W[0] + W[6]) / 2;\n                    E.push(ue)\n                  }\n                }\n            }\n            E.length > 1 && (E.sort(function(Ie, Ee) {\n              return Ie - Ee\n            }),\n              I.x = (E[0] + E[1]) / 2)\n          }\n          return I\n        }\n      }\n    }\n  );\n  var kt = d.extend({\n    _class: \"PathFlattener\",\n    initialize: function(e, t, n, i, r) {\n      var s = [], u = [], o = 0, l = 1 / (n || 32), f = e._segments, g = f[0], y;\n      function _(x, S) {\n        var I = re.getValues(x, S, r);\n        s.push(I),\n          v(I, x._index, 0, 1)\n      }\n      function v(x, S, I, m) {\n        if (m - I > l && !(i && re.isStraight(x)) && !re.isFlatEnough(x, t || .25)) {\n          var w = re.subdivide(x, .5)\n            , E = (I + m) / 2;\n          v(w[0], S, I, E),\n            v(w[1], S, E, m)\n        } else {\n          var A = x[6] - x[0]\n            , N = x[7] - x[1]\n            , L = Math.sqrt(A * A + N * N);\n          L > 0 && (o += L,\n            u.push({\n              offset: o,\n              curve: x,\n              index: S,\n              time: m\n            }))\n        }\n      }\n      for (var b = 1, T = f.length; b < T; b++)\n        y = f[b],\n          _(g, y),\n          g = y;\n      e._closed && _(y || g, f[0]),\n        this.curves = s,\n        this.parts = u,\n        this.length = o,\n        this.index = 0\n    },\n    _get: function(e) {\n      for (var t = this.parts, n = t.length, i, r, s = this.index; r = s,\n        !(!s || t[--s].offset < e); )\n        ;\n      for (; r < n; r++) {\n        var u = t[r];\n        if (u.offset >= e) {\n          this.index = r;\n          var o = t[r - 1]\n            , l = o && o.index === u.index ? o.time : 0\n            , f = o ? o.offset : 0;\n          return {\n            index: u.index,\n            time: l + (u.time - l) * (e - f) / (u.offset - f)\n          }\n        }\n      }\n      return {\n        index: t[n - 1].index,\n        time: 1\n      }\n    },\n    drawPart: function(e, t, n) {\n      for (var i = this._get(t), r = this._get(n), s = i.index, u = r.index; s <= u; s++) {\n        var o = re.getPart(this.curves[s], s === i.index ? i.time : 0, s === r.index ? r.time : 1);\n        s === i.index && e.moveTo(o[0], o[1]),\n          e.bezierCurveTo.apply(e, o.slice(2))\n      }\n    }\n  }, d.each(re._evaluateMethods, function(e) {\n    this[e + \"At\"] = function(t) {\n      var n = this._get(t);\n      return re[e](this.curves[n.index], n.time)\n    }\n  }, {}))\n    , yn = d.extend({\n    initialize: function(e) {\n      for (var t = this.points = [], n = e._segments, i = e._closed, r = 0, s, u = n.length; r < u; r++) {\n        var o = n[r].point;\n        (!s || !s.equals(o)) && t.push(s = o.clone())\n      }\n      i && (t.unshift(t[t.length - 1]),\n        t.push(t[1])),\n        this.closed = i\n    },\n    fit: function(e) {\n      var t = this.points\n        , n = t.length\n        , i = null;\n      return n > 0 && (i = [new pe(t[0])],\n      n > 1 && (this.fitCubic(i, e, 0, n - 1, t[1].subtract(t[0]), t[n - 2].subtract(t[n - 1])),\n      this.closed && (i.shift(),\n        i.pop()))),\n        i\n    },\n    fitCubic: function(e, t, n, i, r, s) {\n      var u = this.points;\n      if (i - n === 1) {\n        var o = u[n]\n          , l = u[i]\n          , f = o.getDistance(l) / 3;\n        this.addCurve(e, [o, o.add(r.normalize(f)), l.add(s.normalize(f)), l]);\n        return\n      }\n      for (var g = this.chordLengthParameterize(n, i), y = Math.max(t, t * t), _, v = !0, b = 0; b <= 4; b++) {\n        var T = this.generateBezier(n, i, g, r, s)\n          , x = this.findMaxError(n, i, T, g);\n        if (x.error < t && v) {\n          this.addCurve(e, T);\n          return\n        }\n        if (_ = x.index,\n        x.error >= y)\n          break;\n        v = this.reparameterize(n, i, g, T),\n          y = x.error\n      }\n      var S = u[_ - 1].subtract(u[_ + 1]);\n      this.fitCubic(e, t, n, _, r, S),\n        this.fitCubic(e, t, _, i, S.negate(), s)\n    },\n    addCurve: function(e, t) {\n      var n = e[e.length - 1];\n      n.setHandleOut(t[1].subtract(t[0])),\n        e.push(new pe(t[3],t[2].subtract(t[3])))\n    },\n    generateBezier: function(e, t, n, i, r) {\n      for (var s = 1e-12, u = Math.abs, o = this.points, l = o[e], f = o[t], g = [[0, 0], [0, 0]], y = [0, 0], _ = 0, v = t - e + 1; _ < v; _++) {\n        var b = n[_]\n          , T = 1 - b\n          , x = 3 * b * T\n          , S = T * T * T\n          , I = x * T\n          , m = x * b\n          , w = b * b * b\n          , E = i.normalize(I)\n          , A = r.normalize(m)\n          , N = o[e + _].subtract(l.multiply(S + I)).subtract(f.multiply(m + w));\n        g[0][0] += E.dot(E),\n          g[0][1] += E.dot(A),\n          g[1][0] = g[0][1],\n          g[1][1] += A.dot(A),\n          y[0] += E.dot(N),\n          y[1] += A.dot(N)\n      }\n      var L = g[0][0] * g[1][1] - g[1][0] * g[0][1], R, D;\n      if (u(L) > s) {\n        var V = g[0][0] * y[1] - g[1][0] * y[0]\n          , z = y[0] * g[1][1] - y[1] * g[0][1];\n        R = z / L,\n          D = V / L\n      } else {\n        var G = g[0][0] + g[0][1]\n          , H = g[1][0] + g[1][1];\n        R = D = u(G) > s ? y[0] / G : u(H) > s ? y[1] / H : 0\n      }\n      var K = f.getDistance(l), $ = s * K, W, te;\n      if (R < $ || D < $)\n        R = D = K / 3;\n      else {\n        var se = f.subtract(l);\n        W = i.normalize(R),\n          te = r.normalize(D),\n        W.dot(se) - te.dot(se) > K * K && (R = D = K / 3,\n          W = te = null)\n      }\n      return [l, l.add(W || i.normalize(R)), f.add(te || r.normalize(D)), f]\n    },\n    reparameterize: function(e, t, n, i) {\n      for (var r = e; r <= t; r++)\n        n[r - e] = this.findRoot(i, this.points[r], n[r - e]);\n      for (var r = 1, s = n.length; r < s; r++)\n        if (n[r] <= n[r - 1])\n          return !1;\n      return !0\n    },\n    findRoot: function(e, t, n) {\n      for (var i = [], r = [], s = 0; s <= 2; s++)\n        i[s] = e[s + 1].subtract(e[s]).multiply(3);\n      for (var s = 0; s <= 1; s++)\n        r[s] = i[s + 1].subtract(i[s]).multiply(2);\n      var u = this.evaluate(3, e, n)\n        , o = this.evaluate(2, i, n)\n        , l = this.evaluate(1, r, n)\n        , f = u.subtract(t)\n        , g = o.dot(o) + f.dot(l);\n      return O.isMachineZero(g) ? n : n - f.dot(o) / g\n    },\n    evaluate: function(e, t, n) {\n      for (var i = t.slice(), r = 1; r <= e; r++)\n        for (var s = 0; s <= e - r; s++)\n          i[s] = i[s].multiply(1 - n).add(i[s + 1].multiply(n));\n      return i[0]\n    },\n    chordLengthParameterize: function(e, t) {\n      for (var n = [0], i = e + 1; i <= t; i++)\n        n[i - e] = n[i - e - 1] + this.points[i].getDistance(this.points[i - 1]);\n      for (var i = 1, r = t - e; i <= r; i++)\n        n[i] /= n[r];\n      return n\n    },\n    findMaxError: function(e, t, n, i) {\n      for (var r = Math.floor((t - e + 1) / 2), s = 0, u = e + 1; u < t; u++) {\n        var o = this.evaluate(3, n, i[u - e])\n          , l = o.subtract(this.points[u])\n          , f = l.x * l.x + l.y * l.y;\n        f >= s && (s = f,\n          r = u)\n      }\n      return {\n        error: s,\n        index: r\n      }\n    }\n  })\n    , Gt = oe.extend({\n    _class: \"TextItem\",\n    _applyMatrix: !1,\n    _canApplyMatrix: !1,\n    _serializeFields: {\n      content: null\n    },\n    _boundsOptions: {\n      stroke: !1,\n      handle: !1\n    },\n    initialize: function(t) {\n      this._content = \"\",\n        this._lines = [];\n      var n = t && d.isPlainObject(t) && t.x === a && t.y === a;\n      this._initialize(n && t, !n && C.read(arguments))\n    },\n    _equals: function(e) {\n      return this._content === e._content\n    },\n    copyContent: function(e) {\n      this.setContent(e._content)\n    },\n    getContent: function() {\n      return this._content\n    },\n    setContent: function(e) {\n      this._content = \"\" + e,\n        this._lines = this._content.split(/\\r\\n|\\n|\\r/mg),\n        this._changed(521)\n    },\n    isEmpty: function() {\n      return !this._content\n    },\n    getCharacterStyle: \"#getStyle\",\n    setCharacterStyle: \"#setStyle\",\n    getParagraphStyle: \"#getStyle\",\n    setParagraphStyle: \"#setStyle\"\n  })\n    , Mt = Gt.extend({\n    _class: \"PointText\",\n    initialize: function() {\n      Gt.apply(this, arguments)\n    },\n    getPoint: function() {\n      var e = this._matrix.getTranslation();\n      return new Q(e.x,e.y,this,\"setPoint\")\n    },\n    setPoint: function() {\n      var e = C.read(arguments);\n      this.translate(e.subtract(this._matrix.getTranslation()))\n    },\n    _draw: function(e, t, n) {\n      if (this._content) {\n        this._setStyles(e, t, n);\n        var i = this._lines\n          , r = this._style\n          , s = r.hasFill()\n          , u = r.hasStroke()\n          , o = r.getLeading()\n          , l = e.shadowColor;\n        e.font = r.getFontStyle(),\n          e.textAlign = r.getJustification();\n        for (var f = 0, g = i.length; f < g; f++) {\n          e.shadowColor = l;\n          var y = i[f];\n          s && (e.fillText(y, 0, 0),\n            e.shadowColor = \"rgba(0,0,0,0)\"),\n          u && e.strokeText(y, 0, 0),\n            e.translate(0, o)\n        }\n      }\n    },\n    _getBounds: function(e, t) {\n      var n = this._style\n        , i = this._lines\n        , r = i.length\n        , s = n.getJustification()\n        , u = n.getLeading()\n        , o = this.getView().getTextWidth(n.getFontStyle(), i)\n        , l = 0;\n      s !== \"left\" && (l -= o / (s === \"center\" ? 2 : 1));\n      var f = new Y(l,r ? -.75 * u : 0,o,r * u);\n      return e ? e._transformBounds(f, f) : f\n    }\n  })\n    , Xe = d.extend(new function() {\n      var e = {\n        gray: [\"gray\"],\n        rgb: [\"red\", \"green\", \"blue\"],\n        hsb: [\"hue\", \"saturation\", \"brightness\"],\n        hsl: [\"hue\", \"saturation\", \"lightness\"],\n        gradient: [\"gradient\", \"origin\", \"destination\", \"highlight\"]\n      }, t = {}, n = {\n        transparent: [0, 0, 0, 0]\n      }, i;\n      function r(o) {\n        var l = o.match(/^#([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})?$/i) || o.match(/^#([\\da-f])([\\da-f])([\\da-f])([\\da-f])?$/i), f = \"rgb\", g;\n        if (l) {\n          var y = l[4] ? 4 : 3;\n          g = new Array(y);\n          for (var _ = 0; _ < y; _++) {\n            var v = l[_ + 1];\n            g[_] = parseInt(v.length == 1 ? v + v : v, 16) / 255\n          }\n        } else if (l = o.match(/^(rgb|hsl)a?\\((.*)\\)$/)) {\n          f = l[1],\n            g = l[2].trim().split(/[,\\s]+/g);\n          for (var b = f === \"hsl\", _ = 0, T = Math.min(g.length, 4); _ < T; _++) {\n            var x = g[_]\n              , v = parseFloat(x);\n            if (b)\n              if (_ === 0) {\n                var S = x.match(/([a-z]*)$/)[1];\n                v *= {\n                  turn: 360,\n                  rad: 180 / Math.PI,\n                  grad: .9\n                }[S] || 1\n              } else\n                _ < 3 && (v /= 100);\n            else\n              _ < 3 && (v /= /%$/.test(x) ? 100 : 255);\n            g[_] = v\n          }\n        } else {\n          var I = n[o];\n          if (!I)\n            if (h) {\n              i || (i = Je.getContext(1, 1, {\n                willReadFrequently: !0\n              }),\n                i.globalCompositeOperation = \"copy\"),\n                i.fillStyle = \"rgba(0,0,0,0)\",\n                i.fillStyle = o,\n                i.fillRect(0, 0, 1, 1);\n              var m = i.getImageData(0, 0, 1, 1).data;\n              I = n[o] = [m[0] / 255, m[1] / 255, m[2] / 255]\n            } else\n              I = [0, 0, 0];\n          g = I.slice()\n        }\n        return [f, g]\n      }\n      var s = [[0, 3, 1], [2, 0, 1], [1, 0, 3], [1, 2, 0], [3, 1, 0], [0, 1, 2]]\n        , u = {\n        \"rgb-hsb\": function(o, l, f) {\n          var g = Math.max(o, l, f)\n            , y = Math.min(o, l, f)\n            , _ = g - y\n            , v = _ === 0 ? 0 : (g == o ? (l - f) / _ + (l < f ? 6 : 0) : g == l ? (f - o) / _ + 2 : (o - l) / _ + 4) * 60;\n          return [v, g === 0 ? 0 : _ / g, g]\n        },\n        \"hsb-rgb\": function(o, l, f) {\n          o = (o / 60 % 6 + 6) % 6;\n          var y = Math.floor(o)\n            , g = o - y\n            , y = s[y]\n            , _ = [f, f * (1 - l), f * (1 - l * g), f * (1 - l * (1 - g))];\n          return [_[y[0]], _[y[1]], _[y[2]]]\n        },\n        \"rgb-hsl\": function(o, l, f) {\n          var g = Math.max(o, l, f)\n            , y = Math.min(o, l, f)\n            , _ = g - y\n            , v = _ === 0\n            , b = v ? 0 : (g == o ? (l - f) / _ + (l < f ? 6 : 0) : g == l ? (f - o) / _ + 2 : (o - l) / _ + 4) * 60\n            , T = (g + y) / 2\n            , x = v ? 0 : T < .5 ? _ / (g + y) : _ / (2 - g - y);\n          return [b, x, T]\n        },\n        \"hsl-rgb\": function(o, l, f) {\n          if (o = (o / 360 % 1 + 1) % 1,\n          l === 0)\n            return [f, f, f];\n          for (var g = [o + 1 / 3, o, o - 1 / 3], y = f < .5 ? f * (1 + l) : f + l - f * l, _ = 2 * f - y, v = [], b = 0; b < 3; b++) {\n            var T = g[b];\n            T < 0 && (T += 1),\n            T > 1 && (T -= 1),\n              v[b] = 6 * T < 1 ? _ + (y - _) * 6 * T : 2 * T < 1 ? y : 3 * T < 2 ? _ + (y - _) * (2 / 3 - T) * 6 : _\n          }\n          return v\n        },\n        \"rgb-gray\": function(o, l, f) {\n          return [o * .2989 + l * .587 + f * .114]\n        },\n        \"gray-rgb\": function(o) {\n          return [o, o, o]\n        },\n        \"gray-hsb\": function(o) {\n          return [0, 0, o]\n        },\n        \"gray-hsl\": function(o) {\n          return [0, 0, o]\n        },\n        \"gradient-rgb\": function() {\n          return []\n        },\n        \"rgb-gradient\": function() {\n          return []\n        }\n      };\n      return d.each(e, function(o, l) {\n        t[l] = [],\n          d.each(o, function(f, g) {\n            var y = d.capitalize(f)\n              , _ = /^(hue|saturation)$/.test(f)\n              , v = t[l][g] = l === \"gradient\" ? f === \"gradient\" ? function(b) {\n                    var T = this._components[0];\n                    return b = xt.read(Array.isArray(b) ? b : arguments, 0, {\n                      readNull: !0\n                    }),\n                    T !== b && (T && T._removeOwner(this),\n                    b && b._addOwner(this)),\n                      b\n                  }\n                  : function() {\n                    return C.read(arguments, 0, {\n                      readNull: f === \"highlight\",\n                      clone: !0\n                    })\n                  }\n                : function(b) {\n                  return b == null || isNaN(b) ? 0 : +b\n                }\n            ;\n            this[\"get\" + y] = function() {\n              return this._type === l || _ && /^hs[bl]$/.test(this._type) ? this._components[g] : this._convert(l)[g]\n            }\n              ,\n              this[\"set\" + y] = function(b) {\n                this._type !== l && !(_ && /^hs[bl]$/.test(this._type)) && (this._components = this._convert(l),\n                  this._properties = e[l],\n                  this._type = l),\n                  this._components[g] = v.call(this, b),\n                  this._changed()\n              }\n          }, this)\n      }, {\n        _class: \"Color\",\n        _readIndex: !0,\n        initialize: function o(l) {\n          var f = arguments, g = this.__read, y = 0, _, v, b, T;\n          Array.isArray(l) && (f = l,\n            l = f[0]);\n          var x = l != null && typeof l;\n          if (x === \"string\" && l in e && (_ = l,\n            l = f[1],\n            Array.isArray(l) ? (v = l,\n              b = f[2]) : (g && (y = 1),\n              f = d.slice(f, 1),\n              x = typeof l)),\n            !v) {\n            if (T = x === \"number\" ? f : x === \"object\" && l.length != null ? l : null,\n              T) {\n              _ || (_ = T.length >= 3 ? \"rgb\" : \"gray\");\n              var S = e[_].length;\n              b = T[S],\n              g && (y += T === arguments ? S + (b != null ? 1 : 0) : 1),\n              T.length > S && (T = d.slice(T, 0, S))\n            } else if (x === \"string\") {\n              var I = r(l);\n              _ = I[0],\n                v = I[1],\n              v.length === 4 && (b = v[3],\n                v.length--)\n            } else if (x === \"object\")\n              if (l.constructor === o) {\n                if (_ = l._type,\n                  v = l._components.slice(),\n                  b = l._alpha,\n                _ === \"gradient\")\n                  for (var m = 1, w = v.length; m < w; m++) {\n                    var E = v[m];\n                    E && (v[m] = E.clone())\n                  }\n              } else if (l.constructor === xt)\n                _ = \"gradient\",\n                  T = f;\n              else {\n                _ = \"hue\"in l ? \"lightness\"in l ? \"hsl\" : \"hsb\" : \"gradient\"in l || \"stops\"in l || \"radial\"in l ? \"gradient\" : \"gray\"in l ? \"gray\" : \"rgb\";\n                var A = e[_]\n                  , N = t[_];\n                this._components = v = [];\n                for (var m = 0, w = A.length; m < w; m++) {\n                  var L = l[A[m]];\n                  L == null && !m && _ === \"gradient\" && \"stops\"in l && (L = {\n                    stops: l.stops,\n                    radial: l.radial\n                  }),\n                    L = N[m].call(this, L),\n                  L != null && (v[m] = L)\n                }\n                b = l.alpha\n              }\n            g && _ && (y = 1)\n          }\n          if (this._type = _ || \"rgb\",\n            !v) {\n            this._components = v = [];\n            for (var N = t[this._type], m = 0, w = N.length; m < w; m++) {\n              var L = N[m].call(this, T && T[m]);\n              L != null && (v[m] = L)\n            }\n          }\n          return this._components = v,\n            this._properties = e[this._type],\n            this._alpha = b,\n          g && (this.__read = y),\n            this\n        },\n        set: \"#initialize\",\n        _serialize: function(o, l) {\n          var f = this.getComponents();\n          return d.serialize(/^(gray|rgb)$/.test(this._type) ? f : [this._type].concat(f), o, !0, l)\n        },\n        _changed: function() {\n          this._canvasStyle = null,\n          this._owner && (this._setter ? this._owner[this._setter](this) : this._owner._changed(129))\n        },\n        _convert: function(o) {\n          var l;\n          return this._type === o ? this._components.slice() : (l = u[this._type + \"-\" + o]) ? l.apply(this, this._components) : u[\"rgb-\" + o].apply(this, u[this._type + \"-rgb\"].apply(this, this._components))\n        },\n        convert: function(o) {\n          return new Xe(o,this._convert(o),this._alpha)\n        },\n        getType: function() {\n          return this._type\n        },\n        setType: function(o) {\n          this._components = this._convert(o),\n            this._properties = e[o],\n            this._type = o\n        },\n        getComponents: function() {\n          var o = this._components.slice();\n          return this._alpha != null && o.push(this._alpha),\n            o\n        },\n        getAlpha: function() {\n          return this._alpha != null ? this._alpha : 1\n        },\n        setAlpha: function(o) {\n          this._alpha = o == null ? null : Math.min(Math.max(o, 0), 1),\n            this._changed()\n        },\n        hasAlpha: function() {\n          return this._alpha != null\n        },\n        equals: function(o) {\n          var l = d.isPlainValue(o, !0) ? Xe.read(arguments) : o;\n          return l === this || l && this._class === l._class && this._type === l._type && this.getAlpha() === l.getAlpha() && d.equals(this._components, l._components) || !1\n        },\n        toString: function() {\n          for (var o = this._properties, l = [], f = this._type === \"gradient\", g = k.instance, y = 0, _ = o.length; y < _; y++) {\n            var v = this._components[y];\n            v != null && l.push(o[y] + \": \" + (f ? v : g.number(v)))\n          }\n          return this._alpha != null && l.push(\"alpha: \" + g.number(this._alpha)),\n          \"{ \" + l.join(\", \") + \" }\"\n        },\n        toCSS: function(o) {\n          var l = this._convert(\"rgb\")\n            , f = o || this._alpha == null ? 1 : this._alpha;\n          function g(y) {\n            return Math.round((y < 0 ? 0 : y > 1 ? 1 : y) * 255)\n          }\n          return l = [g(l[0]), g(l[1]), g(l[2])],\n          f < 1 && l.push(f < 0 ? 0 : f),\n            o ? \"#\" + ((1 << 24) + (l[0] << 16) + (l[1] << 8) + l[2]).toString(16).slice(1) : (l.length == 4 ? \"rgba(\" : \"rgb(\") + l.join(\",\") + \")\"\n        },\n        toCanvasStyle: function(o, l) {\n          if (this._canvasStyle)\n            return this._canvasStyle;\n          if (this._type !== \"gradient\")\n            return this._canvasStyle = this.toCSS();\n          var f = this._components, g = f[0], y = g._stops, _ = f[1], v = f[2], b = f[3], T = l && l.inverted(), x;\n          if (T && (_ = T._transformPoint(_),\n            v = T._transformPoint(v),\n          b && (b = T._transformPoint(b))),\n            g._radial) {\n            var S = v.getDistance(_);\n            if (b) {\n              var I = b.subtract(_);\n              I.getLength() > S && (b = _.add(I.normalize(S - .1)))\n            }\n            var m = b || _;\n            x = o.createRadialGradient(m.x, m.y, 0, _.x, _.y, S)\n          } else\n            x = o.createLinearGradient(_.x, _.y, v.x, v.y);\n          for (var w = 0, E = y.length; w < E; w++) {\n            var A = y[w]\n              , N = A._offset;\n            x.addColorStop(N ?? w / (E - 1), A._color.toCanvasStyle())\n          }\n          return this._canvasStyle = x\n        },\n        transform: function(o) {\n          if (this._type === \"gradient\") {\n            for (var l = this._components, f = 1, g = l.length; f < g; f++) {\n              var y = l[f];\n              o._transformPoint(y, y, !0)\n            }\n            this._changed()\n          }\n        },\n        statics: {\n          _types: e,\n          random: function() {\n            var o = Math.random;\n            return new Xe(o(),o(),o())\n          },\n          _setOwner: function(o, l, f) {\n            return o && (o._owner && l && o._owner !== l && (o = o.clone()),\n            !o._owner ^ !l && (o._owner = l || null,\n              o._setter = f || null)),\n              o\n          }\n        }\n      })\n    }\n    , new function() {\n      var e = {\n        add: function(t, n) {\n          return t + n\n        },\n        subtract: function(t, n) {\n          return t - n\n        },\n        multiply: function(t, n) {\n          return t * n\n        },\n        divide: function(t, n) {\n          return t / n\n        }\n      };\n      return d.each(e, function(t, n) {\n        this[n] = function(i) {\n          i = Xe.read(arguments);\n          for (var r = this._type, s = this._components, u = i._convert(r), o = 0, l = s.length; o < l; o++)\n            u[o] = t(s[o], u[o]);\n          return new Xe(r,u,this._alpha != null ? t(this._alpha, i.getAlpha()) : null)\n        }\n      }, {})\n    }\n  )\n    , xt = d.extend({\n    _class: \"Gradient\",\n    initialize: function(t, n) {\n      this._id = B.get(),\n      t && d.isPlainObject(t) && (this.set(t),\n        t = n = null),\n      this._stops == null && this.setStops(t || [\"white\", \"black\"]),\n      this._radial == null && this.setRadial(typeof n == \"string\" && n === \"radial\" || n || !1)\n    },\n    _serialize: function(e, t) {\n      return t.add(this, function() {\n        return d.serialize([this._stops, this._radial], e, !0, t)\n      })\n    },\n    _changed: function() {\n      for (var e = 0, t = this._owners && this._owners.length; e < t; e++)\n        this._owners[e]._changed()\n    },\n    _addOwner: function(e) {\n      this._owners || (this._owners = []),\n        this._owners.push(e)\n    },\n    _removeOwner: function(e) {\n      var t = this._owners ? this._owners.indexOf(e) : -1;\n      t != -1 && (this._owners.splice(t, 1),\n      this._owners.length || (this._owners = a))\n    },\n    clone: function() {\n      for (var e = [], t = 0, n = this._stops.length; t < n; t++)\n        e[t] = this._stops[t].clone();\n      return new xt(e,this._radial)\n    },\n    getStops: function() {\n      return this._stops\n    },\n    setStops: function(e) {\n      if (e.length < 2)\n        throw new Error(\"Gradient stop list needs to contain at least two stops.\");\n      var t = this._stops;\n      if (t)\n        for (var n = 0, i = t.length; n < i; n++)\n          t[n]._owner = a;\n      t = this._stops = en.readList(e, 0, {\n        clone: !0\n      });\n      for (var n = 0, i = t.length; n < i; n++)\n        t[n]._owner = this;\n      this._changed()\n    },\n    getRadial: function() {\n      return this._radial\n    },\n    setRadial: function(e) {\n      this._radial = e,\n        this._changed()\n    },\n    equals: function(e) {\n      if (e === this)\n        return !0;\n      if (e && this._class === e._class) {\n        var t = this._stops\n          , n = e._stops\n          , i = t.length;\n        if (i === n.length) {\n          for (var r = 0; r < i; r++)\n            if (!t[r].equals(n[r]))\n              return !1;\n          return !0\n        }\n      }\n      return !1\n    }\n  })\n    , en = d.extend({\n    _class: \"GradientStop\",\n    initialize: function(t, n) {\n      var i = t\n        , r = n;\n      typeof t == \"object\" && n === a && (Array.isArray(t) && typeof t[0] != \"number\" ? (i = t[0],\n        r = t[1]) : (\"color\"in t || \"offset\"in t || \"rampPoint\"in t) && (i = t.color,\n        r = t.offset || t.rampPoint || 0)),\n        this.setColor(i),\n        this.setOffset(r)\n    },\n    clone: function() {\n      return new en(this._color.clone(),this._offset)\n    },\n    _serialize: function(e, t) {\n      var n = this._color\n        , i = this._offset;\n      return d.serialize(i == null ? [n] : [n, i], e, !0, t)\n    },\n    _changed: function() {\n      this._owner && this._owner._changed(129)\n    },\n    getOffset: function() {\n      return this._offset\n    },\n    setOffset: function(e) {\n      this._offset = e,\n        this._changed()\n    },\n    getRampPoint: \"#getOffset\",\n    setRampPoint: \"#setOffset\",\n    getColor: function() {\n      return this._color\n    },\n    setColor: function() {\n      Xe._setOwner(this._color, null),\n        this._color = Xe._setOwner(Xe.read(arguments, 0), this, \"setColor\"),\n        this._changed()\n    },\n    equals: function(e) {\n      return e === this || e && this._class === e._class && this._color.equals(e._color) && this._offset == e._offset || !1\n    }\n  })\n    , Kt = d.extend(new function() {\n      var e = {\n        fillColor: null,\n        fillRule: \"nonzero\",\n        strokeColor: null,\n        strokeWidth: 1,\n        strokeCap: \"butt\",\n        strokeJoin: \"miter\",\n        strokeScaling: !0,\n        miterLimit: 10,\n        dashOffset: 0,\n        dashArray: [],\n        shadowColor: null,\n        shadowBlur: 0,\n        shadowOffset: new C,\n        selectedColor: null\n      }\n        , t = d.set({}, e, {\n        fontFamily: \"sans-serif\",\n        fontWeight: \"normal\",\n        fontSize: 12,\n        leading: null,\n        justification: \"left\"\n      })\n        , n = d.set({}, t, {\n        fillColor: new Xe\n      })\n        , i = {\n        strokeWidth: 193,\n        strokeCap: 193,\n        strokeJoin: 193,\n        strokeScaling: 201,\n        miterLimit: 193,\n        fontFamily: 9,\n        fontWeight: 9,\n        fontSize: 9,\n        font: 9,\n        leading: 9,\n        justification: 9\n      }\n        , r = {\n        beans: !0\n      }\n        , s = {\n        _class: \"Style\",\n        beans: !0,\n        initialize: function(o, l, f) {\n          this._values = {},\n            this._owner = l,\n            this._project = l && l._project || f || ae.project,\n            this._defaults = !l || l instanceof We ? t : l instanceof Gt ? n : e,\n          o && this.set(o)\n        }\n      };\n      return d.each(t, function(u, o) {\n        var l = /Color$/.test(o)\n          , f = o === \"shadowOffset\"\n          , g = d.capitalize(o)\n          , y = i[o]\n          , _ = \"set\" + g\n          , v = \"get\" + g;\n        s[_] = function(b) {\n          var T = this._owner\n            , x = T && T._children\n            , S = x && x.length > 0 && !(T instanceof ot);\n          if (S)\n            for (var I = 0, m = x.length; I < m; I++)\n              x[I]._style[_](b);\n          if ((o === \"selectedColor\" || !S) && o in this._defaults) {\n            var w = this._values[o];\n            w !== b && (l && (w && (Xe._setOwner(w, null),\n              w._canvasStyle = null),\n            b && b.constructor === Xe && (b = Xe._setOwner(b, T, S && _))),\n              this._values[o] = b,\n            T && T._changed(y || 129))\n          }\n        }\n          ,\n          s[v] = function(b) {\n            var T = this._owner, x = T && T._children, S = x && x.length > 0 && !(T instanceof ot), I;\n            if (S && !b)\n              for (var m = 0, w = x.length; m < w; m++) {\n                var E = x[m]._style[v]();\n                if (!m)\n                  I = E;\n                else if (!d.equals(I, E))\n                  return a\n              }\n            else if (o in this._defaults) {\n              var I = this._values[o];\n              if (I === a)\n                I = this._defaults[o],\n                I && I.clone && (I = I.clone());\n              else {\n                var A = l ? Xe : f ? C : null;\n                A && !(I && I.constructor === A) && (this._values[o] = I = A.read([I], 0, {\n                  readNull: !0,\n                  clone: !0\n                }))\n              }\n            }\n            return I && l && (I = Xe._setOwner(I, T, S && _)),\n              I\n          }\n          ,\n          r[v] = function(b) {\n            return this._style[v](b)\n          }\n          ,\n          r[_] = function(b) {\n            this._style[_](b)\n          }\n      }),\n        d.each({\n          Font: \"FontFamily\",\n          WindingRule: \"FillRule\"\n        }, function(u, o) {\n          var l = \"get\" + o\n            , f = \"set\" + o;\n          s[l] = r[l] = \"#get\" + u,\n            s[f] = r[f] = \"#set\" + u\n        }),\n        oe.inject(r),\n        s\n    }\n    , {\n      set: function(e) {\n        var t = e instanceof Kt\n          , n = t ? e._values : e;\n        if (n) {\n          for (var i in n)\n            if (i in this._defaults) {\n              var r = n[i];\n              this[i] = r && t && r.clone ? r.clone() : r\n            }\n        }\n      },\n      equals: function(e) {\n        function t(n, i, r) {\n          var s = n._values\n            , u = i._values\n            , o = i._defaults;\n          for (var l in s) {\n            var f = s[l]\n              , g = u[l];\n            if (!(r && l in u) && !d.equals(f, g === a ? o[l] : g))\n              return !1\n          }\n          return !0\n        }\n        return e === this || e && this._class === e._class && t(this, e) && t(e, this, !0) || !1\n      },\n      _dispose: function() {\n        var e;\n        e = this.getFillColor(),\n        e && (e._canvasStyle = null),\n          e = this.getStrokeColor(),\n        e && (e._canvasStyle = null),\n          e = this.getShadowColor(),\n        e && (e._canvasStyle = null)\n      },\n      hasFill: function() {\n        var e = this.getFillColor();\n        return !!e && e.alpha > 0\n      },\n      hasStroke: function() {\n        var e = this.getStrokeColor();\n        return !!e && e.alpha > 0 && this.getStrokeWidth() > 0\n      },\n      hasShadow: function() {\n        var e = this.getShadowColor();\n        return !!e && e.alpha > 0 && (this.getShadowBlur() > 0 || !this.getShadowOffset().isZero())\n      },\n      getView: function() {\n        return this._project._view\n      },\n      getFontStyle: function() {\n        var e = this.getFontSize();\n        return this.getFontWeight() + \" \" + e + (/[a-z]/i.test(e + \"\") ? \" \" : \"px \") + this.getFontFamily()\n      },\n      getFont: \"#getFontFamily\",\n      setFont: \"#setFontFamily\",\n      getLeading: function e() {\n        var t = e.base.call(this)\n          , n = this.getFontSize();\n        return /pt|em|%|px/.test(n) && (n = this.getView().getPixelSize(n)),\n        t ?? n * 1.2\n      }\n    })\n    , Ce = new function() {\n    function e(t, n, i, r) {\n      for (var s = [\"\", \"webkit\", \"moz\", \"Moz\", \"ms\", \"o\"], u = n[0].toUpperCase() + n.substring(1), o = 0; o < 6; o++) {\n        var l = s[o]\n          , f = l ? l + u : n;\n        if (f in t) {\n          if (i)\n            t[f] = r;\n          else\n            return t[f];\n          break\n        }\n      }\n    }\n    return {\n      getStyles: function(t) {\n        var n = t && t.nodeType !== 9 ? t.ownerDocument : t\n          , i = n && n.defaultView;\n        return i && i.getComputedStyle(t, \"\")\n      },\n      getBounds: function(t, n) {\n        var i = t.ownerDocument, r = i.body, s = i.documentElement, u;\n        try {\n          u = t.getBoundingClientRect()\n        } catch {\n          u = {\n            left: 0,\n            top: 0,\n            width: 0,\n            height: 0\n          }\n        }\n        var o = u.left - (s.clientLeft || r.clientLeft || 0)\n          , l = u.top - (s.clientTop || r.clientTop || 0);\n        if (!n) {\n          var f = i.defaultView;\n          o += f.pageXOffset || s.scrollLeft || r.scrollLeft,\n            l += f.pageYOffset || s.scrollTop || r.scrollTop\n        }\n        return new Y(o,l,u.width,u.height)\n      },\n      getViewportBounds: function(t) {\n        var n = t.ownerDocument\n          , i = n.defaultView\n          , r = n.documentElement;\n        return new Y(0,0,i.innerWidth || r.clientWidth,i.innerHeight || r.clientHeight)\n      },\n      getOffset: function(t, n) {\n        return Ce.getBounds(t, n).getPoint()\n      },\n      getSize: function(t) {\n        return Ce.getBounds(t, !0).getSize()\n      },\n      isInvisible: function(t) {\n        return Ce.getSize(t).equals(new J(0,0))\n      },\n      isInView: function(t) {\n        return !Ce.isInvisible(t) && Ce.getViewportBounds(t).intersects(Ce.getBounds(t, !0))\n      },\n      isInserted: function(t) {\n        return p.body.contains(t)\n      },\n      getPrefixed: function(t, n) {\n        return t && e(t, n)\n      },\n      setPrefixed: function(t, n, i) {\n        if (typeof n == \"object\")\n          for (var r in n)\n            e(t, r, !0, n[r]);\n        else\n          e(t, n, !0, i)\n      }\n    }\n  }\n    , tt = {\n    add: function(e, t) {\n      if (e)\n        for (var n in t)\n          for (var i = t[n], r = n.split(/[\\s,]+/g), s = 0, u = r.length; s < u; s++) {\n            var o = r[s]\n              , l = e === p && (o === \"touchstart\" || o === \"touchmove\") ? {\n              passive: !1\n            } : !1;\n            e.addEventListener(o, i, l)\n          }\n    },\n    remove: function(e, t) {\n      if (e)\n        for (var n in t)\n          for (var i = t[n], r = n.split(/[\\s,]+/g), s = 0, u = r.length; s < u; s++)\n            e.removeEventListener(r[s], i, !1)\n    },\n    getPoint: function(e) {\n      var t = e.targetTouches ? e.targetTouches.length ? e.targetTouches[0] : e.changedTouches[0] : e;\n      return new C(t.pageX || t.clientX + p.documentElement.scrollLeft,t.pageY || t.clientY + p.documentElement.scrollTop)\n    },\n    getTarget: function(e) {\n      return e.target || e.srcElement\n    },\n    getRelatedTarget: function(e) {\n      return e.relatedTarget || e.toElement\n    },\n    getOffset: function(e, t) {\n      return tt.getPoint(e).subtract(Ce.getOffset(t || tt.getTarget(e)))\n    }\n  };\n  tt.requestAnimationFrame = new function() {\n    var e = Ce.getPrefixed(h, \"requestAnimationFrame\"), t = !1, n = [], i;\n    function r() {\n      var s = n;\n      n = [];\n      for (var u = 0, o = s.length; u < o; u++)\n        s[u]();\n      t = e && n.length,\n      t && e(r)\n    }\n    return function(s) {\n      n.push(s),\n        e ? t || (e(r),\n          t = !0) : i || (i = setInterval(r, 16.666666666666668))\n    }\n  }\n  ;\n  var Ke = d.extend(M, {\n      _class: \"View\",\n      initialize: function e(t, n) {\n        function i(y) {\n          return n[y] || parseInt(n.getAttribute(y), 10)\n        }\n        function r() {\n          var y = Ce.getSize(n);\n          return y.isNaN() || y.isZero() ? new J(i(\"width\"),i(\"height\")) : y\n        }\n        var s;\n        if (h && n) {\n          this._id = n.getAttribute(\"id\"),\n          this._id == null && n.setAttribute(\"id\", this._id = \"paper-view-\" + e._id++),\n            tt.add(n, this._viewEvents);\n          var u = \"none\";\n          if (Ce.setPrefixed(n.style, {\n            userDrag: u,\n            userSelect: u,\n            touchAction: u,\n            touchCallout: u,\n            contentZooming: u,\n            tapHighlightColor: \"rgba(0,0,0,0)\"\n          }),\n            F.hasAttribute(n, \"resize\")) {\n            var o = this;\n            tt.add(h, this._windowEvents = {\n              resize: function() {\n                o.setViewSize(r())\n              }\n            })\n          }\n          if (s = r(),\n          F.hasAttribute(n, \"stats\") && typeof Stats < \"u\") {\n            this._stats = new Stats;\n            var l = this._stats.domElement\n              , f = l.style\n              , g = Ce.getOffset(n);\n            f.position = \"absolute\",\n              f.left = g.x + \"px\",\n              f.top = g.y + \"px\",\n              p.body.appendChild(l)\n          }\n        } else\n          s = new J(n),\n            n = null;\n        this._project = t,\n          this._scope = t._scope,\n          this._element = n,\n        this._pixelRatio || (this._pixelRatio = h && h.devicePixelRatio || 1),\n          this._setElementSize(s.width, s.height),\n          this._viewSize = s,\n          e._views.push(this),\n          e._viewsById[this._id] = this,\n          (this._matrix = new le)._owner = this,\n        e._focused || (e._focused = this),\n          this._frameItems = {},\n          this._frameItemCount = 0,\n          this._itemEvents = {\n            native: {},\n            virtual: {}\n          },\n          this._autoUpdate = !ae.agent.node,\n          this._needsUpdate = !1\n      },\n      remove: function() {\n        if (!this._project)\n          return !1;\n        Ke._focused === this && (Ke._focused = null),\n          Ke._views.splice(Ke._views.indexOf(this), 1),\n          delete Ke._viewsById[this._id];\n        var e = this._project;\n        return e._view === this && (e._view = null),\n          tt.remove(this._element, this._viewEvents),\n          tt.remove(h, this._windowEvents),\n          this._element = this._project = null,\n          this.off(\"frame\"),\n          this._animate = !1,\n          this._frameItems = {},\n          !0\n      },\n      _events: d.each(oe._itemHandlers.concat([\"onResize\", \"onKeyDown\", \"onKeyUp\"]), function(e) {\n        this[e] = {}\n      }, {\n        onFrame: {\n          install: function() {\n            this.play()\n          },\n          uninstall: function() {\n            this.pause()\n          }\n        }\n      }),\n      _animate: !1,\n      _time: 0,\n      _count: 0,\n      getAutoUpdate: function() {\n        return this._autoUpdate\n      },\n      setAutoUpdate: function(e) {\n        this._autoUpdate = e,\n        e && this.requestUpdate()\n      },\n      update: function() {},\n      draw: function() {\n        this.update()\n      },\n      requestUpdate: function() {\n        if (!this._requested) {\n          var e = this;\n          tt.requestAnimationFrame(function() {\n            if (e._requested = !1,\n              e._animate) {\n              e.requestUpdate();\n              var t = e._element;\n              (!Ce.getPrefixed(p, \"hidden\") || F.getAttribute(t, \"keepalive\") === \"true\") && Ce.isInView(t) && e._handleFrame()\n            }\n            e._autoUpdate && e.update()\n          }),\n            this._requested = !0\n        }\n      },\n      play: function() {\n        this._animate = !0,\n          this.requestUpdate()\n      },\n      pause: function() {\n        this._animate = !1\n      },\n      _handleFrame: function() {\n        ae = this._scope;\n        var e = Date.now() / 1e3\n          , t = this._last ? e - this._last : 0;\n        this._last = e,\n          this.emit(\"frame\", new d({\n            delta: t,\n            time: this._time += t,\n            count: this._count++\n          })),\n        this._stats && this._stats.update()\n      },\n      _animateItem: function(e, t) {\n        var n = this._frameItems;\n        t ? (n[e._id] = {\n          item: e,\n          time: 0,\n          count: 0\n        },\n        ++this._frameItemCount === 1 && this.on(\"frame\", this._handleFrameItems)) : (delete n[e._id],\n        --this._frameItemCount === 0 && this.off(\"frame\", this._handleFrameItems))\n      },\n      _handleFrameItems: function(e) {\n        for (var t in this._frameItems) {\n          var n = this._frameItems[t];\n          n.item.emit(\"frame\", new d(e,{\n            time: n.time += e.delta,\n            count: n.count++\n          }))\n        }\n      },\n      _changed: function() {\n        this._project._changed(4097),\n          this._bounds = this._decomposed = a\n      },\n      getElement: function() {\n        return this._element\n      },\n      getPixelRatio: function() {\n        return this._pixelRatio\n      },\n      getResolution: function() {\n        return this._pixelRatio * 72\n      },\n      getViewSize: function() {\n        var e = this._viewSize;\n        return new ne(e.width,e.height,this,\"setViewSize\")\n      },\n      setViewSize: function() {\n        var e = J.read(arguments)\n          , t = e.subtract(this._viewSize);\n        t.isZero() || (this._setElementSize(e.width, e.height),\n          this._viewSize.set(e),\n          this._changed(),\n          this.emit(\"resize\", {\n            size: e,\n            delta: t\n          }),\n        this._autoUpdate && this.update())\n      },\n      _setElementSize: function(e, t) {\n        var n = this._element;\n        n && (n.width !== e && (n.width = e),\n        n.height !== t && (n.height = t))\n      },\n      getBounds: function() {\n        return this._bounds || (this._bounds = this._matrix.inverted()._transformBounds(new Y(new C,this._viewSize))),\n          this._bounds\n      },\n      getSize: function() {\n        return this.getBounds().getSize()\n      },\n      isVisible: function() {\n        return Ce.isInView(this._element)\n      },\n      isInserted: function() {\n        return Ce.isInserted(this._element)\n      },\n      getPixelSize: function(e) {\n        var t = this._element, n;\n        if (t) {\n          var i = t.parentNode\n            , r = p.createElement(\"div\");\n          r.style.fontSize = e,\n            i.appendChild(r),\n            n = parseFloat(Ce.getStyles(r).fontSize),\n            i.removeChild(r)\n        } else\n          n = parseFloat(n);\n        return n\n      },\n      getTextWidth: function(e, t) {\n        return 0\n      }\n    }, d.each([\"rotate\", \"scale\", \"shear\", \"skew\"], function(e) {\n      var t = e === \"rotate\";\n      this[e] = function() {\n        var n = arguments\n          , i = (t ? d : C).read(n)\n          , r = C.read(n, 0, {\n          readNull: !0\n        });\n        return this.transform(new le()[e](i, r || this.getCenter(!0)))\n      }\n    }, {\n      _decompose: function() {\n        return this._decomposed || (this._decomposed = this._matrix.decompose())\n      },\n      translate: function() {\n        var e = new le;\n        return this.transform(e.translate.apply(e, arguments))\n      },\n      getCenter: function() {\n        return this.getBounds().getCenter()\n      },\n      setCenter: function() {\n        var e = C.read(arguments);\n        this.translate(this.getCenter().subtract(e))\n      },\n      getZoom: function() {\n        var e = this._decompose().scaling;\n        return (e.x + e.y) / 2\n      },\n      setZoom: function(e) {\n        this.transform(new le().scale(e / this.getZoom(), this.getCenter()))\n      },\n      getRotation: function() {\n        return this._decompose().rotation\n      },\n      setRotation: function(e) {\n        var t = this.getRotation();\n        t != null && e != null && this.rotate(e - t)\n      },\n      getScaling: function() {\n        var e = this._decompose().scaling;\n        return new Q(e.x,e.y,this,\"setScaling\")\n      },\n      setScaling: function() {\n        var e = this.getScaling()\n          , t = C.read(arguments, 0, {\n          clone: !0,\n          readNull: !0\n        });\n        e && t && this.scale(t.x / e.x, t.y / e.y)\n      },\n      getMatrix: function() {\n        return this._matrix\n      },\n      setMatrix: function() {\n        var e = this._matrix;\n        e.set.apply(e, arguments)\n      },\n      transform: function(e) {\n        this._matrix.append(e)\n      },\n      scrollBy: function() {\n        this.translate(C.read(arguments).negate())\n      }\n    }), {\n      projectToView: function() {\n        return this._matrix._transformPoint(C.read(arguments))\n      },\n      viewToProject: function() {\n        return this._matrix._inverseTransform(C.read(arguments))\n      },\n      getEventPoint: function(e) {\n        return this.viewToProject(tt.getOffset(e, this._element))\n      }\n    }, {\n      statics: {\n        _views: [],\n        _viewsById: {},\n        _id: 0,\n        create: function(e, t) {\n          p && typeof t == \"string\" && (t = p.getElementById(t));\n          var n = h ? Rt : Ke;\n          return new n(e,t)\n        }\n      }\n    }, new function() {\n      if (!h)\n        return;\n      var e, t, n = !1, i = !1;\n      function r(z) {\n        var G = tt.getTarget(z);\n        return G.getAttribute && Ke._viewsById[G.getAttribute(\"id\")]\n      }\n      function s() {\n        var z = Ke._focused;\n        if (!z || !z.isVisible()) {\n          for (var G = 0, H = Ke._views.length; G < H; G++)\n            if ((z = Ke._views[G]).isVisible()) {\n              Ke._focused = t = z;\n              break\n            }\n        }\n      }\n      function u(z, G, H) {\n        z._handleMouseEvent(\"mousemove\", G, H)\n      }\n      var o, l, f;\n      \"onpointerdown\"in h || h.PointerEvent || h.MSPointerEvent ? (o = \"pointerdown MSPointerDown\",\n        l = \"pointermove MSPointerMove\",\n        f = \"pointerup pointercancel MSPointerUp MSPointerCancel\") : (o = \"touchstart\",\n        l = \"touchmove\",\n        f = \"touchend touchcancel\",\n      \"ontouchstart\"in h && navigator.userAgent.match(/mobile|tablet|ip(ad|hone|od)|android|silk/i) || (o += \" mousedown\",\n        l += \" mousemove\",\n        f += \" mouseup\"));\n      var g = {}\n        , y = {\n        mouseout: function(z) {\n          var G = Ke._focused\n            , H = tt.getRelatedTarget(z);\n          if (G && (!H || H.nodeName === \"HTML\")) {\n            var K = tt.getOffset(z, G._element)\n              , $ = K.x\n              , W = Math.abs\n              , te = W($)\n              , se = 1 << 25\n              , ue = te - se;\n            K.x = W(ue) < te ? ue * ($ < 0 ? -1 : 1) : $,\n              u(G, z, G.viewToProject(K))\n          }\n        },\n        scroll: s\n      };\n      g[o] = function(z) {\n        var G = Ke._focused = r(z);\n        n || (n = !0,\n          G._handleMouseEvent(\"mousedown\", z))\n      }\n        ,\n        y[l] = function(z) {\n          var G = Ke._focused;\n          if (!i) {\n            var H = r(z);\n            H ? G !== H && (G && u(G, z),\n            e || (e = G),\n              G = Ke._focused = t = H) : t && t === G && (e && !e.isInserted() && (e = null),\n              G = Ke._focused = e,\n              e = null,\n              s())\n          }\n          G && u(G, z)\n        }\n        ,\n        y[o] = function() {\n          i = !0\n        }\n        ,\n        y[f] = function(z) {\n          var G = Ke._focused;\n          G && n && G._handleMouseEvent(\"mouseup\", z),\n            i = n = !1\n        }\n        ,\n        tt.add(p, y),\n        tt.add(h, {\n          load: s\n        });\n      var _ = !1, v = !1, b = {\n        doubleclick: \"click\",\n        mousedrag: \"mousemove\"\n      }, T = !1, x, S, I, m, w, E, A, N, L;\n      function R(z, G, H, K, $, W, te) {\n        var se = !1, ue;\n        function Ie(Ee, de) {\n          if (Ee.responds(de)) {\n            if (ue || (ue = new wn(de,K,$,G || Ee,W ? $.subtract(W) : null)),\n            Ee.emit(de, ue) && (_ = !0,\n            ue.prevented && (v = !0),\n              ue.stopped))\n              return se = !0\n          } else {\n            var ve = b[de];\n            if (ve)\n              return Ie(Ee, ve)\n          }\n        }\n        for (; z && z !== te && !Ie(z, H); )\n          z = z._parent;\n        return se\n      }\n      function D(z, G, H, K, $, W) {\n        return z._project.removeOn(H),\n          v = _ = !1,\n        E && R(E, null, H, K, $, W) || G && G !== E && !G.isDescendant(E) && R(G, null, H === \"mousedrag\" ? \"mousemove\" : H, K, $, W, E) || R(z, E || G || z, H, K, $, W)\n      }\n      var V = {\n        mousedown: {\n          mousedown: 1,\n          mousedrag: 1,\n          click: 1,\n          doubleclick: 1\n        },\n        mouseup: {\n          mouseup: 1,\n          mousedrag: 1,\n          click: 1,\n          doubleclick: 1\n        },\n        mousemove: {\n          mousedrag: 1,\n          mousemove: 1,\n          mouseenter: 1,\n          mouseleave: 1\n        }\n      };\n      return {\n        _viewEvents: g,\n        _handleMouseEvent: function(z, G, H) {\n          var K = this._itemEvents\n            , $ = K.native[z]\n            , W = z === \"mousemove\"\n            , te = this._scope.tool\n            , se = this;\n          function ue(Ge) {\n            return K.virtual[Ge] || se.responds(Ge) || te && te.responds(Ge)\n          }\n          W && n && ue(\"mousedrag\") && (z = \"mousedrag\"),\n          H || (H = this.getEventPoint(G));\n          var Ie = this.getBounds().contains(H)\n            , Ee = $ && Ie && se._project.hitTest(H, {\n            tolerance: 0,\n            fill: !0,\n            stroke: !0\n          })\n            , de = Ee && Ee.item || null\n            , ve = !1\n            , Oe = {};\n          if (Oe[z.substr(5)] = !0,\n          $ && de !== w && (w && R(w, null, \"mouseleave\", G, H),\n          de && R(de, null, \"mouseenter\", G, H),\n            w = de),\n          T ^ Ie && (R(this, null, Ie ? \"mouseenter\" : \"mouseleave\", G, H),\n            x = Ie ? this : null,\n            ve = !0),\n          (Ie || Oe.drag) && !H.equals(I) && (D(this, de, W ? z : \"mousemove\", G, H, I),\n            ve = !0),\n            T = Ie,\n          Oe.down && Ie || Oe.up && S) {\n            if (D(this, de, z, G, H, S),\n              Oe.down) {\n              if (L = de === A && Date.now() - N < 300,\n                m = A = de,\n              !v && de) {\n                for (var Te = de; Te && !Te.responds(\"mousedrag\"); )\n                  Te = Te._parent;\n                Te && (E = de)\n              }\n              S = H\n            } else\n              Oe.up && (!v && de === m && (N = Date.now(),\n                D(this, de, L ? \"doubleclick\" : \"click\", G, H, S),\n                L = !1),\n                m = E = null);\n            T = !1,\n              ve = !0\n          }\n          I = H,\n          ve && te && (_ = te._handleMouseEvent(z, G, H, Oe) || _),\n          G.cancelable !== !1 && (_ && !Oe.move || Oe.down && ue(\"mouseup\")) && G.preventDefault()\n        },\n        _handleKeyEvent: function(z, G, H, K) {\n          var $ = this._scope, W = $.tool, te;\n          function se(ue) {\n            ue.responds(z) && (ae = $,\n              ue.emit(z, te = te || new tn(z,G,H,K)))\n          }\n          this.isVisible() && (se(this),\n          W && W.responds(z) && se(W))\n        },\n        _countItemEvent: function(z, G) {\n          var H = this._itemEvents\n            , K = H.native\n            , $ = H.virtual;\n          for (var W in V)\n            K[W] = (K[W] || 0) + (V[W][z] || 0) * G;\n          $[z] = ($[z] || 0) + G\n        },\n        statics: {\n          updateFocus: s,\n          _resetState: function() {\n            n = i = _ = T = !1,\n              e = t = x = S = I = m = w = E = A = N = L = null\n          }\n        }\n      }\n    }\n  )\n    , Rt = Ke.extend({\n    _class: \"CanvasView\",\n    initialize: function(t, n) {\n      if (!(n instanceof h.HTMLCanvasElement)) {\n        var i = J.read(arguments, 1);\n        if (i.isZero())\n          throw new Error(\"Cannot create CanvasView with the provided argument: \" + d.slice(arguments, 1));\n        n = Je.getCanvas(i)\n      }\n      var r = this._context = n.getContext(\"2d\");\n      if (r.save(),\n        this._pixelRatio = 1,\n        !/^off|false$/.test(F.getAttribute(n, \"hidpi\"))) {\n        var s = h.devicePixelRatio || 1\n          , u = Ce.getPrefixed(r, \"backingStorePixelRatio\") || 1;\n        this._pixelRatio = s / u\n      }\n      Ke.call(this, t, n),\n        this._needsUpdate = !0\n    },\n    remove: function e() {\n      return this._context.restore(),\n        e.base.call(this)\n    },\n    _setElementSize: function e(t, n) {\n      var i = this._pixelRatio;\n      if (e.base.call(this, t * i, n * i),\n      i !== 1) {\n        var r = this._element\n          , s = this._context;\n        if (!F.hasAttribute(r, \"resize\")) {\n          var u = r.style;\n          u.width = t + \"px\",\n            u.height = n + \"px\"\n        }\n        s.restore(),\n          s.save(),\n          s.scale(i, i)\n      }\n    },\n    getContext: function() {\n      return this._context\n    },\n    getPixelSize: function e(t) {\n      var n = ae.agent, i;\n      if (n && n.firefox)\n        i = e.base.call(this, t);\n      else {\n        var r = this._context\n          , s = r.font;\n        r.font = t + \" serif\",\n          i = parseFloat(r.font),\n          r.font = s\n      }\n      return i\n    },\n    getTextWidth: function(e, t) {\n      var n = this._context\n        , i = n.font\n        , r = 0;\n      n.font = e;\n      for (var s = 0, u = t.length; s < u; s++)\n        r = Math.max(r, n.measureText(t[s]).width);\n      return n.font = i,\n        r\n    },\n    update: function() {\n      if (!this._needsUpdate)\n        return !1;\n      var e = this._project\n        , t = this._context\n        , n = this._viewSize;\n      return t.clearRect(0, 0, n.width + 1, n.height + 1),\n      e && e.draw(t, this._matrix, this._pixelRatio),\n        this._needsUpdate = !1,\n        !0\n    }\n  })\n    , Zt = d.extend({\n    _class: \"Event\",\n    initialize: function(t) {\n      this.event = t,\n        this.type = t && t.type\n    },\n    prevented: !1,\n    stopped: !1,\n    preventDefault: function() {\n      this.prevented = !0,\n        this.event.preventDefault()\n    },\n    stopPropagation: function() {\n      this.stopped = !0,\n        this.event.stopPropagation()\n    },\n    stop: function() {\n      this.stopPropagation(),\n        this.preventDefault()\n    },\n    getTimeStamp: function() {\n      return this.event.timeStamp\n    },\n    getModifiers: function() {\n      return cn.modifiers\n    }\n  })\n    , tn = Zt.extend({\n    _class: \"KeyEvent\",\n    initialize: function(t, n, i, r) {\n      this.type = t,\n        this.event = n,\n        this.key = i,\n        this.character = r\n    },\n    toString: function() {\n      return \"{ type: '\" + this.type + \"', key: '\" + this.key + \"', character: '\" + this.character + \"', modifiers: \" + this.getModifiers() + \" }\"\n    }\n  })\n    , cn = new function() {\n    var e = {\n      \"\t\": \"tab\",\n      \" \": \"space\",\n      \"\\b\": \"backspace\",\n      \"\\x7F\": \"delete\",\n      Spacebar: \"space\",\n      Del: \"delete\",\n      Win: \"meta\",\n      Esc: \"escape\"\n    }, t = {\n      tab: \"\t\",\n      space: \" \",\n      enter: \"\\r\"\n    }, n = {}, i = {}, r, s, u = new d({\n      shift: !1,\n      control: !1,\n      alt: !1,\n      meta: !1,\n      capsLock: !1,\n      space: !1\n    }).inject({\n      option: {\n        get: function() {\n          return this.alt\n        }\n      },\n      command: {\n        get: function() {\n          var f = ae && ae.agent;\n          return f && f.mac ? this.meta : this.control\n        }\n      }\n    });\n    function o(f) {\n      var g = f.key || f.keyIdentifier;\n      return g = /^U\\+/.test(g) ? String.fromCharCode(parseInt(g.substr(2), 16)) : /^Arrow[A-Z]/.test(g) ? g.substr(5) : g === \"Unidentified\" || g === a ? String.fromCharCode(f.keyCode) : g,\n      e[g] || (g.length > 1 ? d.hyphenate(g) : g.toLowerCase())\n    }\n    function l(f, g, y, _) {\n      var v = f ? \"keydown\" : \"keyup\", b = Ke._focused, T;\n      if (n[g] = f,\n        f ? i[g] = y : delete i[g],\n      g.length > 1 && (T = d.camelize(g))in u) {\n        u[T] = f;\n        var x = ae && ae.agent;\n        if (T === \"meta\" && x && x.mac)\n          if (f)\n            r = {};\n          else {\n            for (var S in r)\n              S in i && l(!1, S, r[S], _);\n            r = null\n          }\n      } else\n        f && r && (r[g] = y);\n      b && b._handleKeyEvent(f ? \"keydown\" : \"keyup\", _, g, y)\n    }\n    return tt.add(p, {\n      keydown: function(f) {\n        var g = o(f)\n          , y = ae && ae.agent;\n        g.length > 1 || y && y.chrome && (f.altKey || y.mac && f.metaKey || !y.mac && f.ctrlKey) ? l(!0, g, t[g] || (g.length > 1 ? \"\" : g), f) : s = g\n      },\n      keypress: function(f) {\n        if (s) {\n          var g = o(f)\n            , y = f.charCode\n            , _ = y >= 32 ? String.fromCharCode(y) : g.length > 1 ? \"\" : g;\n          g !== s && (g = _.toLowerCase()),\n            l(!0, g, _, f),\n            s = null\n        }\n      },\n      keyup: function(f) {\n        var g = o(f);\n        g in i && l(!1, g, i[g], f)\n      }\n    }),\n      tt.add(h, {\n        blur: function(f) {\n          for (var g in i)\n            l(!1, g, i[g], f)\n        }\n      }),\n      {\n        modifiers: u,\n        isDown: function(f) {\n          return !!n[f]\n        }\n      }\n  }\n    , wn = Zt.extend({\n    _class: \"MouseEvent\",\n    initialize: function(t, n, i, r, s) {\n      this.type = t,\n        this.event = n,\n        this.point = i,\n        this.target = r,\n        this.delta = s\n    },\n    toString: function() {\n      return \"{ type: '\" + this.type + \"', point: \" + this.point + \", target: \" + this.target + (this.delta ? \", delta: \" + this.delta : \"\") + \", modifiers: \" + this.getModifiers() + \" }\"\n    }\n  })\n    , bn = Zt.extend({\n    _class: \"ToolEvent\",\n    _item: null,\n    initialize: function(t, n, i) {\n      this.tool = t,\n        this.type = n,\n        this.event = i\n    },\n    _choosePoint: function(e, t) {\n      return e || (t ? t.clone() : null)\n    },\n    getPoint: function() {\n      return this._choosePoint(this._point, this.tool._point)\n    },\n    setPoint: function(e) {\n      this._point = e\n    },\n    getLastPoint: function() {\n      return this._choosePoint(this._lastPoint, this.tool._lastPoint)\n    },\n    setLastPoint: function(e) {\n      this._lastPoint = e\n    },\n    getDownPoint: function() {\n      return this._choosePoint(this._downPoint, this.tool._downPoint)\n    },\n    setDownPoint: function(e) {\n      this._downPoint = e\n    },\n    getMiddlePoint: function() {\n      return !this._middlePoint && this.tool._lastPoint ? this.tool._point.add(this.tool._lastPoint).divide(2) : this._middlePoint\n    },\n    setMiddlePoint: function(e) {\n      this._middlePoint = e\n    },\n    getDelta: function() {\n      return !this._delta && this.tool._lastPoint ? this.tool._point.subtract(this.tool._lastPoint) : this._delta\n    },\n    setDelta: function(e) {\n      this._delta = e\n    },\n    getCount: function() {\n      return this.tool[/^mouse(down|up)$/.test(this.type) ? \"_downCount\" : \"_moveCount\"]\n    },\n    setCount: function(e) {\n      this.tool[/^mouse(down|up)$/.test(this.type) ? \"downCount\" : \"count\"] = e\n    },\n    getItem: function() {\n      if (!this._item) {\n        var e = this.tool._scope.project.hitTest(this.getPoint());\n        if (e) {\n          for (var t = e.item, n = t._parent; /^(Group|CompoundPath)$/.test(n._class); )\n            t = n,\n              n = n._parent;\n          this._item = t\n        }\n      }\n      return this._item\n    },\n    setItem: function(e) {\n      this._item = e\n    },\n    toString: function() {\n      return \"{ type: \" + this.type + \", point: \" + this.getPoint() + \", count: \" + this.getCount() + \", modifiers: \" + this.getModifiers() + \" }\"\n    }\n  })\n    , kn = Z.extend({\n    _class: \"Tool\",\n    _list: \"tools\",\n    _reference: \"tool\",\n    _events: [\"onMouseDown\", \"onMouseUp\", \"onMouseDrag\", \"onMouseMove\", \"onActivate\", \"onDeactivate\", \"onEditOptions\", \"onKeyDown\", \"onKeyUp\"],\n    initialize: function(t) {\n      Z.call(this),\n        this._moveCount = -1,\n        this._downCount = -1,\n        this.set(t)\n    },\n    getMinDistance: function() {\n      return this._minDistance\n    },\n    setMinDistance: function(e) {\n      this._minDistance = e,\n      e != null && this._maxDistance != null && e > this._maxDistance && (this._maxDistance = e)\n    },\n    getMaxDistance: function() {\n      return this._maxDistance\n    },\n    setMaxDistance: function(e) {\n      this._maxDistance = e,\n      this._minDistance != null && e != null && e < this._minDistance && (this._minDistance = e)\n    },\n    getFixedDistance: function() {\n      return this._minDistance == this._maxDistance ? this._minDistance : null\n    },\n    setFixedDistance: function(e) {\n      this._minDistance = this._maxDistance = e\n    },\n    _handleMouseEvent: function(e, t, n, i) {\n      ae = this._scope,\n      i.drag && !this.responds(e) && (e = \"mousemove\");\n      var r = i.move || i.drag\n        , s = this.responds(e)\n        , u = this.minDistance\n        , o = this.maxDistance\n        , l = !1\n        , f = this;\n      function g(_, v) {\n        var b = n\n          , T = r ? f._point : f._downPoint || b;\n        if (r) {\n          if (f._moveCount >= 0 && b.equals(T))\n            return !1;\n          if (T && (_ != null || v != null)) {\n            var x = b.subtract(T)\n              , S = x.getLength();\n            if (S < (_ || 0))\n              return !1;\n            v && (b = T.add(x.normalize(Math.min(S, v))))\n          }\n          f._moveCount++\n        }\n        return f._point = b,\n          f._lastPoint = T || b,\n        i.down && (f._moveCount = -1,\n          f._downPoint = b,\n          f._downCount++),\n          !0\n      }\n      function y() {\n        s && (l = f.emit(e, new bn(f,e,t)) || l)\n      }\n      if (i.down)\n        g(),\n          y();\n      else if (i.up)\n        g(null, o),\n          y();\n      else if (s)\n        for (; g(u, o); )\n          y();\n      return l\n    }\n  })\n    , Sn = d.extend(M, {\n    _class: \"Tween\",\n    statics: {\n      easings: new d({\n        linear: function(e) {\n          return e\n        },\n        easeInQuad: function(e) {\n          return e * e\n        },\n        easeOutQuad: function(e) {\n          return e * (2 - e)\n        },\n        easeInOutQuad: function(e) {\n          return e < .5 ? 2 * e * e : -1 + 2 * (2 - e) * e\n        },\n        easeInCubic: function(e) {\n          return e * e * e\n        },\n        easeOutCubic: function(e) {\n          return --e * e * e + 1\n        },\n        easeInOutCubic: function(e) {\n          return e < .5 ? 4 * e * e * e : (e - 1) * (2 * e - 2) * (2 * e - 2) + 1\n        },\n        easeInQuart: function(e) {\n          return e * e * e * e\n        },\n        easeOutQuart: function(e) {\n          return 1 - --e * e * e * e\n        },\n        easeInOutQuart: function(e) {\n          return e < .5 ? 8 * e * e * e * e : 1 - 8 * --e * e * e * e\n        },\n        easeInQuint: function(e) {\n          return e * e * e * e * e\n        },\n        easeOutQuint: function(e) {\n          return 1 + --e * e * e * e * e\n        },\n        easeInOutQuint: function(e) {\n          return e < .5 ? 16 * e * e * e * e * e : 1 + 16 * --e * e * e * e * e\n        }\n      })\n    },\n    initialize: function e(t, n, i, r, s, u) {\n      this.object = t;\n      var o = typeof s\n        , l = o === \"function\";\n      this.type = l ? o : o === \"string\" ? s : \"linear\",\n        this.easing = l ? s : e.easings[this.type],\n        this.duration = r,\n        this.running = !1,\n        this._then = null,\n        this._startTime = null;\n      var f = n || i;\n      this._keys = f ? Object.keys(f) : [],\n        this._parsedKeys = this._parseKeys(this._keys),\n        this._from = f && this._getState(n),\n        this._to = f && this._getState(i),\n      u !== !1 && this.start()\n    },\n    then: function(e) {\n      return this._then = e,\n        this\n    },\n    start: function() {\n      return this._startTime = null,\n        this.running = !0,\n        this\n    },\n    stop: function() {\n      return this.running = !1,\n        this\n    },\n    update: function(e) {\n      if (this.running) {\n        e >= 1 && (e = 1,\n          this.running = !1);\n        for (var t = this.easing(e), n = this._keys, i = function(g) {\n          return typeof g == \"function\" ? g(t, e) : g\n        }, r = 0, s = n && n.length; r < s; r++) {\n          var u = n[r]\n            , o = i(this._from[u])\n            , l = i(this._to[u])\n            , f = o && l && o.__add && l.__add ? l.__subtract(o).__multiply(t).__add(o) : (l - o) * t + o;\n          this._setProperty(this._parsedKeys[u], f)\n        }\n        this.responds(\"update\") && this.emit(\"update\", new d({\n          progress: e,\n          factor: t\n        })),\n        !this.running && this._then && this._then(this.object)\n      }\n      return this\n    },\n    _events: {\n      onUpdate: {}\n    },\n    _handleFrame: function(e) {\n      var t = this._startTime\n        , n = t ? (e - t) / this.duration : 0;\n      t || (this._startTime = e),\n        this.update(n)\n    },\n    _getState: function(e) {\n      for (var t = this._keys, n = {}, i = 0, r = t.length; i < r; i++) {\n        var s = t[i], u = this._parsedKeys[s], o = this._getProperty(u), l;\n        if (e) {\n          var f = this._resolveValue(o, e[s]);\n          this._setProperty(u, f),\n            l = this._getProperty(u),\n            l = l && l.clone ? l.clone() : l,\n            this._setProperty(u, o)\n        } else\n          l = o && o.clone ? o.clone() : o;\n        n[s] = l\n      }\n      return n\n    },\n    _resolveValue: function(e, t) {\n      if (t) {\n        if (Array.isArray(t) && t.length === 2) {\n          var n = t[0];\n          return n && n.match && n.match(/^[+\\-\\*\\/]=/) ? this._calculate(e, n[0], t[1]) : t\n        } else if (typeof t == \"string\") {\n          var i = t.match(/^[+\\-*/]=(.*)/);\n          if (i) {\n            var r = JSON.parse(i[1].replace(/(['\"])?([a-zA-Z0-9_]+)(['\"])?:/g, '\"$2\": '));\n            return this._calculate(e, t[0], r)\n          }\n        }\n      }\n      return t\n    },\n    _calculate: function(e, t, n) {\n      return ae.PaperScript.calculateBinary(e, t, n)\n    },\n    _parseKeys: function(e) {\n      for (var t = {}, n = 0, i = e.length; n < i; n++) {\n        var r = e[n]\n          , s = r.replace(/\\.([^.]*)/g, \"/$1\").replace(/\\[['\"]?([^'\"\\]]*)['\"]?\\]/g, \"/$1\");\n        t[r] = s.split(\"/\")\n      }\n      return t\n    },\n    _getProperty: function(e, t) {\n      for (var n = this.object, i = 0, r = e.length - (t || 0); i < r && n; i++)\n        n = n[e[i]];\n      return n\n    },\n    _setProperty: function(e, t) {\n      var n = this._getProperty(e, 1);\n      n && (n[e[e.length - 1]] = t)\n    }\n  })\n    , Bn = {\n    request: function(e) {\n      var t = new c.XMLHttpRequest;\n      return t.open((e.method || \"get\").toUpperCase(), e.url, d.pick(e.async, !0)),\n      e.mimeType && t.overrideMimeType(e.mimeType),\n        t.onload = function() {\n          var n = t.status;\n          n === 0 || n === 200 ? e.onLoad && e.onLoad.call(t, t.responseText) : t.onerror()\n        }\n        ,\n        t.onerror = function() {\n          var n = t.status\n            , i = 'Could not load \"' + e.url + '\" (Status: ' + n + \")\";\n          if (e.onError)\n            e.onError(i, n);\n          else\n            throw new Error(i)\n        }\n        ,\n        t.send(null)\n    }\n  }\n    , Je = d.exports.CanvasProvider = {\n    canvases: [],\n    getCanvas: function(e, t, n) {\n      if (!h)\n        return null;\n      var i, r = !0;\n      typeof e == \"object\" && (t = e.height,\n        e = e.width),\n        this.canvases.length ? i = this.canvases.pop() : (i = p.createElement(\"canvas\"),\n          r = !1);\n      var s = i.getContext(\"2d\", n || {});\n      if (!s)\n        throw new Error(\"Canvas \" + i + \" is unable to provide a 2D context.\");\n      return i.width === e && i.height === t ? r && s.clearRect(0, 0, e + 1, t + 1) : (i.width = e,\n        i.height = t),\n        s.save(),\n        i\n    },\n    getContext: function(e, t, n) {\n      var i = this.getCanvas(e, t, n);\n      return i ? i.getContext(\"2d\", n || {}) : null\n    },\n    release: function(e) {\n      var t = e && e.canvas ? e.canvas : e;\n      t && t.getContext && (t.getContext(\"2d\").restore(),\n        this.canvases.push(t))\n    }\n  }\n    , nn = new function() {\n    var e = Math.min, t = Math.max, n = Math.abs, i, r, s, u, o, l, f, g, y, _, v;\n    function b(E, A, N) {\n      return .2989 * E + .587 * A + .114 * N\n    }\n    function T(E, A, N, D) {\n      var R = D - b(E, A, N);\n      y = E + R,\n        _ = A + R,\n        v = N + R;\n      var D = b(y, _, v)\n        , V = e(y, _, v)\n        , z = t(y, _, v);\n      if (V < 0) {\n        var G = D - V;\n        y = D + (y - D) * D / G,\n          _ = D + (_ - D) * D / G,\n          v = D + (v - D) * D / G\n      }\n      if (z > 255) {\n        var H = 255 - D\n          , K = z - D;\n        y = D + (y - D) * H / K,\n          _ = D + (_ - D) * H / K,\n          v = D + (v - D) * H / K\n      }\n    }\n    function x(E, A, N) {\n      return t(E, A, N) - e(E, A, N)\n    }\n    function S(E, A, N, L) {\n      var R = [E, A, N], D = t(E, A, N), V = e(E, A, N), z;\n      V = V === E ? 0 : V === A ? 1 : 2,\n        D = D === E ? 0 : D === A ? 1 : 2,\n        z = e(V, D) === 0 ? t(V, D) === 1 ? 2 : 1 : 0,\n        R[D] > R[V] ? (R[z] = (R[z] - R[V]) * L / (R[D] - R[V]),\n          R[D] = L) : R[z] = R[D] = 0,\n        R[V] = 0,\n        y = R[0],\n        _ = R[1],\n        v = R[2]\n    }\n    var I = {\n      multiply: function() {\n        y = o * i / 255,\n          _ = l * r / 255,\n          v = f * s / 255\n      },\n      screen: function() {\n        y = o + i - o * i / 255,\n          _ = l + r - l * r / 255,\n          v = f + s - f * s / 255\n      },\n      overlay: function() {\n        y = o < 128 ? 2 * o * i / 255 : 255 - 2 * (255 - o) * (255 - i) / 255,\n          _ = l < 128 ? 2 * l * r / 255 : 255 - 2 * (255 - l) * (255 - r) / 255,\n          v = f < 128 ? 2 * f * s / 255 : 255 - 2 * (255 - f) * (255 - s) / 255\n      },\n      \"soft-light\": function() {\n        var E = i * o / 255;\n        y = E + o * (255 - (255 - o) * (255 - i) / 255 - E) / 255,\n          E = r * l / 255,\n          _ = E + l * (255 - (255 - l) * (255 - r) / 255 - E) / 255,\n          E = s * f / 255,\n          v = E + f * (255 - (255 - f) * (255 - s) / 255 - E) / 255\n      },\n      \"hard-light\": function() {\n        y = i < 128 ? 2 * i * o / 255 : 255 - 2 * (255 - i) * (255 - o) / 255,\n          _ = r < 128 ? 2 * r * l / 255 : 255 - 2 * (255 - r) * (255 - l) / 255,\n          v = s < 128 ? 2 * s * f / 255 : 255 - 2 * (255 - s) * (255 - f) / 255\n      },\n      \"color-dodge\": function() {\n        y = o === 0 ? 0 : i === 255 ? 255 : e(255, 255 * o / (255 - i)),\n          _ = l === 0 ? 0 : r === 255 ? 255 : e(255, 255 * l / (255 - r)),\n          v = f === 0 ? 0 : s === 255 ? 255 : e(255, 255 * f / (255 - s))\n      },\n      \"color-burn\": function() {\n        y = o === 255 ? 255 : i === 0 ? 0 : t(0, 255 - (255 - o) * 255 / i),\n          _ = l === 255 ? 255 : r === 0 ? 0 : t(0, 255 - (255 - l) * 255 / r),\n          v = f === 255 ? 255 : s === 0 ? 0 : t(0, 255 - (255 - f) * 255 / s)\n      },\n      darken: function() {\n        y = o < i ? o : i,\n          _ = l < r ? l : r,\n          v = f < s ? f : s\n      },\n      lighten: function() {\n        y = o > i ? o : i,\n          _ = l > r ? l : r,\n          v = f > s ? f : s\n      },\n      difference: function() {\n        y = o - i,\n        y < 0 && (y = -y),\n          _ = l - r,\n        _ < 0 && (_ = -_),\n          v = f - s,\n        v < 0 && (v = -v)\n      },\n      exclusion: function() {\n        y = o + i * (255 - o - o) / 255,\n          _ = l + r * (255 - l - l) / 255,\n          v = f + s * (255 - f - f) / 255\n      },\n      hue: function() {\n        S(i, r, s, x(o, l, f)),\n          T(y, _, v, b(o, l, f))\n      },\n      saturation: function() {\n        S(o, l, f, x(i, r, s)),\n          T(y, _, v, b(o, l, f))\n      },\n      luminosity: function() {\n        T(o, l, f, b(i, r, s))\n      },\n      color: function() {\n        T(i, r, s, b(o, l, f))\n      },\n      add: function() {\n        y = e(o + i, 255),\n          _ = e(l + r, 255),\n          v = e(f + s, 255)\n      },\n      subtract: function() {\n        y = t(o - i, 0),\n          _ = t(l - r, 0),\n          v = t(f - s, 0)\n      },\n      average: function() {\n        y = (o + i) / 2,\n          _ = (l + r) / 2,\n          v = (f + s) / 2\n      },\n      negation: function() {\n        y = 255 - n(255 - i - o),\n          _ = 255 - n(255 - r - l),\n          v = 255 - n(255 - s - f)\n      }\n    }\n      , m = this.nativeModes = d.each([\"source-over\", \"source-in\", \"source-out\", \"source-atop\", \"destination-over\", \"destination-in\", \"destination-out\", \"destination-atop\", \"lighter\", \"darker\", \"copy\", \"xor\"], function(E) {\n      this[E] = !0\n    }, {})\n      , w = Je.getContext(1, 1, {\n      willReadFrequently: !0\n    });\n    w && (d.each(I, function(E, A) {\n      var N = A === \"darken\"\n        , L = !1;\n      w.save();\n      try {\n        w.fillStyle = N ? \"#300\" : \"#a00\",\n          w.fillRect(0, 0, 1, 1),\n          w.globalCompositeOperation = A,\n        w.globalCompositeOperation === A && (w.fillStyle = N ? \"#a00\" : \"#300\",\n          w.fillRect(0, 0, 1, 1),\n          L = w.getImageData(0, 0, 1, 1).data[0] !== N ? 170 : 51)\n      } catch {}\n      w.restore(),\n        m[A] = L\n    }),\n      Je.release(w)),\n      this.process = function(E, A, N, L, R) {\n        var D = A.canvas\n          , V = E === \"normal\";\n        if (V || m[E])\n          N.save(),\n            N.setTransform(1, 0, 0, 1, 0, 0),\n            N.globalAlpha = L,\n          V || (N.globalCompositeOperation = E),\n            N.drawImage(D, R.x, R.y),\n            N.restore();\n        else {\n          var z = I[E];\n          if (!z)\n            return;\n          for (var G = N.getImageData(R.x, R.y, D.width, D.height), H = G.data, K = A.getImageData(0, 0, D.width, D.height).data, $ = 0, W = H.length; $ < W; $ += 4) {\n            i = K[$],\n              o = H[$],\n              r = K[$ + 1],\n              l = H[$ + 1],\n              s = K[$ + 2],\n              f = H[$ + 2],\n              u = K[$ + 3],\n              g = H[$ + 3],\n              z();\n            var te = u * L / 255\n              , se = 1 - te;\n            H[$] = te * y + se * o,\n              H[$ + 1] = te * _ + se * l,\n              H[$ + 2] = te * v + se * f,\n              H[$ + 3] = u * L + se * g\n          }\n          N.putImageData(G, R.x, R.y)\n        }\n      }\n  }\n    , Qe = new function() {\n    var e = \"http://www.w3.org/2000/svg\"\n      , t = \"http://www.w3.org/2000/xmlns\"\n      , n = \"http://www.w3.org/1999/xlink\"\n      , i = {\n      href: n,\n      xlink: t,\n      xmlns: t + \"/\",\n      \"xmlns:xlink\": t + \"/\"\n    };\n    function r(o, l, f) {\n      return u(p.createElementNS(e, o), l, f)\n    }\n    function s(o, l) {\n      var f = i[l]\n        , g = f ? o.getAttributeNS(f, l) : o.getAttribute(l);\n      return g === \"null\" ? null : g\n    }\n    function u(o, l, f) {\n      for (var g in l) {\n        var y = l[g]\n          , _ = i[g];\n        typeof y == \"number\" && f && (y = f.number(y)),\n          _ ? o.setAttributeNS(_, g, y) : o.setAttribute(g, y)\n      }\n      return o\n    }\n    return {\n      svg: e,\n      xmlns: t,\n      xlink: n,\n      create: r,\n      get: s,\n      set: u\n    }\n  }\n    , En = d.each({\n    fillColor: [\"fill\", \"color\"],\n    fillRule: [\"fill-rule\", \"string\"],\n    strokeColor: [\"stroke\", \"color\"],\n    strokeWidth: [\"stroke-width\", \"number\"],\n    strokeCap: [\"stroke-linecap\", \"string\"],\n    strokeJoin: [\"stroke-linejoin\", \"string\"],\n    strokeScaling: [\"vector-effect\", \"lookup\", {\n      true: \"none\",\n      false: \"non-scaling-stroke\"\n    }, function(e, t) {\n      return !t && (e instanceof Ft || e instanceof je || e instanceof Gt)\n    }\n    ],\n    miterLimit: [\"stroke-miterlimit\", \"number\"],\n    dashArray: [\"stroke-dasharray\", \"array\"],\n    dashOffset: [\"stroke-dashoffset\", \"number\"],\n    fontFamily: [\"font-family\", \"string\"],\n    fontWeight: [\"font-weight\", \"string\"],\n    fontSize: [\"font-size\", \"number\"],\n    justification: [\"text-anchor\", \"lookup\", {\n      left: \"start\",\n      center: \"middle\",\n      right: \"end\"\n    }],\n    opacity: [\"opacity\", \"number\"],\n    blendMode: [\"mix-blend-mode\", \"style\"]\n  }, function(e, t) {\n    var n = d.capitalize(t)\n      , i = e[2];\n    this[t] = {\n      type: e[1],\n      property: t,\n      attribute: e[0],\n      toSVG: i,\n      fromSVG: i && d.each(i, function(r, s) {\n        this[r] = s\n      }, {}),\n      exportFilter: e[3],\n      get: \"get\" + n,\n      set: \"set\" + n\n    }\n  }, {});\n  new function() {\n    var e;\n    function t(I, m, w) {\n      var E = new d\n        , A = I.getTranslation();\n      if (m) {\n        var N;\n        I.isInvertible() ? (I = I._shiftless(),\n          N = I._inverseTransform(A),\n          A = null) : N = new C,\n          E[w ? \"cx\" : \"x\"] = N.x,\n          E[w ? \"cy\" : \"y\"] = N.y\n      }\n      if (!I.isIdentity()) {\n        var L = I.decompose();\n        if (L) {\n          var R = []\n            , D = L.rotation\n            , V = L.scaling\n            , z = L.skewing;\n          A && !A.isZero() && R.push(\"translate(\" + e.point(A) + \")\"),\n          D && R.push(\"rotate(\" + e.number(D) + \")\"),\n          (!O.isZero(V.x - 1) || !O.isZero(V.y - 1)) && R.push(\"scale(\" + e.point(V) + \")\"),\n          z.x && R.push(\"skewX(\" + e.number(z.x) + \")\"),\n          z.y && R.push(\"skewY(\" + e.number(z.y) + \")\"),\n            E.transform = R.join(\" \")\n        } else\n          E.transform = \"matrix(\" + I.getValues().join(\",\") + \")\"\n      }\n      return E\n    }\n    function n(I, m) {\n      for (var w = t(I._matrix), E = I._children, A = Qe.create(\"g\", w, e), N = 0, L = E.length; N < L; N++) {\n        var R = E[N]\n          , D = x(R, m);\n        if (D)\n          if (R.isClipMask()) {\n            var V = Qe.create(\"clipPath\");\n            V.appendChild(D),\n              b(R, V, \"clip\"),\n              Qe.set(A, {\n                \"clip-path\": \"url(#\" + V.id + \")\"\n              })\n          } else\n            A.appendChild(D)\n      }\n      return A\n    }\n    function i(I, m) {\n      var w = t(I._matrix, !0)\n        , E = I.getSize()\n        , A = I.getImage();\n      return w.x -= E.width / 2,\n        w.y -= E.height / 2,\n        w.width = E.width,\n        w.height = E.height,\n        w.href = m.embedImages == !1 && A && A.src || I.toDataURL(),\n        Qe.create(\"image\", w, e)\n    }\n    function r(I, m) {\n      var w = m.matchShapes;\n      if (w) {\n        var E = I.toShape(!1);\n        if (E)\n          return s(E, m)\n      }\n      var A = I._segments, N = A.length, L, R = t(I._matrix);\n      if (w && N >= 2 && !I.hasHandles())\n        if (N > 2) {\n          L = I._closed ? \"polygon\" : \"polyline\";\n          for (var D = [], V = 0; V < N; V++)\n            D.push(e.point(A[V]._point));\n          R.points = D.join(\" \")\n        } else {\n          L = \"line\";\n          var z = A[0]._point\n            , G = A[1]._point;\n          R.set({\n            x1: z.x,\n            y1: z.y,\n            x2: G.x,\n            y2: G.y\n          })\n        }\n      else\n        L = \"path\",\n          R.d = I.getPathData(null, m.precision);\n      return Qe.create(L, R, e)\n    }\n    function s(I) {\n      var m = I._type\n        , w = I._radius\n        , E = t(I._matrix, !0, m !== \"rectangle\");\n      if (m === \"rectangle\") {\n        m = \"rect\";\n        var A = I._size\n          , N = A.width\n          , L = A.height;\n        E.x -= N / 2,\n          E.y -= L / 2,\n          E.width = N,\n          E.height = L,\n        w.isZero() && (w = null)\n      }\n      return w && (m === \"circle\" ? E.r = w : (E.rx = w.width,\n        E.ry = w.height)),\n        Qe.create(m, E, e)\n    }\n    function u(I, m) {\n      var w = t(I._matrix)\n        , E = I.getPathData(null, m.precision);\n      return E && (w.d = E),\n        Qe.create(\"path\", w, e)\n    }\n    function o(I, m) {\n      var w = t(I._matrix, !0)\n        , E = I._definition\n        , A = v(E, \"symbol\")\n        , N = E._item\n        , L = N.getStrokeBounds();\n      return A || (A = Qe.create(\"symbol\", {\n        viewBox: e.rectangle(L)\n      }),\n        A.appendChild(x(N, m)),\n        b(E, A, \"symbol\")),\n        w.href = \"#\" + A.id,\n        w.x += L.x,\n        w.y += L.y,\n        w.width = L.width,\n        w.height = L.height,\n        w.overflow = \"visible\",\n        Qe.create(\"use\", w, e)\n    }\n    function l(I) {\n      var m = v(I, \"color\");\n      if (!m) {\n        var w = I.getGradient(), E = w._radial, A = I.getOrigin(), N = I.getDestination(), L;\n        if (E) {\n          L = {\n            cx: A.x,\n            cy: A.y,\n            r: A.getDistance(N)\n          };\n          var R = I.getHighlight();\n          R && (L.fx = R.x,\n            L.fy = R.y)\n        } else\n          L = {\n            x1: A.x,\n            y1: A.y,\n            x2: N.x,\n            y2: N.y\n          };\n        L.gradientUnits = \"userSpaceOnUse\",\n          m = Qe.create((E ? \"radial\" : \"linear\") + \"Gradient\", L, e);\n        for (var D = w._stops, V = 0, z = D.length; V < z; V++) {\n          var G = D[V]\n            , H = G._color\n            , K = H.getAlpha()\n            , $ = G._offset;\n          L = {\n            offset: $ ?? V / (z - 1)\n          },\n          H && (L[\"stop-color\"] = H.toCSS(!0)),\n          K < 1 && (L[\"stop-opacity\"] = K),\n            m.appendChild(Qe.create(\"stop\", L, e))\n        }\n        b(I, m, \"color\")\n      }\n      return \"url(#\" + m.id + \")\"\n    }\n    function f(I) {\n      var m = Qe.create(\"text\", t(I._matrix, !0), e);\n      return m.textContent = I._content,\n        m\n    }\n    var g = {\n      Group: n,\n      Layer: n,\n      Raster: i,\n      Path: r,\n      Shape: s,\n      CompoundPath: u,\n      SymbolItem: o,\n      PointText: f\n    };\n    function y(I, m, w) {\n      var E = {}\n        , A = !w && I.getParent()\n        , N = [];\n      return I._name != null && (E.id = I._name),\n        d.each(En, function(L) {\n          var R = L.get\n            , D = L.type\n            , V = I[R]();\n          if (L.exportFilter ? L.exportFilter(I, V) : !A || !d.equals(A[R](), V)) {\n            if (D === \"color\" && V != null) {\n              var z = V.getAlpha();\n              z < 1 && (E[L.attribute + \"-opacity\"] = z)\n            }\n            D === \"style\" ? N.push(L.attribute + \": \" + V) : E[L.attribute] = V == null ? \"none\" : D === \"color\" ? V.gradient ? l(V, I) : V.toCSS(!0) : D === \"array\" ? V.join(\",\") : D === \"lookup\" ? L.toSVG[V] : V\n          }\n        }),\n      N.length && (E.style = N.join(\";\")),\n      E.opacity === 1 && delete E.opacity,\n      I._visible || (E.visibility = \"hidden\"),\n        Qe.set(m, E, e)\n    }\n    var _;\n    function v(I, m) {\n      return _ || (_ = {\n        ids: {},\n        svgs: {}\n      }),\n      I && _.svgs[m + \"-\" + (I._id || I.__id || (I.__id = B.get(\"svg\")))]\n    }\n    function b(I, m, w) {\n      _ || v();\n      var E = _.ids[w] = (_.ids[w] || 0) + 1;\n      m.id = w + \"-\" + E,\n        _.svgs[w + \"-\" + (I._id || I.__id)] = m\n    }\n    function T(I, m) {\n      var w = I\n        , E = null;\n      if (_) {\n        w = I.nodeName.toLowerCase() === \"svg\" && I;\n        for (var A in _.svgs)\n          E || (w || (w = Qe.create(\"svg\"),\n            w.appendChild(I)),\n            E = w.insertBefore(Qe.create(\"defs\"), w.firstChild)),\n            E.appendChild(_.svgs[A]);\n        _ = null\n      }\n      return m.asString ? new c.XMLSerializer().serializeToString(w) : w\n    }\n    function x(I, m, w) {\n      var E = g[I._class]\n        , A = E && E(I, m);\n      if (A) {\n        var N = m.onExport;\n        N && (A = N(I, A, m) || A);\n        var L = JSON.stringify(I._data);\n        L && L !== \"{}\" && L !== \"null\" && A.setAttribute(\"data-paper-data\", L)\n      }\n      return A && y(I, A, w)\n    }\n    function S(I) {\n      return I || (I = {}),\n        e = new k(I.precision),\n        I\n    }\n    oe.inject({\n      exportSVG: function(I) {\n        return I = S(I),\n          T(x(this, I, !0), I)\n      }\n    }),\n      ye.inject({\n        exportSVG: function(I) {\n          I = S(I);\n          var m = this._children\n            , w = this.getView()\n            , E = d.pick(I.bounds, \"view\")\n            , A = I.matrix || E === \"view\" && w._matrix\n            , N = A && le.read([A])\n            , L = E === \"view\" ? new Y([0, 0],w.getViewSize()) : E === \"content\" ? oe._getBounds(m, N, {\n            stroke: !0\n          }).rect : Y.read([E], 0, {\n            readNull: !0\n          })\n            , R = {\n            version: \"1.1\",\n            xmlns: Qe.svg,\n            \"xmlns:xlink\": Qe.xlink\n          };\n          L && (R.width = L.width,\n            R.height = L.height,\n          (L.x || L.x === 0 || L.y || L.y === 0) && (R.viewBox = e.rectangle(L)));\n          var D = Qe.create(\"svg\", R, e)\n            , V = D;\n          N && !N.isIdentity() && (V = D.appendChild(Qe.create(\"g\", t(N), e)));\n          for (var z = 0, G = m.length; z < G; z++)\n            V.appendChild(x(m[z], I, !0));\n          return T(D, I)\n        }\n      })\n  }\n    ,\n    new function() {\n      var e = {}, t;\n      function n(m, w, E, A, N, L) {\n        var R = Qe.get(m, w) || L\n          , D = R == null ? A ? null : E ? \"\" : 0 : E ? R : parseFloat(R);\n        return /%\\s*$/.test(R) ? D / 100 * (N ? 1 : t[/x|^width/.test(w) ? \"width\" : \"height\"]) : D\n      }\n      function i(m, w, E, A, N, L, R) {\n        return w = n(m, w || \"x\", !1, A, N, L),\n          E = n(m, E || \"y\", !1, A, N, R),\n          A && (w == null || E == null) ? null : new C(w,E)\n      }\n      function r(m, w, E, A, N) {\n        return w = n(m, w || \"width\", !1, A, N),\n          E = n(m, E || \"height\", !1, A, N),\n          A && (w == null || E == null) ? null : new J(w,E)\n      }\n      function s(m, w, E) {\n        return m === \"none\" ? null : w === \"number\" ? parseFloat(m) : w === \"array\" ? m ? m.split(/[\\s,]+/g).map(parseFloat) : [] : w === \"color\" ? x(m) || m : w === \"lookup\" ? E[m] : m\n      }\n      function u(m, w, E, A) {\n        var N = m.childNodes\n          , L = w === \"clippath\"\n          , R = w === \"defs\"\n          , D = new We\n          , V = D._project\n          , z = V._currentStyle\n          , G = [];\n        if (!L && !R && (D = T(D, m, A),\n          V._currentStyle = D._style.clone()),\n          A)\n          for (var H = m.querySelectorAll(\"defs\"), K = 0, $ = H.length; K < $; K++)\n            S(H[K], E, !1);\n        for (var K = 0, $ = N.length; K < $; K++) {\n          var W = N[K], te;\n          W.nodeType === 1 && !/^defs$/i.test(W.nodeName) && (te = S(W, E, !1)) && !(te instanceof dt) && G.push(te)\n        }\n        return D.addChildren(G),\n        L && (D = T(D.reduce(), m, A)),\n          V._currentStyle = z,\n        (L || R) && (D.remove(),\n          D = null),\n          D\n      }\n      function o(m, w) {\n        for (var E = m.getAttribute(\"points\").match(/[+-]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][+-]?\\d+)?/g), A = [], N = 0, L = E.length; N < L; N += 2)\n          A.push(new C(parseFloat(E[N]),parseFloat(E[N + 1])));\n        var R = new ke(A);\n        return w === \"polygon\" && R.closePath(),\n          R\n      }\n      function l(m) {\n        return Ft.create(m.getAttribute(\"d\"))\n      }\n      function f(m, w) {\n        var E = (n(m, \"href\", !0) || \"\").substring(1), A = w === \"radialgradient\", N;\n        if (E)\n          N = e[E].getGradient(),\n          N._radial ^ A && (N = N.clone(),\n            N._radial = A);\n        else {\n          for (var L = m.childNodes, R = [], D = 0, V = L.length; D < V; D++) {\n            var z = L[D];\n            z.nodeType === 1 && R.push(T(new en, z))\n          }\n          N = new xt(R,A)\n        }\n        var G, H, K, $ = n(m, \"gradientUnits\", !0) !== \"userSpaceOnUse\";\n        A ? (G = i(m, \"cx\", \"cy\", !1, $, \"50%\", \"50%\"),\n          H = G.add(n(m, \"r\", !1, !1, $, \"50%\"), 0),\n          K = i(m, \"fx\", \"fy\", !0, $)) : (G = i(m, \"x1\", \"y1\", !1, $, \"0%\", \"0%\"),\n          H = i(m, \"x2\", \"y2\", !1, $, \"100%\", \"0%\"));\n        var W = T(new Xe(N,G,H,K), m);\n        return W._scaleToBounds = $,\n          null\n      }\n      var g = {\n        \"#document\": function(m, w, E, A) {\n          for (var N = m.childNodes, L = 0, R = N.length; L < R; L++) {\n            var D = N[L];\n            if (D.nodeType === 1)\n              return S(D, E, A)\n          }\n        },\n        g: u,\n        svg: u,\n        clippath: u,\n        polygon: o,\n        polyline: o,\n        path: l,\n        lineargradient: f,\n        radialgradient: f,\n        image: function(m) {\n          var w = new Pt(n(m, \"href\", !0));\n          return w.on(\"load\", function() {\n            var E = r(m);\n            this.setSize(E);\n            var A = i(m).add(E.divide(2));\n            this._matrix.append(new le().translate(A))\n          }),\n            w\n        },\n        symbol: function(m, w, E, A) {\n          return new dt(u(m, w, E, A),!0)\n        },\n        defs: u,\n        use: function(m) {\n          var w = (n(m, \"href\", !0) || \"\").substring(1)\n            , E = e[w]\n            , A = i(m);\n          return E ? E instanceof dt ? E.place(A) : E.clone().translate(A) : null\n        },\n        circle: function(m) {\n          return new je.Circle(i(m, \"cx\", \"cy\"),n(m, \"r\"))\n        },\n        ellipse: function(m) {\n          return new je.Ellipse({\n            center: i(m, \"cx\", \"cy\"),\n            radius: r(m, \"rx\", \"ry\")\n          })\n        },\n        rect: function(m) {\n          return new je.Rectangle(new Y(i(m),r(m)),r(m, \"rx\", \"ry\"))\n        },\n        line: function(m) {\n          return new ke.Line(i(m, \"x1\", \"y1\"),i(m, \"x2\", \"y2\"))\n        },\n        text: function(m) {\n          var w = new Mt(i(m).add(i(m, \"dx\", \"dy\")));\n          return w.setContent(m.textContent.trim() || \"\"),\n            w\n        },\n        switch: u\n      };\n      function y(m, w, E, A) {\n        if (m.transform) {\n          for (var N = (A.getAttribute(E) || \"\").split(/\\)\\s*/g), L = new le, R = 0, D = N.length; R < D; R++) {\n            var V = N[R];\n            if (!V)\n              break;\n            for (var z = V.split(/\\(\\s*/), G = z[0], H = z[1].split(/[\\s,]+/g), K = 0, $ = H.length; K < $; K++)\n              H[K] = parseFloat(H[K]);\n            switch (G) {\n              case \"matrix\":\n                L.append(new le(H[0],H[1],H[2],H[3],H[4],H[5]));\n                break;\n              case \"rotate\":\n                L.rotate(H[0], H[1] || 0, H[2] || 0);\n                break;\n              case \"translate\":\n                L.translate(H[0], H[1] || 0);\n                break;\n              case \"scale\":\n                L.scale(H);\n                break;\n              case \"skewX\":\n                L.skew(H[0], 0);\n                break;\n              case \"skewY\":\n                L.skew(0, H[0]);\n                break\n            }\n          }\n          m.transform(L)\n        }\n      }\n      function _(m, w, E) {\n        var A = E === \"fill-opacity\" ? \"getFillColor\" : \"getStrokeColor\"\n          , N = m[A] && m[A]();\n        N && N.setAlpha(parseFloat(w))\n      }\n      var v = d.set(d.each(En, function(m) {\n        this[m.attribute] = function(w, E) {\n          if (w[m.set] && (w[m.set](s(E, m.type, m.fromSVG)),\n          m.type === \"color\")) {\n            var A = w[m.get]();\n            if (A && A._scaleToBounds) {\n              var N = w.getBounds();\n              A.transform(new le().translate(N.getPoint()).scale(N.getSize()))\n            }\n          }\n        }\n      }, {}), {\n        id: function(m, w) {\n          e[w] = m,\n          m.setName && m.setName(w)\n        },\n        \"clip-path\": function(m, w) {\n          var E = x(w);\n          if (E)\n            if (E = E.clone(),\n              E.setClipMask(!0),\n            m instanceof We)\n              m.insertChild(0, E);\n            else\n              return new We(E,m)\n        },\n        gradientTransform: y,\n        transform: y,\n        \"fill-opacity\": _,\n        \"stroke-opacity\": _,\n        visibility: function(m, w) {\n          m.setVisible && m.setVisible(w === \"visible\")\n        },\n        display: function(m, w) {\n          m.setVisible && m.setVisible(w !== null)\n        },\n        \"stop-color\": function(m, w) {\n          m.setColor && m.setColor(w)\n        },\n        \"stop-opacity\": function(m, w) {\n          m._color && m._color.setAlpha(parseFloat(w))\n        },\n        offset: function(m, w) {\n          if (m.setOffset) {\n            var E = w.match(/(.*)%$/);\n            m.setOffset(E ? E[1] / 100 : parseFloat(w))\n          }\n        },\n        viewBox: function(m, w, E, A, N) {\n          var L = new Y(s(w, \"array\")), R = r(A, null, null, !0), D, V;\n          if (m instanceof We) {\n            var z = R ? R.divide(L.getSize()) : 1\n              , V = new le().scale(z).translate(L.getPoint().negate());\n            D = m\n          } else\n            m instanceof dt && (R && L.setSize(R),\n              D = m._item);\n          if (D) {\n            if (b(A, \"overflow\", N) !== \"visible\") {\n              var G = new je.Rectangle(L);\n              G.setClipMask(!0),\n                D.addChild(G)\n            }\n            V && D.transform(V)\n          }\n        }\n      });\n      function b(m, w, E) {\n        var A = m.attributes[w]\n          , N = A && A.value;\n        if (!N && m.style) {\n          var L = d.camelize(w);\n          N = m.style[L],\n          !N && E.node[L] !== E.parent[L] && (N = E.node[L])\n        }\n        return N ? N === \"none\" ? null : N : a\n      }\n      function T(m, w, E) {\n        var A = w.parentNode\n          , N = {\n          node: Ce.getStyles(w) || {},\n          parent: !E && !/^defs$/i.test(A.tagName) && Ce.getStyles(A) || {}\n        };\n        return d.each(v, function(L, R) {\n          var D = b(w, R, N);\n          m = D !== a && L(m, D, R, w, N) || m\n        }),\n          m\n      }\n      function x(m) {\n        var w = m && m.match(/\\((?:[\"'#]*)([^\"')]+)/)\n          , E = w && w[1]\n          , A = E && e[h ? E.replace(h.location.href.split(\"#\")[0] + \"#\", \"\") : E];\n        return A && A._scaleToBounds && (A = A.clone(),\n          A._scaleToBounds = !0),\n          A\n      }\n      function S(m, w, E) {\n        var A = m.nodeName.toLowerCase(), N = A !== \"#document\", L = p.body, R, D, V;\n        E && N && (t = ae.getView().getSize(),\n          t = r(m, null, null, !0) || t,\n          R = Qe.create(\"svg\", {\n            style: \"stroke-width: 1px; stroke-miterlimit: 10\"\n          }),\n          D = m.parentNode,\n          V = m.nextSibling,\n          R.appendChild(m),\n          L.appendChild(R));\n        var z = ae.settings\n          , G = z.applyMatrix\n          , H = z.insertItems;\n        z.applyMatrix = !1,\n          z.insertItems = !1;\n        var K = g[A]\n          , $ = K && K(m, A, w, E) || null;\n        if (z.insertItems = H,\n          z.applyMatrix = G,\n          $) {\n          N && !($ instanceof We) && ($ = T($, m, E));\n          var W = w.onImport\n            , te = N && m.getAttribute(\"data-paper-data\");\n          W && ($ = W(m, $, w) || $),\n          w.expandShapes && $ instanceof je && ($.remove(),\n            $ = $.toPath()),\n          te && ($._data = JSON.parse(te))\n        }\n        return R && (L.removeChild(R),\n        D && (V ? D.insertBefore(m, V) : D.appendChild(m))),\n        E && (e = {},\n        $ && d.pick(w.applyMatrix, G) && $.matrix.apply(!0, !0)),\n          $\n      }\n      function I(m, w, E) {\n        if (!m)\n          return null;\n        w = typeof w == \"function\" ? {\n          onLoad: w\n        } : w || {};\n        var A = ae\n          , N = null;\n        function L(z) {\n          try {\n            var G = typeof z == \"object\" ? z : new c.DOMParser().parseFromString(z.trim(), \"image/svg+xml\");\n            if (!G.nodeName)\n              throw G = null,\n                new Error(\"Unsupported SVG source: \" + m);\n            ae = A,\n              N = S(G, w, !0),\n            (!w || w.insert !== !1) && E._insertItem(a, N);\n            var H = w.onLoad;\n            H && H(N, z)\n          } catch (K) {\n            R(K)\n          }\n        }\n        function R(z, G) {\n          var H = w.onError;\n          if (H)\n            H(z, G);\n          else\n            throw new Error(z)\n        }\n        if (typeof m == \"string\" && !/^[\\s\\S]*</.test(m)) {\n          var D = p.getElementById(m);\n          D ? L(D) : Bn.request({\n            url: m,\n            async: !0,\n            onLoad: L,\n            onError: R\n          })\n        } else if (typeof File < \"u\" && m instanceof File) {\n          var V = new FileReader;\n          return V.onload = function() {\n            L(V.result)\n          }\n            ,\n            V.onerror = function() {\n              R(V.error)\n            }\n            ,\n            V.readAsText(m)\n        } else\n          L(m);\n        return N\n      }\n      oe.inject({\n        importSVG: function(m, w) {\n          return I(m, w, this)\n        }\n      }),\n        ye.inject({\n          importSVG: function(m, w) {\n            return this.activate(),\n              I(m, w, this)\n          }\n        })\n    }\n  ;\n  var ae = new (F.inject(d.exports, {\n    Base: d,\n    Numerical: O,\n    Key: cn,\n    DomEvent: tt,\n    DomElement: Ce,\n    document: p,\n    window: h,\n    Symbol: dt,\n    PlacedSymbol: ft\n  }));\n  return ae\n}\n  .call(void 0, typeof self == \"object\" ? self : null)\n  , ce = Sa;\nfunction _n(c, a, h, p) {\n  function d(M) {\n    return M instanceof h ? M : new h(function(F) {\n        F(M)\n      }\n    )\n  }\n  return new (h || (h = Promise))(function(M, F) {\n      function Z(O) {\n        try {\n          k(p.next(O))\n        } catch (B) {\n          F(B)\n        }\n      }\n      function q(O) {\n        try {\n          k(p.throw(O))\n        } catch (B) {\n          F(B)\n        }\n      }\n      function k(O) {\n        O.done ? M(O.value) : d(O.value).then(Z, q)\n      }\n      k((p = p.apply(c, a || [])).next())\n    }\n  )\n}\nvar ri = typeof globalThis < \"u\" ? globalThis : typeof window < \"u\" ? window : typeof global < \"u\" ? global : typeof self < \"u\" ? self : {}\n  , Ir = {\n  exports: {}\n};\n(function(c) {\n    var a = Object.prototype.hasOwnProperty\n      , h = \"~\";\n    function p() {}\n    Object.create && (p.prototype = Object.create(null),\n    new p().__proto__ || (h = !1));\n    function d(q, k, O) {\n      this.fn = q,\n        this.context = k,\n        this.once = O || !1\n    }\n    function M(q, k, O, B, C) {\n      if (typeof O != \"function\")\n        throw new TypeError(\"The listener must be a function\");\n      var Q = new d(O,B || q,C)\n        , J = h ? h + k : k;\n      return q._events[J] ? q._events[J].fn ? q._events[J] = [q._events[J], Q] : q._events[J].push(Q) : (q._events[J] = Q,\n        q._eventsCount++),\n        q\n    }\n    function F(q, k) {\n      --q._eventsCount === 0 ? q._events = new p : delete q._events[k]\n    }\n    function Z() {\n      this._events = new p,\n        this._eventsCount = 0\n    }\n    Z.prototype.eventNames = function() {\n      var k = [], O, B;\n      if (this._eventsCount === 0)\n        return k;\n      for (B in O = this._events)\n        a.call(O, B) && k.push(h ? B.slice(1) : B);\n      return Object.getOwnPropertySymbols ? k.concat(Object.getOwnPropertySymbols(O)) : k\n    }\n      ,\n      Z.prototype.listeners = function(k) {\n        var O = h ? h + k : k\n          , B = this._events[O];\n        if (!B)\n          return [];\n        if (B.fn)\n          return [B.fn];\n        for (var C = 0, Q = B.length, J = new Array(Q); C < Q; C++)\n          J[C] = B[C].fn;\n        return J\n      }\n      ,\n      Z.prototype.listenerCount = function(k) {\n        var O = h ? h + k : k\n          , B = this._events[O];\n        return B ? B.fn ? 1 : B.length : 0\n      }\n      ,\n      Z.prototype.emit = function(k, O, B, C, Q, J) {\n        var ne = h ? h + k : k;\n        if (!this._events[ne])\n          return !1;\n        var Y = this._events[ne], Me = arguments.length, le, Se;\n        if (Y.fn) {\n          switch (Y.once && this.removeListener(k, Y.fn, void 0, !0),\n            Me) {\n            case 1:\n              return Y.fn.call(Y.context),\n                !0;\n            case 2:\n              return Y.fn.call(Y.context, O),\n                !0;\n            case 3:\n              return Y.fn.call(Y.context, O, B),\n                !0;\n            case 4:\n              return Y.fn.call(Y.context, O, B, C),\n                !0;\n            case 5:\n              return Y.fn.call(Y.context, O, B, C, Q),\n                !0;\n            case 6:\n              return Y.fn.call(Y.context, O, B, C, Q, J),\n                !0\n          }\n          for (Se = 1,\n                 le = new Array(Me - 1); Se < Me; Se++)\n            le[Se - 1] = arguments[Se];\n          Y.fn.apply(Y.context, le)\n        } else {\n          var ye = Y.length, oe;\n          for (Se = 0; Se < ye; Se++)\n            switch (Y[Se].once && this.removeListener(k, Y[Se].fn, void 0, !0),\n              Me) {\n              case 1:\n                Y[Se].fn.call(Y[Se].context);\n                break;\n              case 2:\n                Y[Se].fn.call(Y[Se].context, O);\n                break;\n              case 3:\n                Y[Se].fn.call(Y[Se].context, O, B);\n                break;\n              case 4:\n                Y[Se].fn.call(Y[Se].context, O, B, C);\n                break;\n              default:\n                if (!le)\n                  for (oe = 1,\n                         le = new Array(Me - 1); oe < Me; oe++)\n                    le[oe - 1] = arguments[oe];\n                Y[Se].fn.apply(Y[Se].context, le)\n            }\n        }\n        return !0\n      }\n      ,\n      Z.prototype.on = function(k, O, B) {\n        return M(this, k, O, B, !1)\n      }\n      ,\n      Z.prototype.once = function(k, O, B) {\n        return M(this, k, O, B, !0)\n      }\n      ,\n      Z.prototype.removeListener = function(k, O, B, C) {\n        var Q = h ? h + k : k;\n        if (!this._events[Q])\n          return this;\n        if (!O)\n          return F(this, Q),\n            this;\n        var J = this._events[Q];\n        if (J.fn)\n          J.fn === O && (!C || J.once) && (!B || J.context === B) && F(this, Q);\n        else {\n          for (var ne = 0, Y = [], Me = J.length; ne < Me; ne++)\n            (J[ne].fn !== O || C && !J[ne].once || B && J[ne].context !== B) && Y.push(J[ne]);\n          Y.length ? this._events[Q] = Y.length === 1 ? Y[0] : Y : F(this, Q)\n        }\n        return this\n      }\n      ,\n      Z.prototype.removeAllListeners = function(k) {\n        var O;\n        return k ? (O = h ? h + k : k,\n        this._events[O] && F(this, O)) : (this._events = new p,\n          this._eventsCount = 0),\n          this\n      }\n      ,\n      Z.prototype.off = Z.prototype.removeListener,\n      Z.prototype.addListener = Z.prototype.on,\n      Z.prefixed = h,\n      Z.EventEmitter = Z,\n      c.exports = Z\n  }\n)(Ir);\nvar Ea = Ir.exports\n  , Cr = function(c, a) {\n  return (Cr = Object.setPrototypeOf || {\n        __proto__: []\n      }instanceof Array && function(h, p) {\n        h.__proto__ = p\n      }\n      || function(h, p) {\n        for (var d in p)\n          Object.prototype.hasOwnProperty.call(p, d) && (h[d] = p[d])\n      }\n  )(c, a)\n};\nfunction He(c, a) {\n  if (typeof a != \"function\" && a !== null)\n    throw new TypeError(\"Class extends value \" + String(a) + \" is not a constructor or null\");\n  function h() {\n    this.constructor = c\n  }\n  Cr(c, a),\n    c.prototype = a === null ? Object.create(a) : (h.prototype = a.prototype,\n      new h)\n}\nvar rt, ee = function() {\n  return (ee = Object.assign || function(c) {\n      for (var a, h = 1, p = arguments.length; h < p; h++)\n        for (var d in a = arguments[h])\n          Object.prototype.hasOwnProperty.call(a, d) && (c[d] = a[d]);\n      return c\n    }\n  ).apply(this, arguments)\n};\nfunction Bi(c, a, h, p) {\n  return new (h = h || Promise)(function(d, M) {\n      function F(k) {\n        try {\n          q(p.next(k))\n        } catch (O) {\n          M(O)\n        }\n      }\n      function Z(k) {\n        try {\n          q(p.throw(k))\n        } catch (O) {\n          M(O)\n        }\n      }\n      function q(k) {\n        var O;\n        k.done ? d(k.value) : ((O = k.value)instanceof h ? O : new h(function(B) {\n            B(O)\n          }\n        )).then(F, Z)\n      }\n      q((p = p.apply(c, a || [])).next())\n    }\n  )\n}\nfunction Ui(c, a) {\n  var h, p, d, M = {\n    label: 0,\n    sent: function() {\n      if (1 & d[0])\n        throw d[1];\n      return d[1]\n    },\n    trys: [],\n    ops: []\n  }, F = {\n    next: Z(0),\n    throw: Z(1),\n    return: Z(2)\n  };\n  return typeof Symbol == \"function\" && (F[Symbol.iterator] = function() {\n      return this\n    }\n  ),\n    F;\n  function Z(q) {\n    return function(k) {\n      return function(O) {\n        if (h)\n          throw new TypeError(\"Generator is already executing.\");\n        for (; M; )\n          try {\n            if (h = 1,\n            p && (d = 2 & O[0] ? p.return : O[0] ? p.throw || ((d = p.return) && d.call(p),\n              0) : p.next) && !(d = d.call(p, O[1])).done)\n              return d;\n            switch (p = 0,\n              (O = d ? [2 & O[0], d.value] : O)[0]) {\n              case 0:\n              case 1:\n                d = O;\n                break;\n              case 4:\n                return M.label++,\n                  {\n                    value: O[1],\n                    done: !1\n                  };\n              case 5:\n                M.label++,\n                  p = O[1],\n                  O = [0];\n                continue;\n              case 7:\n                O = M.ops.pop(),\n                  M.trys.pop();\n                continue;\n              default:\n                if (!(d = 0 < (d = M.trys).length && d[d.length - 1]) && (O[0] === 6 || O[0] === 2)) {\n                  M = 0;\n                  continue\n                }\n                if (O[0] === 3 && (!d || O[1] > d[0] && O[1] < d[3])) {\n                  M.label = O[1];\n                  break\n                }\n                if (O[0] === 6 && M.label < d[1]) {\n                  M.label = d[1],\n                    d = O;\n                  break\n                }\n                if (d && M.label < d[2]) {\n                  M.label = d[2],\n                    M.ops.push(O);\n                  break\n                }\n                d[2] && M.ops.pop(),\n                  M.trys.pop();\n                continue\n            }\n            O = a.call(c, M)\n          } catch (B) {\n            O = [6, B],\n              p = 0\n          } finally {\n            h = d = 0\n          }\n        if (5 & O[0])\n          throw O[1];\n        return {\n          value: O[0] ? O[1] : void 0,\n          done: !0\n        }\n      }([q, k])\n    }\n  }\n}\nfunction lt(c) {\n  var a = typeof Symbol == \"function\" && Symbol.iterator\n    , h = a && c[a]\n    , p = 0;\n  if (h)\n    return h.call(c);\n  if (c && typeof c.length == \"number\")\n    return {\n      next: function() {\n        return {\n          value: (c = c && p >= c.length ? void 0 : c) && c[p++],\n          done: !c\n        }\n      }\n    };\n  throw new TypeError(a ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\")\n}\nfunction It(c, a) {\n  var h = typeof Symbol == \"function\" && c[Symbol.iterator];\n  if (!h)\n    return c;\n  var p, d, M = h.call(c), F = [];\n  try {\n    for (; (a === void 0 || 0 < a--) && !(p = M.next()).done; )\n      F.push(p.value)\n  } catch (Z) {\n    d = {\n      error: Z\n    }\n  } finally {\n    try {\n      p && !p.done && (h = M.return) && h.call(M)\n    } finally {\n      if (d)\n        throw d.error\n    }\n  }\n  return F\n}\nfunction Tt(c, a) {\n  for (var h = 0, p = a.length, d = c.length; h < p; h++,\n    d++)\n    c[d] = a[h];\n  return c\n}\n(function(c) {\n    c.assertNever = function(a) {\n      throw new Error\n    }\n      ,\n      c.arrayToEnum = function(a) {\n        var h, p, d = {};\n        try {\n          for (var M = lt(a), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            d[Z] = Z\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      }\n      ,\n      c.getValidEnumValues = function(a) {\n        var h, p, d = c.objectKeys(a).filter(function(k) {\n          return typeof a[a[k]] != \"number\"\n        }), M = {};\n        try {\n          for (var F = lt(d), Z = F.next(); !Z.done; Z = F.next()) {\n            var q = Z.value;\n            M[q] = a[q]\n          }\n        } catch (k) {\n          h = {\n            error: k\n          }\n        } finally {\n          try {\n            Z && !Z.done && (p = F.return) && p.call(F)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return c.objectValues(M)\n      }\n      ,\n      c.objectValues = function(a) {\n        return c.objectKeys(a).map(function(h) {\n          return a[h]\n        })\n      }\n      ,\n      c.objectKeys = typeof Object.keys == \"function\" ? function(a) {\n          return Object.keys(a)\n        }\n        : function(a) {\n          var h, p = [];\n          for (h in a)\n            Object.prototype.hasOwnProperty.call(a, h) && p.push(h);\n          return p\n        }\n      ,\n      c.find = function(a, h) {\n        var p, d;\n        try {\n          for (var M = lt(a), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            if (h(Z))\n              return Z\n          }\n        } catch (q) {\n          p = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (d = M.return) && d.call(M)\n          } finally {\n            if (p)\n              throw p.error\n          }\n        }\n      }\n      ,\n      c.isInteger = typeof Number.isInteger == \"function\" ? function(a) {\n          return Number.isInteger(a)\n        }\n        : function(a) {\n          return typeof a == \"number\" && isFinite(a) && Math.floor(a) === a\n        }\n  }\n)(rt = rt || {});\nvar et, be = rt.arrayToEnum([\"invalid_type\", \"custom\", \"invalid_union\", \"invalid_enum_value\", \"unrecognized_keys\", \"invalid_arguments\", \"invalid_return_type\", \"invalid_date\", \"invalid_string\", \"too_small\", \"too_big\", \"invalid_intersection_types\", \"not_multiple_of\"]), Ta = function(c) {\n  return JSON.stringify(c, null, 2).replace(/\"([^\"]+)\":/g, \"$1:\")\n}, On = function(c) {\n  function a(h) {\n    var p = this.constructor\n      , d = c.call(this) || this;\n    return d.issues = [],\n      d.format = function() {\n        var M = {\n          _errors: []\n        }\n          , F = function(Z) {\n          var q, k;\n          try {\n            for (var O = lt(Z.issues), B = O.next(); !B.done; B = O.next()) {\n              var C = B.value;\n              if (C.code === \"invalid_union\")\n                C.unionErrors.map(F);\n              else if (C.code === \"invalid_return_type\")\n                F(C.returnTypeError);\n              else if (C.code === \"invalid_arguments\")\n                F(C.argumentsError);\n              else if (C.path.length === 0)\n                M._errors.push(C.message);\n              else\n                for (var Q = M, J = 0; J < C.path.length; ) {\n                  var ne, Y = C.path[J];\n                  J === C.path.length - 1 ? (Q[Y] = Q[Y] || {\n                    _errors: []\n                  },\n                    Q[Y]._errors.push(C.message)) : typeof Y == \"string\" ? Q[Y] = Q[Y] || {\n                    _errors: []\n                  } : typeof Y == \"number\" && ((ne = [])._errors = [],\n                    Q[Y] = Q[Y] || ne),\n                    Q = Q[Y],\n                    J++\n                }\n            }\n          } catch (Me) {\n            q = {\n              error: Me\n            }\n          } finally {\n            try {\n              B && !B.done && (k = O.return) && k.call(O)\n            } finally {\n              if (q)\n                throw q.error\n            }\n          }\n        };\n        return F(d),\n          M\n      }\n      ,\n      d.addIssue = function(M) {\n        d.issues = Tt(Tt([], It(d.issues), !1), [M])\n      }\n      ,\n      d.addIssues = function(M) {\n        M === void 0 && (M = []),\n          d.issues = Tt(Tt([], It(d.issues), !1), It(M))\n      }\n      ,\n      d.flatten = function(M) {\n        var F, Z;\n        M === void 0 && (M = function(Q) {\n            return Q.message\n          }\n        );\n        var q = {}\n          , k = [];\n        try {\n          for (var O = lt(d.issues), B = O.next(); !B.done; B = O.next()) {\n            var C = B.value;\n            0 < C.path.length ? (q[C.path[0]] = q[C.path[0]] || [],\n              q[C.path[0]].push(M(C))) : k.push(M(C))\n          }\n        } catch (Q) {\n          F = {\n            error: Q\n          }\n        } finally {\n          try {\n            B && !B.done && (Z = O.return) && Z.call(O)\n          } finally {\n            if (F)\n              throw F.error\n          }\n        }\n        return {\n          formErrors: k,\n          fieldErrors: q\n        }\n      }\n      ,\n      p = p.prototype,\n      Object.setPrototypeOf ? Object.setPrototypeOf(d, p) : d.__proto__ = p,\n      d.name = \"ZodError\",\n      d.issues = h,\n      d\n  }\n  return He(a, c),\n    Object.defineProperty(a.prototype, \"errors\", {\n      get: function() {\n        return this.issues\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype.toString = function() {\n      return this.message\n    }\n    ,\n    Object.defineProperty(a.prototype, \"message\", {\n      get: function() {\n        return JSON.stringify(this.issues, null, 2)\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"isEmpty\", {\n      get: function() {\n        return this.issues.length === 0\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"formErrors\", {\n      get: function() {\n        return this.flatten()\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h) {\n      return new a(h)\n    }\n    ,\n    a\n}(Error), ji = function(c, a) {\n  var h;\n  switch (c.code) {\n    case be.invalid_type:\n      h = c.received === \"undefined\" ? \"Required\" : \"Expected \" + c.expected + \", received \" + c.received;\n      break;\n    case be.unrecognized_keys:\n      h = \"Unrecognized key(s) in object: \" + c.keys.map(function(p) {\n        return \"'\" + p + \"'\"\n      }).join(\", \");\n      break;\n    case be.invalid_union:\n      h = \"Invalid input\";\n      break;\n    case be.invalid_enum_value:\n      h = \"Invalid enum value. Expected \" + c.options.map(function(p) {\n        return typeof p == \"string\" ? \"'\" + p + \"'\" : p\n      }).join(\" | \") + \", received \" + (typeof a.data == \"string\" ? \"'\" + a.data + \"'\" : a.data);\n      break;\n    case be.invalid_arguments:\n      h = \"Invalid function arguments\";\n      break;\n    case be.invalid_return_type:\n      h = \"Invalid function return type\";\n      break;\n    case be.invalid_date:\n      h = \"Invalid date\";\n      break;\n    case be.invalid_string:\n      h = c.validation !== \"regex\" ? \"Invalid \" + c.validation : \"Invalid\";\n      break;\n    case be.too_small:\n      h = c.type === \"array\" ? \"Should have \" + (c.inclusive ? \"at least\" : \"more than\") + \" \" + c.minimum + \" items\" : c.type === \"string\" ? \"Should be \" + (c.inclusive ? \"at least\" : \"over\") + \" \" + c.minimum + \" characters\" : c.type === \"number\" ? \"Value should be greater than \" + (c.inclusive ? \"or equal to \" : \"\") + c.minimum : \"Invalid input\";\n      break;\n    case be.too_big:\n      h = c.type === \"array\" ? \"Should have \" + (c.inclusive ? \"at most\" : \"less than\") + \" \" + c.maximum + \" items\" : c.type === \"string\" ? \"Should be \" + (c.inclusive ? \"at most\" : \"under\") + \" \" + c.maximum + \" characters long\" : c.type === \"number\" ? \"Value should be less than \" + (c.inclusive ? \"or equal to \" : \"\") + c.maximum : \"Invalid input\";\n      break;\n    case be.custom:\n      h = \"Invalid input\";\n      break;\n    case be.invalid_intersection_types:\n      h = \"Intersection results could not be merged\";\n      break;\n    case be.not_multiple_of:\n      h = \"Should be multiple of \" + c.multipleOf;\n      break;\n    default:\n      h = a.defaultError,\n        rt.assertNever(c)\n  }\n  return {\n    message: h\n  }\n}, qi = ji, Ia = function(c) {\n  qi = c\n}, we = rt.arrayToEnum([\"string\", \"nan\", \"number\", \"integer\", \"float\", \"boolean\", \"date\", \"bigint\", \"symbol\", \"function\", \"undefined\", \"null\", \"array\", \"object\", \"unknown\", \"promise\", \"void\", \"never\", \"map\", \"set\"]), wt = function(c) {\n  switch (typeof c) {\n    case \"undefined\":\n      return we.undefined;\n    case \"string\":\n      return we.string;\n    case \"number\":\n      return isNaN(c) ? we.nan : we.number;\n    case \"boolean\":\n      return we.boolean;\n    case \"function\":\n      return we.function;\n    case \"bigint\":\n      return we.bigint;\n    case \"object\":\n      return Array.isArray(c) ? we.array : c === null ? we.null : c.then && typeof c.then == \"function\" && c.catch && typeof c.catch == \"function\" ? we.promise : c instanceof Map ? we.map : c instanceof Set ? we.set : c instanceof Date ? we.date : we.object;\n    default:\n      return we.unknown\n  }\n}, ui = function(d) {\n  var a, h, p = d.data, M = d.path, q = d.errorMaps, d = d.issueData, M = Tt(Tt([], It(M), !1), It(d.path || [])), F = ee(ee({}, d), {\n    path: M\n  }), Z = \"\", q = q.filter(function(B) {\n    return !!B\n  }).slice().reverse();\n  try {\n    for (var k = lt(q), O = k.next(); !O.done; O = k.next())\n      Z = (0,\n        O.value)(F, {\n        data: p,\n        defaultError: Z\n      }).message\n  } catch (B) {\n    a = {\n      error: B\n    }\n  } finally {\n    try {\n      O && !O.done && (h = k.return) && h.call(k)\n    } finally {\n      if (a)\n        throw a.error\n    }\n  }\n  return ee(ee({}, d), {\n    path: M,\n    message: d.message || Z\n  })\n}, Ca = null, Nn = function(c) {\n  if (c === null)\n    return [];\n  for (var a = new Array(c.count); c !== null; )\n    a[c.count - 1] = c.component,\n      c = c.parent;\n  return a\n}, Ar = function(c) {\n  for (var a = null, h = 0; h < c.length; h++)\n    a = {\n      parent: a,\n      component: c[h],\n      count: h + 1\n    };\n  return a\n}, li = function() {\n  function c(a) {\n    this.def = a\n  }\n  return Object.defineProperty(c.prototype, \"path\", {\n    get: function() {\n      return this.def.path\n    },\n    enumerable: !1,\n    configurable: !0\n  }),\n    Object.defineProperty(c.prototype, \"issues\", {\n      get: function() {\n        return this.def.issues\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(c.prototype, \"errorMap\", {\n      get: function() {\n        return this.def.errorMap\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(c.prototype, \"async\", {\n      get: function() {\n        return this.def.async\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    c.prototype.stepInto = function(a) {\n      return new c(ee(ee({}, this.def), {\n        path: this.path === null ? {\n          parent: null,\n          count: 1,\n          component: a\n        } : {\n          parent: this.path,\n          count: this.path.count + 1,\n          component: a\n        }\n      }))\n    }\n    ,\n    c.prototype._addIssue = function(a, h, p) {\n      p === void 0 && (p = {}),\n        p = ui({\n          data: a,\n          issueData: h,\n          path: Nn(this.path),\n          errorMaps: [this.def.errorMap, p.schemaErrorMap, qi, ji]\n        }),\n        this.issues.push(p)\n    }\n    ,\n    c\n}(), Pe = Object.freeze({\n  valid: !1\n}), Ue = function(c) {\n  return {\n    valid: !0,\n    value: c\n  }\n}, Lt = function(c) {\n  return c.valid === !1\n}, Qt = function(c) {\n  return c.valid === !0\n}, vn = function(c) {\n  return c instanceof Promise\n};\n(function(c) {\n    c.errToObj = function(a) {\n      return typeof a == \"string\" ? {\n        message: a\n      } : a || {}\n    }\n      ,\n      c.toString = function(a) {\n        return typeof a == \"string\" ? a : a?.message\n      }\n  }\n)(et = et || {});\nvar wr = function(c) {\n  return new li({\n    path: Ar(c.path || []),\n    issues: [],\n    errorMap: c.errorMap,\n    async: (c = c.async) !== null && c !== void 0 && c\n  })\n}\n  , br = function(c, a) {\n  return Qt(a) && !c.issues.length ? {\n    success: !0,\n    data: a.value\n  } : {\n    success: !1,\n    error: new On(c.issues)\n  }\n};\nfunction Ve(c) {\n  if (!c)\n    return {};\n  if (c.errorMap && (c.invalid_type_error || c.required_error))\n    throw new Error(`Can't use \"invalid\" or \"required\" in conjunction with custom error map.`);\n  return c.errorMap ? {\n    errorMap: c.errorMap\n  } : {\n    errorMap: function(a, h) {\n      return a.code !== \"invalid_type\" ? {\n        message: h.defaultError\n      } : h.data === void 0 && c.required_error ? {\n        message: c.required_error\n      } : c.invalid_type_error ? {\n        message: c.invalid_type_error\n      } : {\n        message: h.defaultError\n      }\n    }\n  }\n}\nvar Vn, Fe = function() {\n  function c(a) {\n    this.spa = this.safeParseAsync,\n      this.superRefine = this._refinement,\n      this._def = a,\n      this.transform = this.transform.bind(this),\n      this.default = this.default.bind(this)\n  }\n  return c.prototype.addIssue = function(a, h, p) {\n    a._addIssue(p.data, h, {\n      schemaErrorMap: this._def.errorMap\n    })\n  }\n    ,\n    c.prototype._parseSync = function(a, h, p) {\n      if (p = this._parse(a, h, p),\n        vn(p))\n        throw new Error(\"Synchronous parse encountered promise.\");\n      return p\n    }\n    ,\n    c.prototype._parseAsync = function(a, h, p) {\n      return p = this._parse(a, h, p),\n        Promise.resolve(p)\n    }\n    ,\n    c.prototype.parse = function(a, h) {\n      if (h = this.safeParse(a, h),\n        h.success)\n        return h.data;\n      throw h.error\n    }\n    ,\n    c.prototype.safeParse = function(a, h) {\n      return h = wr(ee(ee({}, h), {\n        async: !1\n      })),\n        a = this._parseSync(h, a, wt(a)),\n        br(h, a)\n    }\n    ,\n    c.prototype.parseAsync = function(a, h) {\n      return Bi(this, void 0, void 0, function() {\n        var p;\n        return Ui(this, function(d) {\n          switch (d.label) {\n            case 0:\n              return [4, this.safeParseAsync(a, h)];\n            case 1:\n              if ((p = d.sent()).success)\n                return [2, p.data];\n              throw p.error\n          }\n        })\n      })\n    }\n    ,\n    c.prototype.safeParseAsync = function(a, h) {\n      return Bi(this, void 0, void 0, function() {\n        var p, d;\n        return Ui(this, function(M) {\n          switch (M.label) {\n            case 0:\n              return p = wr(ee(ee({}, h), {\n                async: !0\n              })),\n                d = this._parse(p, a, wt(a)),\n                [4, vn(d) ? d : Promise.resolve(d)];\n            case 1:\n              return d = M.sent(),\n                [2, br(p, d)]\n          }\n        })\n      })\n    }\n    ,\n    c.prototype.refine = function(a, h) {\n      return this._refinement(function(p, d) {\n        function M() {\n          return d.addIssue(ee({\n            code: be.custom\n          }, (Z = p,\n            typeof h == \"string\" || h === void 0 ? {\n              message: h\n            } : typeof h == \"function\" ? h(Z) : h)));\n          var Z\n        }\n        var F = a(p);\n        return F instanceof Promise ? F.then(function(Z) {\n          return !!Z || (M(),\n            !1)\n        }) : !!F || (M(),\n          !1)\n      })\n    }\n    ,\n    c.prototype.refinement = function(a, h) {\n      return this._refinement(function(p, d) {\n        return !!a(p) || (d.addIssue(typeof h == \"function\" ? h(p, d) : h),\n          !1)\n      })\n    }\n    ,\n    c.prototype._refinement = function(a) {\n      return new Mn({\n        schema: this,\n        typeName: Le.ZodEffects,\n        effect: {\n          type: \"refinement\",\n          refinement: a\n        }\n      })\n    }\n    ,\n    c.prototype.optional = function() {\n      return on.create(this)\n    }\n    ,\n    c.prototype.nullable = function() {\n      return Gn.create(this)\n    }\n    ,\n    c.prototype.nullish = function() {\n      return this.optional().nullable()\n    }\n    ,\n    c.prototype.array = function() {\n      return Fn.create(this)\n    }\n    ,\n    c.prototype.promise = function() {\n      return _i.create(this)\n    }\n    ,\n    c.prototype.or = function(a) {\n      return Yi.create([this, a])\n    }\n    ,\n    c.prototype.and = function(a) {\n      return pi.create(this, a)\n    }\n    ,\n    c.prototype.transform = function(a) {\n      return new Mn({\n        schema: this,\n        typeName: Le.ZodEffects,\n        effect: {\n          type: \"transform\",\n          transform: a\n        }\n      })\n    }\n    ,\n    c.prototype.default = function(a) {\n      return new Gr({\n        innerType: this,\n        defaultValue: typeof a == \"function\" ? a : function() {\n          return a\n        }\n        ,\n        typeName: Le.ZodDefault\n      })\n    }\n    ,\n    c.prototype.isOptional = function() {\n      return this.safeParse(void 0).success\n    }\n    ,\n    c.prototype.isNullable = function() {\n      return this.safeParse(null).success\n    }\n    ,\n    c\n}(), Aa = /^c[^\\s-]{8,}$/i, Pa = /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i, Oa = /^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$/i, Ki = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h._regex = function(p, d, M) {\n      return h.refinement(function(F) {\n        return p.test(F)\n      }, ee({\n        validation: d,\n        code: be.invalid_string\n      }, et.errToObj(M)))\n    }\n      ,\n      h.nonempty = function(p) {\n        return h.min(1, et.errToObj(p))\n      }\n      ,\n      h\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      var M, F;\n      if (d !== we.string)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.string,\n          received: d\n        }, {\n          data: p\n        }),\n          Pe;\n      var Z = !1;\n      try {\n        for (var q = lt(this._def.checks), k = q.next(); !k.done; k = q.next()) {\n          var O = k.value;\n          if (O.kind === \"min\")\n            p.length < O.value && (Z = !0,\n              this.addIssue(h, {\n                code: be.too_small,\n                minimum: O.value,\n                type: \"string\",\n                inclusive: !0,\n                message: O.message\n              }, {\n                data: p\n              }));\n          else if (O.kind === \"max\")\n            p.length > O.value && (Z = !0,\n              this.addIssue(h, {\n                code: be.too_big,\n                maximum: O.value,\n                type: \"string\",\n                inclusive: !0,\n                message: O.message\n              }, {\n                data: p\n              }));\n          else if (O.kind === \"email\")\n            Oa.test(p) || (Z = !0,\n              this.addIssue(h, {\n                validation: \"email\",\n                code: be.invalid_string,\n                message: O.message\n              }, {\n                data: p\n              }));\n          else if (O.kind === \"uuid\")\n            Pa.test(p) || (Z = !0,\n              this.addIssue(h, {\n                validation: \"uuid\",\n                code: be.invalid_string,\n                message: O.message\n              }, {\n                data: p\n              }));\n          else if (O.kind === \"cuid\")\n            Aa.test(p) || (Z = !0,\n              this.addIssue(h, {\n                validation: \"cuid\",\n                code: be.invalid_string,\n                message: O.message\n              }, {\n                data: p\n              }));\n          else if (O.kind === \"url\")\n            try {\n              new URL(p)\n            } catch {\n              Z = !0,\n                this.addIssue(h, {\n                  validation: \"url\",\n                  code: be.invalid_string,\n                  message: O.message\n                }, {\n                  data: p\n                })\n            }\n          else\n            O.kind === \"regex\" && (O.regex.lastIndex = 0,\n            O.regex.test(p) || (Z = !0,\n              this.addIssue(h, {\n                validation: \"regex\",\n                code: be.invalid_string,\n                message: O.message\n              }, {\n                data: p\n              })))\n        }\n      } catch (B) {\n        M = {\n          error: B\n        }\n      } finally {\n        try {\n          k && !k.done && (F = q.return) && F.call(q)\n        } finally {\n          if (M)\n            throw M.error\n        }\n      }\n      return Z ? Pe : Ue(p)\n    }\n    ,\n    a.prototype._addCheck = function(h) {\n      return new a(ee(ee({}, this._def), {\n        checks: Tt(Tt([], It(this._def.checks), !1), [h])\n      }))\n    }\n    ,\n    a.prototype.email = function(h) {\n      return this._addCheck(ee({\n        kind: \"email\"\n      }, et.errToObj(h)))\n    }\n    ,\n    a.prototype.url = function(h) {\n      return this._addCheck(ee({\n        kind: \"url\"\n      }, et.errToObj(h)))\n    }\n    ,\n    a.prototype.uuid = function(h) {\n      return this._addCheck(ee({\n        kind: \"uuid\"\n      }, et.errToObj(h)))\n    }\n    ,\n    a.prototype.cuid = function(h) {\n      return this._addCheck(ee({\n        kind: \"cuid\"\n      }, et.errToObj(h)))\n    }\n    ,\n    a.prototype.regex = function(h, p) {\n      return this._addCheck(ee({\n        kind: \"regex\",\n        regex: h\n      }, et.errToObj(p)))\n    }\n    ,\n    a.prototype.min = function(h, p) {\n      return this._addCheck(ee({\n        kind: \"min\",\n        value: h\n      }, et.errToObj(p)))\n    }\n    ,\n    a.prototype.max = function(h, p) {\n      return this._addCheck(ee({\n        kind: \"max\",\n        value: h\n      }, et.errToObj(p)))\n    }\n    ,\n    a.prototype.length = function(h, p) {\n      return this.min(h, p).max(h, p)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"isEmail\", {\n      get: function() {\n        return !!this._def.checks.find(function(h) {\n          return h.kind === \"email\"\n        })\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"isURL\", {\n      get: function() {\n        return !!this._def.checks.find(function(h) {\n          return h.kind === \"url\"\n        })\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"isUUID\", {\n      get: function() {\n        return !!this._def.checks.find(function(h) {\n          return h.kind === \"uuid\"\n        })\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"isCUID\", {\n      get: function() {\n        return !!this._def.checks.find(function(h) {\n          return h.kind === \"cuid\"\n        })\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"minLength\", {\n      get: function() {\n        var h = -1 / 0;\n        return this._def.checks.map(function(p) {\n          p.kind === \"min\" && (h === null || p.value > h) && (h = p.value)\n        }),\n          h\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"maxLength\", {\n      get: function() {\n        var h = null;\n        return this._def.checks.map(function(p) {\n          p.kind === \"max\" && (h === null || p.value < h) && (h = p.value)\n        }),\n          h\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h) {\n      return new a(ee({\n        checks: [],\n        typeName: Le.ZodString\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Pr = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h.min = h.gte,\n      h.max = h.lte,\n      h.step = h.multipleOf,\n      h\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      var M, F;\n      if (d !== we.number)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.number,\n          received: d\n        }, {\n          data: p\n        }),\n          Pe;\n      var Z = !1;\n      try {\n        for (var q = lt(this._def.checks), k = q.next(); !k.done; k = q.next()) {\n          var O = k.value;\n          O.kind === \"int\" ? rt.isInteger(p) || (Z = !0,\n            this.addIssue(h, {\n              code: be.invalid_type,\n              expected: \"integer\",\n              received: \"float\",\n              message: O.message\n            }, {\n              data: p\n            })) : O.kind === \"min\" ? (O.inclusive ? p < O.value : p <= O.value) && (Z = !0,\n            this.addIssue(h, {\n              code: be.too_small,\n              minimum: O.value,\n              type: \"number\",\n              inclusive: O.inclusive,\n              message: O.message\n            }, {\n              data: p\n            })) : O.kind === \"max\" ? (O.inclusive ? p > O.value : p >= O.value) && (Z = !0,\n            this.addIssue(h, {\n              code: be.too_big,\n              maximum: O.value,\n              type: \"number\",\n              inclusive: O.inclusive,\n              message: O.message\n            }, {\n              data: p\n            })) : O.kind === \"multipleOf\" ? p % O.value != 0 && (Z = !0,\n            this.addIssue(h, {\n              code: be.not_multiple_of,\n              multipleOf: O.value,\n              message: O.message\n            }, {\n              data: p\n            })) : rt.assertNever(O)\n        }\n      } catch (B) {\n        M = {\n          error: B\n        }\n      } finally {\n        try {\n          k && !k.done && (F = q.return) && F.call(q)\n        } finally {\n          if (M)\n            throw M.error\n        }\n      }\n      return Z ? Pe : Ue(p)\n    }\n    ,\n    a.prototype.gte = function(h, p) {\n      return this.setLimit(\"min\", h, !0, et.toString(p))\n    }\n    ,\n    a.prototype.gt = function(h, p) {\n      return this.setLimit(\"min\", h, !1, et.toString(p))\n    }\n    ,\n    a.prototype.lte = function(h, p) {\n      return this.setLimit(\"max\", h, !0, et.toString(p))\n    }\n    ,\n    a.prototype.lt = function(h, p) {\n      return this.setLimit(\"max\", h, !1, et.toString(p))\n    }\n    ,\n    a.prototype.setLimit = function(h, p, d, M) {\n      return new a(ee(ee({}, this._def), {\n        checks: Tt(Tt([], It(this._def.checks), !1), [{\n          kind: h,\n          value: p,\n          inclusive: d,\n          message: et.toString(M)\n        }])\n      }))\n    }\n    ,\n    a.prototype._addCheck = function(h) {\n      return new a(ee(ee({}, this._def), {\n        checks: Tt(Tt([], It(this._def.checks), !1), [h])\n      }))\n    }\n    ,\n    a.prototype.int = function(h) {\n      return this._addCheck({\n        kind: \"int\",\n        message: et.toString(h)\n      })\n    }\n    ,\n    a.prototype.positive = function(h) {\n      return this._addCheck({\n        kind: \"min\",\n        value: 0,\n        inclusive: !1,\n        message: et.toString(h)\n      })\n    }\n    ,\n    a.prototype.negative = function(h) {\n      return this._addCheck({\n        kind: \"max\",\n        value: 0,\n        inclusive: !1,\n        message: et.toString(h)\n      })\n    }\n    ,\n    a.prototype.nonpositive = function(h) {\n      return this._addCheck({\n        kind: \"max\",\n        value: 0,\n        inclusive: !0,\n        message: et.toString(h)\n      })\n    }\n    ,\n    a.prototype.nonnegative = function(h) {\n      return this._addCheck({\n        kind: \"min\",\n        value: 0,\n        inclusive: !0,\n        message: et.toString(h)\n      })\n    }\n    ,\n    a.prototype.multipleOf = function(h, p) {\n      return this._addCheck({\n        kind: \"multipleOf\",\n        value: h,\n        message: et.toString(p)\n      })\n    }\n    ,\n    Object.defineProperty(a.prototype, \"minValue\", {\n      get: function() {\n        var h, p, d = null;\n        try {\n          for (var M = lt(this._def.checks), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            Z.kind === \"min\" && (d === null || Z.value > d) && (d = Z.value)\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"maxValue\", {\n      get: function() {\n        var h, p, d = null;\n        try {\n          for (var M = lt(this._def.checks), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            Z.kind === \"max\" && (d === null || Z.value < d) && (d = Z.value)\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"isInt\", {\n      get: function() {\n        return !!this._def.checks.find(function(h) {\n          return h.kind === \"int\"\n        })\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h) {\n      return new a(ee(ee({\n        checks: [],\n        typeName: Le.ZodNumber\n      }, Ve(h)), Ve(h)))\n    }\n    ,\n    a\n}(Fe), Or = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.bigint ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.bigint,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodBigInt\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), xr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.boolean ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.boolean,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodBoolean\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Nr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.date ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.date,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : isNaN(p.getTime()) ? (this.addIssue(h, {\n        code: be.invalid_date\n      }, {\n        data: p\n      }),\n        Pe) : Ue(new Date(p.getTime()))\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodDate\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Lr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.undefined ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.undefined,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodUndefined\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Mr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.null ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.null,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodNull\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), hi = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h._any = !0,\n      h\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodAny\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), zn = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h._unknown = !0,\n      h\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodUnknown\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Pn = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.never,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodNever\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Rr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d !== we.undefined ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.void,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h) {\n      return new a(ee({\n        typeName: Le.ZodVoid\n      }, Ve(h)))\n    }\n    ,\n    a\n}(Fe), Fn = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, F, d) {\n      var M = this._def;\n      if (d !== we.array)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.array,\n          received: d\n        }, {\n          data: F\n        }),\n          Pe;\n      var F = F\n        , Z = !1;\n      M.minLength !== null && F.length < M.minLength.value && (Z = !0,\n        this.addIssue(h, {\n          code: be.too_small,\n          minimum: M.minLength.value,\n          type: \"array\",\n          inclusive: !0,\n          message: M.minLength.message\n        }, {\n          data: F\n        })),\n      M.maxLength !== null && F.length > M.maxLength.value && (Z = !0,\n        this.addIssue(h, {\n          code: be.too_big,\n          maximum: M.maxLength.value,\n          type: \"array\",\n          inclusive: !0,\n          message: M.maxLength.message\n        }, {\n          data: F\n        }));\n      var q = []\n        , k = new Array(F.length)\n        , O = M.type\n        , B = function(C, Q) {\n        Qt(Q) ? k[C] = Q.value : Lt(Q) ? Z = !0 : q.push(Q.then(function(J) {\n          return B(C, J)\n        }))\n      };\n      return F.forEach(function(C, Q) {\n        B(Q, O._parse(h.stepInto(Q), C, wt(C)))\n      }),\n        h.async ? Promise.all(q).then(function() {\n          return Z ? Pe : Ue(k)\n        }) : Z ? Pe : Ue(k)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"element\", {\n      get: function() {\n        return this._def.type\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype.min = function(h, p) {\n      return new a(ee(ee({}, this._def), {\n        minLength: {\n          value: h,\n          message: et.toString(p)\n        }\n      }))\n    }\n    ,\n    a.prototype.max = function(h, p) {\n      return new a(ee(ee({}, this._def), {\n        maxLength: {\n          value: h,\n          message: et.toString(p)\n        }\n      }))\n    }\n    ,\n    a.prototype.length = function(h, p) {\n      return this.min(h, p).max(h, p)\n    }\n    ,\n    a.prototype.nonempty = function(h) {\n      return this.min(1, h)\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        type: h,\n        minLength: null,\n        maxLength: null,\n        typeName: Le.ZodArray\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe);\n(function(c) {\n    c.mergeShapes = function(a, h) {\n      return ee(ee({}, a), h)\n    }\n      ,\n      c.intersectShapes = function(a, h) {\n        var p, d, F = rt.objectKeys(a), M = rt.objectKeys(h), F = F.filter(function(B) {\n          return M.indexOf(B) !== -1\n        }), Z = {};\n        try {\n          for (var q = lt(F), k = q.next(); !k.done; k = q.next()) {\n            var O = k.value;\n            Z[O] = pi.create(a[O], h[O])\n          }\n        } catch (B) {\n          p = {\n            error: B\n          }\n        } finally {\n          try {\n            k && !k.done && (d = q.return) && d.call(q)\n          } finally {\n            if (p)\n              throw p.error\n          }\n        }\n        return ee(ee(ee({}, a), h), Z)\n      }\n  }\n)(Vn = Vn || {});\nvar xa = function(c) {\n  return function(a) {\n    var h = Vn.mergeShapes(c._def.shape(), a._def.shape());\n    return new un({\n      unknownKeys: c._def.unknownKeys,\n      catchall: c._def.catchall,\n      shape: function() {\n        return h\n      },\n      typeName: Le.ZodObject\n    })\n  }\n}\n  , Sr = function(c) {\n  return function(a) {\n    return new un(ee(ee({}, c), {\n      shape: function() {\n        return ee(ee({}, c.shape()), a)\n      }\n    }))\n  }\n};\nfunction An(c) {\n  if (c instanceof un) {\n    var a, h = {};\n    for (a in c.shape) {\n      var p = c.shape[a];\n      h[a] = on.create(An(p))\n    }\n    return new un(ee(ee({}, c._def), {\n      shape: function() {\n        return h\n      }\n    }))\n  }\n  return c instanceof Fn ? Fn.create(An(c.element)) : c instanceof on ? on.create(An(c.unwrap())) : c instanceof Gn ? Gn.create(An(c.unwrap())) : c instanceof Ln ? Ln.create(c.items.map(function(d) {\n    return An(d)\n  })) : c\n}\nvar un = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h._cached = null,\n      h.nonstrict = h.passthrough,\n      h.augment = Sr(h._def),\n      h.extend = Sr(h._def),\n      h\n  }\n  return He(a, c),\n    a.prototype._getCached = function() {\n      if (this._cached !== null)\n        return this._cached;\n      var h = this._def.shape()\n        , p = rt.objectKeys(h);\n      return this._cached = {\n        shape: h,\n        keys: p\n      }\n    }\n    ,\n    a.prototype._parse = function(h, p, B) {\n      var M, F, Z, q, k;\n      if (B !== we.object)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.object,\n          received: B\n        }, {\n          data: p\n        }),\n          Pe;\n      var B = this._getCached()\n        , O = B.shape\n        , B = B.keys\n        , C = !1\n        , Q = []\n        , J = {}\n        , ne = function(qe, pe) {\n        var Vt;\n        Qt(pe) ? ((Vt = pe.value) !== void 0 || qe in p) && (J[qe] = Vt) : Lt(pe) ? C = !0 : Q.push(pe.then(function(re) {\n          return ne(qe, re)\n        }))\n      };\n      try {\n        for (var Y = lt(B), Me = Y.next(); !Me.done; Me = Y.next()) {\n          var le = Me.value\n            , Se = O[le]\n            , ye = p[le];\n          ne(le, Se._parse(h.stepInto(le), ye, wt(ye)))\n        }\n      } catch (qe) {\n        oe = {\n          error: qe\n        }\n      } finally {\n        try {\n          Me && !Me.done && (M = Y.return) && M.call(Y)\n        } finally {\n          if (oe)\n            throw oe.error\n        }\n      }\n      if (this._def.catchall instanceof Pn) {\n        var oe = this._def.unknownKeys;\n        if (oe === \"passthrough\") {\n          var We = rt.objectKeys(p).filter(function(qe) {\n            return !(qe in O)\n          });\n          try {\n            for (var ct = lt(We), je = ct.next(); !je.done; je = ct.next())\n              le = je.value,\n                J[le] = p[le]\n          } catch (qe) {\n            F = {\n              error: qe\n            }\n          } finally {\n            try {\n              je && !je.done && (Z = ct.return) && Z.call(ct)\n            } finally {\n              if (F)\n                throw F.error\n            }\n          }\n        } else if (oe === \"strict\")\n          0 < (We = rt.objectKeys(p).filter(function(qe) {\n            return !(qe in O)\n          })).length && (C = !0,\n            this.addIssue(h, {\n              code: be.unrecognized_keys,\n              keys: We\n            }, {\n              data: p\n            }));\n        else if (oe !== \"strip\")\n          throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")\n      } else {\n        var Pt = this._def.catchall\n          , We = rt.objectKeys(p).filter(function(pe) {\n          return !(pe in O)\n        });\n        try {\n          for (var ft = lt(We), dt = ft.next(); !dt.done; dt = ft.next())\n            le = dt.value,\n              ye = p[le],\n              ne(le, Pt._parse(h.stepInto(le), ye, wt(ye)))\n        } catch (pe) {\n          q = {\n            error: pe\n          }\n        } finally {\n          try {\n            dt && !dt.done && (k = ft.return) && k.call(ft)\n          } finally {\n            if (q)\n              throw q.error\n          }\n        }\n      }\n      return h.async ? Promise.all(Q).then(function() {\n        return C ? Pe : Ue(J)\n      }) : C ? Pe : Ue(J)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"shape\", {\n      get: function() {\n        return this._def.shape()\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype.strict = function() {\n      return new a(ee(ee({}, this._def), {\n        unknownKeys: \"strict\"\n      }))\n    }\n    ,\n    a.prototype.strip = function() {\n      return new a(ee(ee({}, this._def), {\n        unknownKeys: \"strip\"\n      }))\n    }\n    ,\n    a.prototype.passthrough = function() {\n      return new a(ee(ee({}, this._def), {\n        unknownKeys: \"passthrough\"\n      }))\n    }\n    ,\n    a.prototype.setKey = function(h, p) {\n      var d;\n      return this.augment(((d = {})[h] = p,\n        d))\n    }\n    ,\n    a.prototype.merge = function(h) {\n      var p = Vn.mergeShapes(this._def.shape(), h._def.shape());\n      return new a({\n        unknownKeys: h._def.unknownKeys,\n        catchall: h._def.catchall,\n        shape: function() {\n          return p\n        },\n        typeName: Le.ZodObject\n      })\n    }\n    ,\n    a.prototype.catchall = function(h) {\n      return new a(ee(ee({}, this._def), {\n        catchall: h\n      }))\n    }\n    ,\n    a.prototype.pick = function(h) {\n      var p = this\n        , d = {};\n      return rt.objectKeys(h).map(function(M) {\n        d[M] = p.shape[M]\n      }),\n        new a(ee(ee({}, this._def), {\n          shape: function() {\n            return d\n          }\n        }))\n    }\n    ,\n    a.prototype.omit = function(h) {\n      var p = this\n        , d = {};\n      return rt.objectKeys(this.shape).map(function(M) {\n        rt.objectKeys(h).indexOf(M) === -1 && (d[M] = p.shape[M])\n      }),\n        new a(ee(ee({}, this._def), {\n          shape: function() {\n            return d\n          }\n        }))\n    }\n    ,\n    a.prototype.deepPartial = function() {\n      return An(this)\n    }\n    ,\n    a.prototype.partial = function(h) {\n      var p, d = this, M = {};\n      if (h)\n        return rt.objectKeys(this.shape).map(function(Z) {\n          rt.objectKeys(h).indexOf(Z) === -1 ? M[Z] = d.shape[Z] : M[Z] = d.shape[Z].optional()\n        }),\n          new a(ee(ee({}, this._def), {\n            shape: function() {\n              return M\n            }\n          }));\n      for (p in this.shape) {\n        var F = this.shape[p];\n        M[p] = F.optional()\n      }\n      return new a(ee(ee({}, this._def), {\n        shape: function() {\n          return M\n        }\n      }))\n    }\n    ,\n    a.prototype.required = function() {\n      var h, p = {};\n      for (h in this.shape) {\n        for (var d = this.shape[h]; d instanceof on; )\n          d = d._def.innerType;\n        p[h] = d\n      }\n      return new a(ee(ee({}, this._def), {\n        shape: function() {\n          return p\n        }\n      }))\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        shape: function() {\n          return h\n        },\n        unknownKeys: \"strip\",\n        catchall: Pn.create(),\n        typeName: Le.ZodObject\n      }, Ve(p)))\n    }\n    ,\n    a.strictCreate = function(h, p) {\n      return new a(ee({\n        shape: function() {\n          return h\n        },\n        unknownKeys: \"strict\",\n        catchall: Pn.create(),\n        typeName: Le.ZodObject\n      }, Ve(p)))\n    }\n    ,\n    a.lazycreate = function(h, p) {\n      return new a(ee({\n        shape: h,\n        unknownKeys: \"strip\",\n        catchall: Pn.create(),\n        typeName: Le.ZodObject\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe)\n  , Yi = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      function M(Me) {\n        var le = Me.map(function(Se) {\n          return new On(Se)\n        });\n        return (Me = le.filter(function(Se) {\n          return Se.issues[0].code !== \"invalid_type\"\n        })).length === 1 ? Me[0].issues.forEach(function(Se) {\n          return h.issues.push(Se)\n        }) : q.addIssue(h, {\n          code: be.invalid_union,\n          unionErrors: le\n        }, {\n          data: p\n        }),\n          Pe\n      }\n      var F, Z, q = this, k = this._def.options;\n      if (h.async) {\n        var O = k.map(function() {\n          return new li(ee(ee({}, h.def), {\n            issues: []\n          }))\n        });\n        return Promise.all(k.map(function(Me, le) {\n          return Me._parse(O[le], p, d)\n        })).then(function(Me) {\n          var le, Se;\n          try {\n            for (var ye = lt(Me), oe = ye.next(); !oe.done; oe = ye.next()) {\n              var We = oe.value;\n              if (Qt(We))\n                return We\n            }\n          } catch (ct) {\n            le = {\n              error: ct\n            }\n          } finally {\n            try {\n              oe && !oe.done && (Se = ye.return) && Se.call(ye)\n            } finally {\n              if (le)\n                throw le.error\n            }\n          }\n          return M(O.map(function(ct) {\n            return ct.issues\n          }))\n        })\n      }\n      var B = [];\n      try {\n        for (var C = lt(k), Q = C.next(); !Q.done; Q = C.next()) {\n          var J = Q.value\n            , ne = new li(ee(ee({}, h.def), {\n            issues: []\n          }))\n            , Y = J._parseSync(ne, p, d);\n          if (!Lt(Y))\n            return Y;\n          B.push(ne.issues)\n        }\n      } catch (Me) {\n        F = {\n          error: Me\n        }\n      } finally {\n        try {\n          Q && !Q.done && (Z = C.return) && Z.call(C)\n        } finally {\n          if (F)\n            throw F.error\n        }\n      }\n      return M(B)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"options\", {\n      get: function() {\n        return this._def.options\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h, p) {\n      return new a(ee({\n        options: h,\n        typeName: Le.ZodUnion\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe);\nfunction zi(c, a) {\n  var h, p, d = wt(c), M = wt(a);\n  if (c === a)\n    return {\n      valid: !0,\n      data: c\n    };\n  if (d === we.object && M === we.object) {\n    var F = rt.objectKeys(a)\n      , Z = rt.objectKeys(c).filter(function(ne) {\n      return F.indexOf(ne) !== -1\n    })\n      , q = ee(ee({}, c), a);\n    try {\n      for (var k = lt(Z), O = k.next(); !O.done; O = k.next()) {\n        var B = O.value;\n        if (!(C = zi(c[B], a[B])).valid)\n          return {\n            valid: !1\n          };\n        q[B] = C.data\n      }\n    } catch (ne) {\n      h = {\n        error: ne\n      }\n    } finally {\n      try {\n        O && !O.done && (p = k.return) && p.call(k)\n      } finally {\n        if (h)\n          throw h.error\n      }\n    }\n    return {\n      valid: !0,\n      data: q\n    }\n  }\n  if (d !== we.array || M !== we.array)\n    return {\n      valid: !1\n    };\n  if (c.length !== a.length)\n    return {\n      valid: !1\n    };\n  for (var C, Q = [], J = 0; J < c.length; J++) {\n    if (!(C = zi(c[J], a[J])).valid)\n      return {\n        valid: !1\n      };\n    Q.push(C.data)\n  }\n  return {\n    valid: !0,\n    data: Q\n  }\n}\nvar pi = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      function M(Z, q) {\n        return Lt(Z) || Lt(q) ? Pe : (q = zi(Z.value, q.value)).valid ? Ue(q.data) : (F.addIssue(h, {\n          code: be.invalid_intersection_types\n        }, {\n          data: p\n        }),\n          Pe)\n      }\n      var F = this;\n      return h.async ? Promise.all([this._def.left._parse(h, p, d), this._def.right._parse(h, p, d)]).then(function(q) {\n        var k = It(q, 2)\n          , q = k[0]\n          , k = k[1];\n        return M(q, k)\n      }) : M(this._def.left._parseSync(h, p, d), this._def.right._parseSync(h, p, d))\n    }\n    ,\n    a.create = function(h, p, d) {\n      return new a(ee({\n        left: h,\n        right: p,\n        typeName: Le.ZodIntersection\n      }, Ve(d)))\n    }\n    ,\n    a\n}(Fe)\n  , Ln = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      if (d !== we.array)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.array,\n          received: d\n        }, {\n          data: p\n        }),\n          Pe;\n      var M = this._def.rest;\n      if (!M && p.length > this._def.items.length)\n        return this.addIssue(h, {\n          code: be.too_big,\n          maximum: this._def.items.length,\n          inclusive: !0,\n          type: \"array\"\n        }, {\n          data: p\n        }),\n          Pe;\n      if (p.length < this._def.items.length)\n        return this.addIssue(h, {\n          code: be.too_small,\n          minimum: this._def.items.length,\n          inclusive: !0,\n          type: \"array\"\n        }, {\n          data: p\n        }),\n          Pe;\n      var F = []\n        , Z = this._def.items\n        , q = new Array(p.length)\n        , k = !1\n        , O = function(B, C) {\n        Qt(C) ? q[B] = C.value : Lt(C) ? k = !0 : F.push(C.then(function(Q) {\n          return O(B, Q)\n        }))\n      };\n      return Z.forEach(function(B, C) {\n        O(C, B._parse(h.stepInto(C), p[C], wt(p[C])))\n      }),\n      M && p.slice(Z.length).forEach(function(B, C) {\n        C += Z.length,\n          O(C, M._parse(h.stepInto(C), B, wt(B)))\n      }),\n        h.async ? Promise.all(F).then(function() {\n          return k ? Pe : Ue(q)\n        }) : k ? Pe : Ue(q)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"items\", {\n      get: function() {\n        return this._def.items\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype.rest = function(h) {\n      return new a(ee(ee({}, this._def), {\n        rest: h\n      }))\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        items: h,\n        typeName: Le.ZodTuple,\n        rest: null\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe)\n  , Dr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    Object.defineProperty(a.prototype, \"keySchema\", {\n      get: function() {\n        return this._def.keyType\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"valueSchema\", {\n      get: function() {\n        return this._def.valueType\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype._parse = function(h, p, d) {\n      if (d !== we.object)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.object,\n          received: d\n        }, {\n          data: p\n        }),\n          Pe;\n      var M, F = [], Z = this._def.keyType, q = this._def.valueType, k = {}, O = !1, B = function(C, Q) {\n        Qt(C) && Qt(Q) ? k[C.value] = Q.value : vn(C) || vn(Q) ? F.push(Promise.all([C, Q]).then(function(ne) {\n          var Y = It(ne, 2)\n            , ne = Y[0]\n            , Y = Y[1];\n          return B(ne, Y)\n        })) : O = !0\n      };\n      for (M in p)\n        B(Z._parse(h.stepInto(M), M, wt(M)), q._parse(h.stepInto(M), p[M], wt(p[M])));\n      return h.async ? Promise.all(F).then(function() {\n        return O ? Pe : Ue(k)\n      }) : O ? Pe : Ue(k)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"element\", {\n      get: function() {\n        return this._def.valueType\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h, p, d) {\n      return new a(p instanceof Fe ? ee({\n        keyType: h,\n        valueType: p,\n        typeName: Le.ZodRecord\n      }, Ve(d)) : ee({\n        keyType: Ki.create(),\n        valueType: h,\n        typeName: Le.ZodRecord\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe)\n  , kr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, Z, d) {\n      if (d !== we.map)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.map,\n          received: d\n        }, {\n          data: Z\n        }),\n          Pe;\n      var M = this._def.keyType\n        , F = this._def.valueType\n        , Z = Z\n        , q = new Map\n        , k = []\n        , O = !1\n        , B = function(C, Q) {\n        vn(C) || vn(Q) ? k.push(Promise.all([C, Q]).then(function(ne) {\n          var Y = It(ne, 2)\n            , ne = Y[0]\n            , Y = Y[1];\n          return B(ne, Y)\n        })) : Lt(C) || Lt(Q) ? O = !0 : q.set(C.value, Q.value)\n      };\n      return Tt([], It(Z.entries())).forEach(function(ne, J) {\n        var Y = It(ne, 2)\n          , ne = Y[0]\n          , Y = Y[1]\n          , J = h.stepInto(J)\n          , ne = M._parse(J.stepInto(\"key\"), ne, wt(ne))\n          , Y = F._parse(J.stepInto(\"value\"), Y, wt(Y));\n        B(ne, Y)\n      }),\n        h.async ? Promise.all(k).then(function() {\n          return O ? Pe : Ue(q)\n        }) : O ? Pe : Ue(q)\n    }\n    ,\n    a.create = function(h, p, d) {\n      return new a(ee({\n        valueType: p,\n        keyType: h,\n        typeName: Le.ZodMap\n      }, Ve(d)))\n    }\n    ,\n    a\n}(Fe)\n  , Br = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, M, d) {\n      if (d !== we.set)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.set,\n          received: d\n        }, {\n          data: M\n        }),\n          Pe;\n      var M = M\n        , F = this._def.valueType\n        , Z = new Set\n        , q = []\n        , k = !1\n        , O = function(B) {\n        Qt(B) ? Z.add(B.value) : Lt(B) ? k = !0 : q.push(B.then(function(C) {\n          return O(C)\n        }))\n      };\n      return Tt([], It(M.values())).forEach(function(B, C) {\n        return O(F._parse(h.stepInto(C), B, wt(B)))\n      }),\n        h.async ? Promise.all(q).then(function() {\n          return k ? Pe : Ue(Z)\n        }) : k ? Pe : Ue(Z)\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        valueType: h,\n        typeName: Le.ZodSet\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe)\n  , Ur = function(c) {\n  function a() {\n    var h = c !== null && c.apply(this, arguments) || this;\n    return h.validate = h.implement,\n      h\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      var M = this;\n      if (d !== we.function)\n        return this.addIssue(h, {\n          code: be.invalid_type,\n          expected: we.function,\n          received: d\n        }, {\n          data: p\n        }),\n          Pe;\n      function F(O, B) {\n        return ui({\n          data: O,\n          path: Nn(h.path),\n          errorMaps: [h.errorMap],\n          issueData: {\n            code: be.invalid_arguments,\n            argumentsError: B\n          }\n        })\n      }\n      function Z(O, B) {\n        return ui({\n          data: O,\n          path: Nn(h.path),\n          errorMaps: [h.errorMap],\n          issueData: {\n            code: be.invalid_return_type,\n            returnTypeError: B\n          }\n        })\n      }\n      var q = {\n        errorMap: h.errorMap\n      }\n        , k = p;\n      return this._def.returns instanceof _i ? Ue(function() {\n        for (var O = [], B = 0; B < arguments.length; B++)\n          O[B] = arguments[B];\n        return Bi(M, void 0, void 0, function() {\n          var C, Q, J;\n          return Ui(this, function(ne) {\n            switch (ne.label) {\n              case 0:\n                return C = new On([]),\n                  [4, this._def.args.parseAsync(O, q).catch(function(Y) {\n                    throw C.addIssue(F(O, Y)),\n                      C\n                  })];\n              case 1:\n                return Q = ne.sent(),\n                  [4, k.apply(void 0, Tt([], It(Q)))];\n              case 2:\n                return J = ne.sent(),\n                  [4, this._def.returns.parseAsync(J, q).catch(function(Y) {\n                    throw C.addIssue(Z(J, Y)),\n                      C\n                  })];\n              case 3:\n                return [2, ne.sent()]\n            }\n          })\n        })\n      }) : Ue(function() {\n        for (var O = [], B = 0; B < arguments.length; B++)\n          O[B] = arguments[B];\n        var Q = M._def.args.safeParse(O, q);\n        if (!Q.success)\n          throw new On([F(O, Q.error)]);\n        var C = k.apply(void 0, Tt([], It(Q.data)))\n          , Q = M._def.returns.safeParse(C, q);\n        if (!Q.success)\n          throw new On([Z(C, Q.error)]);\n        return Q.data\n      })\n    }\n    ,\n    a.prototype.parameters = function() {\n      return this._def.args\n    }\n    ,\n    a.prototype.returnType = function() {\n      return this._def.returns\n    }\n    ,\n    a.prototype.args = function() {\n      for (var h = [], p = 0; p < arguments.length; p++)\n        h[p] = arguments[p];\n      return new a(ee(ee({}, this._def), {\n        args: Ln.create(h).rest(zn.create())\n      }))\n    }\n    ,\n    a.prototype.returns = function(h) {\n      return new a(ee(ee({}, this._def), {\n        returns: h\n      }))\n    }\n    ,\n    a.prototype.implement = function(h) {\n      return this.parse(h)\n    }\n    ,\n    a.prototype.strictImplement = function(h) {\n      return this.parse(h)\n    }\n    ,\n    a.create = function(h, p, d) {\n      return new a(ee({\n        args: (h || Ln.create([])).rest(zn.create()),\n        returns: p || zn.create(),\n        typeName: Le.ZodFunction\n      }, Ve(d)))\n    }\n    ,\n    a\n}(Fe)\n  , zr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    Object.defineProperty(a.prototype, \"schema\", {\n      get: function() {\n        return this._def.getter()\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.prototype._parse = function(h, p, d) {\n      return this._def.getter()._parse(h, p, d)\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        getter: h,\n        typeName: Le.ZodLazy\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe)\n  , Vr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return p !== this._def.value ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: this._def.value,\n        received: p\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"value\", {\n      get: function() {\n        return this._def.value\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = function(h, p) {\n      return new a(ee({\n        value: h,\n        typeName: Le.ZodLiteral\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe);\nfunction Na(c) {\n  return new $i({\n    values: c,\n    typeName: Le.ZodEnum\n  })\n}\nvar Le, $i = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return this._def.values.indexOf(p) === -1 ? (this.addIssue(h, {\n        code: be.invalid_enum_value,\n        options: this._def.values\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    Object.defineProperty(a.prototype, \"options\", {\n      get: function() {\n        return this._def.values\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"enum\", {\n      get: function() {\n        var h, p, d = {};\n        try {\n          for (var M = lt(this._def.values), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            d[Z] = Z\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"Values\", {\n      get: function() {\n        var h, p, d = {};\n        try {\n          for (var M = lt(this._def.values), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            d[Z] = Z\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    Object.defineProperty(a.prototype, \"Enum\", {\n      get: function() {\n        var h, p, d = {};\n        try {\n          for (var M = lt(this._def.values), F = M.next(); !F.done; F = M.next()) {\n            var Z = F.value;\n            d[Z] = Z\n          }\n        } catch (q) {\n          h = {\n            error: q\n          }\n        } finally {\n          try {\n            F && !F.done && (p = M.return) && p.call(M)\n          } finally {\n            if (h)\n              throw h.error\n          }\n        }\n        return d\n      },\n      enumerable: !1,\n      configurable: !0\n    }),\n    a.create = Na,\n    a\n}(Fe), Fr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      var M = rt.getValidEnumValues(this._def.values);\n      return M.indexOf(p) === -1 ? (this.addIssue(h, {\n        code: be.invalid_enum_value,\n        options: rt.objectValues(M)\n      }, {\n        data: p\n      }),\n        Pe) : Ue(p)\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        values: h,\n        typeName: Le.ZodNativeEnum\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe), _i = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      var M = this;\n      return d !== we.promise && h.async === !1 ? (this.addIssue(h, {\n        code: be.invalid_type,\n        expected: we.promise,\n        received: d\n      }, {\n        data: p\n      }),\n        Pe) : (p = d === we.promise ? p : Promise.resolve(p),\n        Ue(p.then(function(F) {\n          return M._def.type.parseAsync(F, {\n            path: Nn(h.path),\n            errorMap: h.errorMap\n          })\n        })))\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        type: h,\n        typeName: Le.ZodPromise\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe), Mn = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype.innerType = function() {\n      return this._def.schema\n    }\n    ,\n    a.prototype._parse = function(h, p, k) {\n      var M = this\n        , F = h.async === !1\n        , Z = this._def.effect || null\n        , q = p\n        , k = k;\n      if (Z.type === \"preprocess\") {\n        var O = Z.transform(p);\n        if (h.async)\n          return Promise.resolve(O).then(function(J) {\n            return M._def.schema._parseAsync(h, J, wt(J))\n          });\n        if ((O = this._def.schema._parseSync(h, O, wt(O)))instanceof Promise)\n          throw new Error(\"Asynchronous preprocess step encountered during synchronous parse operation. Use .parseAsync instead.\");\n        return O\n      }\n      if (Z.type === \"refinement\") {\n        let J = function(ne, Y) {\n          if (Y = Y.refinement(ne, C),\n          Y instanceof Promise) {\n            if (F)\n              throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");\n            return Y.then(function() {\n              return ne\n            })\n          }\n          return ne\n        };\n        var B = !1\n          , C = {\n          addIssue: function(ne) {\n            B = !0,\n              M.addIssue(h, ne, {\n                data: q\n              })\n          },\n          get path() {\n            return Nn(h.path)\n          }\n        };\n        if (C.addIssue = C.addIssue.bind(C),\n          F) {\n          var Q = this._def.schema._parseSync(h, q, k);\n          return Lt(Q) ? Pe : (O = J(Q.value, Z),\n            B ? Pe : Ue(O))\n        }\n        return this._def.schema._parseAsync(h, q, k).then(function(ne) {\n          return Lt(ne) ? Pe : J(ne.value, Z)\n        }).then(function(ne) {\n          return B ? Pe : Ue(ne)\n        })\n      }\n      if (Z.type === \"transform\") {\n        let J = function(ne, Y) {\n          if (ne = Y.transform(ne),\n          ne instanceof Promise && F)\n            throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");\n          return ne\n        };\n        return F ? (Q = this._def.schema._parseSync(h, q, k),\n          Lt(Q) ? Pe : (O = J(Q.value, Z),\n            Ue(O))) : this._def.schema._parseAsync(h, q, k).then(function(ne) {\n          return Lt(ne) ? Pe : J(ne.value, Z)\n        }).then(function(ne) {\n          return Ue(ne)\n        })\n      }\n      rt.assertNever(Z)\n    }\n    ,\n    a.create = function(h, p, d) {\n      return new a(ee({\n        schema: h,\n        typeName: Le.ZodEffects,\n        effect: p\n      }, Ve(d)))\n    }\n    ,\n    a.createWithPreprocess = function(h, p, d) {\n      return new a(ee({\n        schema: p,\n        effect: {\n          type: \"preprocess\",\n          transform: h\n        },\n        typeName: Le.ZodEffects\n      }, Ve(d)))\n    }\n    ,\n    a\n}(Fe), on = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d === we.undefined ? Ue(void 0) : this._def.innerType._parse(h, p, d)\n    }\n    ,\n    a.prototype.unwrap = function() {\n      return this._def.innerType\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        innerType: h,\n        typeName: Le.ZodOptional\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe), Gn = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d === we.null ? Ue(null) : this._def.innerType._parse(h, p, d)\n    }\n    ,\n    a.prototype.unwrap = function() {\n      return this._def.innerType\n    }\n    ,\n    a.create = function(h, p) {\n      return new a(ee({\n        innerType: h,\n        typeName: Le.ZodNullable\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe), Gr = function(c) {\n  function a() {\n    return c !== null && c.apply(this, arguments) || this\n  }\n  return He(a, c),\n    a.prototype._parse = function(h, p, d) {\n      return d === we.undefined && (p = this._def.defaultValue()),\n        this._def.innerType._parse(h, p, wt(p))\n    }\n    ,\n    a.prototype.removeDefault = function() {\n      return this._def.innerType\n    }\n    ,\n    a.create = function(h, p) {\n      return new on(ee({\n        innerType: h,\n        typeName: Le.ZodOptional\n      }, Ve(p)))\n    }\n    ,\n    a\n}(Fe), Zr = function(c, a) {\n  return c ? hi.create().refine(c, a) : hi.create()\n}, La = {\n  object: un.lazycreate\n};\n(function(c) {\n    c.ZodString = \"ZodString\",\n      c.ZodNumber = \"ZodNumber\",\n      c.ZodBigInt = \"ZodBigInt\",\n      c.ZodBoolean = \"ZodBoolean\",\n      c.ZodDate = \"ZodDate\",\n      c.ZodUndefined = \"ZodUndefined\",\n      c.ZodNull = \"ZodNull\",\n      c.ZodAny = \"ZodAny\",\n      c.ZodUnknown = \"ZodUnknown\",\n      c.ZodNever = \"ZodNever\",\n      c.ZodVoid = \"ZodVoid\",\n      c.ZodArray = \"ZodArray\",\n      c.ZodObject = \"ZodObject\",\n      c.ZodUnion = \"ZodUnion\",\n      c.ZodIntersection = \"ZodIntersection\",\n      c.ZodTuple = \"ZodTuple\",\n      c.ZodRecord = \"ZodRecord\",\n      c.ZodMap = \"ZodMap\",\n      c.ZodSet = \"ZodSet\",\n      c.ZodFunction = \"ZodFunction\",\n      c.ZodLazy = \"ZodLazy\",\n      c.ZodLiteral = \"ZodLiteral\",\n      c.ZodEnum = \"ZodEnum\",\n      c.ZodEffects = \"ZodEffects\",\n      c.ZodNativeEnum = \"ZodNativeEnum\",\n      c.ZodOptional = \"ZodOptional\",\n      c.ZodNullable = \"ZodNullable\",\n      c.ZodDefault = \"ZodDefault\",\n      c.ZodPromise = \"ZodPromise\"\n  }\n)(Le = Le || {});\nvar Ma = function(c, a) {\n  return a === void 0 && (a = {\n    message: \"Input not instance of \" + c.name\n  }),\n    Zr(function(h) {\n      return h instanceof c\n    }, a)\n}\n  , j = Ki.create\n  , fe = Pr.create\n  , Hr = Or.create\n  , Ae = xr.create\n  , Ra = Nr.create\n  , Da = Lr.create\n  , Wi = Mr.create\n  , ka = hi.create\n  , Zn = zn.create\n  , Ba = Pn.create\n  , Ua = Rr.create\n  , Be = Fn.create\n  , he = un.create\n  , za = un.strictCreate\n  , Ji = Yi.create\n  , Va = pi.create\n  , Fa = Ln.create\n  , Ga = Dr.create\n  , Za = kr.create\n  , Ha = Br.create\n  , ja = Ur.create\n  , qa = zr.create\n  , zt = Vr.create\n  , Ka = $i.create\n  , Rn = Fr.create\n  , Ya = _i.create\n  , Er = Mn.create\n  , jr = on.create\n  , $a = Gn.create\n  , qr = Mn.createWithPreprocess\n  , Wa = function() {\n  return j().optional()\n}\n  , Ja = function() {\n  return fe().optional()\n}\n  , Xa = function() {\n  return Ae().optional()\n};\nObject.freeze({\n  __proto__: null,\n  ZodParsedType: we,\n  getParsedType: wt,\n  makeIssue: ui,\n  EMPTY_PATH: Ca,\n  pathToArray: Nn,\n  pathFromArray: Ar,\n  ParseContext: li,\n  INVALID: Pe,\n  OK: Ue,\n  isInvalid: Lt,\n  isOk: Qt,\n  isAsync: vn,\n  ZodType: Fe,\n  ZodString: Ki,\n  ZodNumber: Pr,\n  ZodBigInt: Or,\n  ZodBoolean: xr,\n  ZodDate: Nr,\n  ZodUndefined: Lr,\n  ZodNull: Mr,\n  ZodAny: hi,\n  ZodUnknown: zn,\n  ZodNever: Pn,\n  ZodVoid: Rr,\n  ZodArray: Fn,\n  get objectUtil() {\n    return Vn\n  },\n  mergeObjects: xa,\n  ZodObject: un,\n  ZodUnion: Yi,\n  ZodIntersection: pi,\n  ZodTuple: Ln,\n  ZodRecord: Dr,\n  ZodMap: kr,\n  ZodSet: Br,\n  ZodFunction: Ur,\n  ZodLazy: zr,\n  ZodLiteral: Vr,\n  ZodEnum: $i,\n  ZodNativeEnum: Fr,\n  ZodPromise: _i,\n  ZodEffects: Mn,\n  ZodTransformer: Mn,\n  ZodOptional: on,\n  ZodNullable: Gn,\n  ZodDefault: Gr,\n  custom: Zr,\n  Schema: Fe,\n  ZodSchema: Fe,\n  late: La,\n  get ZodFirstPartyTypeKind() {\n    return Le\n  },\n  any: ka,\n  array: Be,\n  bigint: Hr,\n  boolean: Ae,\n  date: Ra,\n  effect: Er,\n  enum: Ka,\n  function: ja,\n  instanceof: Ma,\n  intersection: Va,\n  lazy: qa,\n  literal: zt,\n  map: Za,\n  nativeEnum: Rn,\n  never: Ba,\n  null: Wi,\n  nullable: $a,\n  number: fe,\n  object: he,\n  oboolean: Xa,\n  onumber: Ja,\n  optional: jr,\n  ostring: Wa,\n  preprocess: qr,\n  promise: Ya,\n  record: Ga,\n  set: Ha,\n  strictObject: za,\n  string: j,\n  transformer: Er,\n  tuple: Fa,\n  undefined: Da,\n  union: Ji,\n  unknown: Zn,\n  void: Ua,\n  ZodIssueCode: be,\n  quotelessJson: Ta,\n  ZodError: On,\n  defaultErrorMap: ji,\n  get overrideErrorMap() {\n    return qi\n  },\n  setErrorMap: Ia\n});\nvar Kr = {\n  exports: {}\n};\n(function(c) {\n    var a = function(h) {\n      var p = 1e7\n        , d = 7\n        , M = 9007199254740992\n        , F = J(M)\n        , Z = \"0123456789abcdefghijklmnopqrstuvwxyz\"\n        , q = typeof BigInt == \"function\";\n      function k(t, n, i, r) {\n        return typeof t > \"u\" ? k[0] : typeof n < \"u\" ? +n == 10 && !i ? ae(t) : kn(t, n, i, r) : ae(t)\n      }\n      function O(t, n) {\n        this.value = t,\n          this.sign = n,\n          this.isSmall = !1\n      }\n      O.prototype = Object.create(k.prototype);\n      function B(t) {\n        this.value = t,\n          this.sign = t < 0,\n          this.isSmall = !0\n      }\n      B.prototype = Object.create(k.prototype);\n      function C(t) {\n        this.value = t\n      }\n      C.prototype = Object.create(k.prototype);\n      function Q(t) {\n        return -M < t && t < M\n      }\n      function J(t) {\n        return t < 1e7 ? [t] : t < 1e14 ? [t % 1e7, Math.floor(t / 1e7)] : [t % 1e7, Math.floor(t / 1e7) % 1e7, Math.floor(t / 1e14)]\n      }\n      function ne(t) {\n        Y(t);\n        var n = t.length;\n        if (n < 4 && kt(t, F) < 0)\n          switch (n) {\n            case 0:\n              return 0;\n            case 1:\n              return t[0];\n            case 2:\n              return t[0] + t[1] * p;\n            default:\n              return t[0] + (t[1] + t[2] * p) * p\n          }\n        return t\n      }\n      function Y(t) {\n        for (var n = t.length; t[--n] === 0; )\n          ;\n        t.length = n + 1\n      }\n      function Me(t) {\n        for (var n = new Array(t), i = -1; ++i < t; )\n          n[i] = 0;\n        return n\n      }\n      function le(t) {\n        return t > 0 ? Math.floor(t) : Math.ceil(t)\n      }\n      function Se(t, n) {\n        var i = t.length, r = n.length, s = new Array(i), u = 0, o = p, l, f;\n        for (f = 0; f < r; f++)\n          l = t[f] + n[f] + u,\n            u = l >= o ? 1 : 0,\n            s[f] = l - u * o;\n        for (; f < i; )\n          l = t[f] + u,\n            u = l === o ? 1 : 0,\n            s[f++] = l - u * o;\n        return u > 0 && s.push(u),\n          s\n      }\n      function ye(t, n) {\n        return t.length >= n.length ? Se(t, n) : Se(n, t)\n      }\n      function oe(t, n) {\n        var i = t.length, r = new Array(i), s = p, u, o;\n        for (o = 0; o < i; o++)\n          u = t[o] - s + n,\n            n = Math.floor(u / s),\n            r[o] = u - n * s,\n            n += 1;\n        for (; n > 0; )\n          r[o++] = n % s,\n            n = Math.floor(n / s);\n        return r\n      }\n      O.prototype.add = function(t) {\n        var n = ae(t);\n        if (this.sign !== n.sign)\n          return this.subtract(n.negate());\n        var i = this.value\n          , r = n.value;\n        return n.isSmall ? new O(oe(i, Math.abs(r)),this.sign) : new O(ye(i, r),this.sign)\n      }\n        ,\n        O.prototype.plus = O.prototype.add,\n        B.prototype.add = function(t) {\n          var n = ae(t)\n            , i = this.value;\n          if (i < 0 !== n.sign)\n            return this.subtract(n.negate());\n          var r = n.value;\n          if (n.isSmall) {\n            if (Q(i + r))\n              return new B(i + r);\n            r = J(Math.abs(r))\n          }\n          return new O(oe(r, Math.abs(i)),i < 0)\n        }\n        ,\n        B.prototype.plus = B.prototype.add,\n        C.prototype.add = function(t) {\n          return new C(this.value + ae(t).value)\n        }\n        ,\n        C.prototype.plus = C.prototype.add;\n      function We(t, n) {\n        var i = t.length, r = n.length, s = new Array(i), u = 0, o = p, l, f;\n        for (l = 0; l < r; l++)\n          f = t[l] - u - n[l],\n            f < 0 ? (f += o,\n              u = 1) : u = 0,\n            s[l] = f;\n        for (l = r; l < i; l++) {\n          if (f = t[l] - u,\n          f < 0)\n            f += o;\n          else {\n            s[l++] = f;\n            break\n          }\n          s[l] = f\n        }\n        for (; l < i; l++)\n          s[l] = t[l];\n        return Y(s),\n          s\n      }\n      function ct(t, n, i) {\n        var r;\n        return kt(t, n) >= 0 ? r = We(t, n) : (r = We(n, t),\n          i = !i),\n          r = ne(r),\n          typeof r == \"number\" ? (i && (r = -r),\n            new B(r)) : new O(r,i)\n      }\n      function je(t, n, i) {\n        var r = t.length, s = new Array(r), u = -n, o = p, l, f;\n        for (l = 0; l < r; l++)\n          f = t[l] + u,\n            u = Math.floor(f / o),\n            f %= o,\n            s[l] = f < 0 ? f + o : f;\n        return s = ne(s),\n          typeof s == \"number\" ? (i && (s = -s),\n            new B(s)) : new O(s,i)\n      }\n      O.prototype.subtract = function(t) {\n        var n = ae(t);\n        if (this.sign !== n.sign)\n          return this.add(n.negate());\n        var i = this.value\n          , r = n.value;\n        return n.isSmall ? je(i, Math.abs(r), this.sign) : ct(i, r, this.sign)\n      }\n        ,\n        O.prototype.minus = O.prototype.subtract,\n        B.prototype.subtract = function(t) {\n          var n = ae(t)\n            , i = this.value;\n          if (i < 0 !== n.sign)\n            return this.add(n.negate());\n          var r = n.value;\n          return n.isSmall ? new B(i - r) : je(r, Math.abs(i), i >= 0)\n        }\n        ,\n        B.prototype.minus = B.prototype.subtract,\n        C.prototype.subtract = function(t) {\n          return new C(this.value - ae(t).value)\n        }\n        ,\n        C.prototype.minus = C.prototype.subtract,\n        O.prototype.negate = function() {\n          return new O(this.value,!this.sign)\n        }\n        ,\n        B.prototype.negate = function() {\n          var t = this.sign\n            , n = new B(-this.value);\n          return n.sign = !t,\n            n\n        }\n        ,\n        C.prototype.negate = function() {\n          return new C(-this.value)\n        }\n        ,\n        O.prototype.abs = function() {\n          return new O(this.value,!1)\n        }\n        ,\n        B.prototype.abs = function() {\n          return new B(Math.abs(this.value))\n        }\n        ,\n        C.prototype.abs = function() {\n          return new C(this.value >= 0 ? this.value : -this.value)\n        }\n      ;\n      function Pt(t, n) {\n        var i = t.length, r = n.length, s = i + r, u = Me(s), o = p, l, f, g, y, _;\n        for (g = 0; g < i; ++g) {\n          y = t[g];\n          for (var v = 0; v < r; ++v)\n            _ = n[v],\n              l = y * _ + u[g + v],\n              f = Math.floor(l / o),\n              u[g + v] = l - f * o,\n              u[g + v + 1] += f\n        }\n        return Y(u),\n          u\n      }\n      function ft(t, n) {\n        var i = t.length, r = new Array(i), s = p, u = 0, o, l;\n        for (l = 0; l < i; l++)\n          o = t[l] * n + u,\n            u = Math.floor(o / s),\n            r[l] = o - u * s;\n        for (; u > 0; )\n          r[l++] = u % s,\n            u = Math.floor(u / s);\n        return r\n      }\n      function dt(t, n) {\n        for (var i = []; n-- > 0; )\n          i.push(0);\n        return i.concat(t)\n      }\n      function qe(t, n) {\n        var i = Math.max(t.length, n.length);\n        if (i <= 30)\n          return Pt(t, n);\n        i = Math.ceil(i / 2);\n        var r = t.slice(i)\n          , s = t.slice(0, i)\n          , u = n.slice(i)\n          , o = n.slice(0, i)\n          , l = qe(s, o)\n          , f = qe(r, u)\n          , g = qe(ye(s, r), ye(o, u))\n          , y = ye(ye(l, dt(We(We(g, l), f), i)), dt(f, 2 * i));\n        return Y(y),\n          y\n      }\n      function pe(t, n) {\n        return -.012 * t - .012 * n + 15e-6 * t * n > 0\n      }\n      O.prototype.multiply = function(t) {\n        var n = ae(t), i = this.value, r = n.value, s = this.sign !== n.sign, u;\n        if (n.isSmall) {\n          if (r === 0)\n            return k[0];\n          if (r === 1)\n            return this;\n          if (r === -1)\n            return this.negate();\n          if (u = Math.abs(r),\n          u < p)\n            return new O(ft(i, u),s);\n          r = J(u)\n        }\n        return pe(i.length, r.length) ? new O(qe(i, r),s) : new O(Pt(i, r),s)\n      }\n        ,\n        O.prototype.times = O.prototype.multiply;\n      function Vt(t, n, i) {\n        return t < p ? new O(ft(n, t),i) : new O(Pt(n, J(t)),i)\n      }\n      B.prototype._multiplyBySmall = function(t) {\n        return Q(t.value * this.value) ? new B(t.value * this.value) : Vt(Math.abs(t.value), J(Math.abs(this.value)), this.sign !== t.sign)\n      }\n        ,\n        O.prototype._multiplyBySmall = function(t) {\n          return t.value === 0 ? k[0] : t.value === 1 ? this : t.value === -1 ? this.negate() : Vt(Math.abs(t.value), this.value, this.sign !== t.sign)\n        }\n        ,\n        B.prototype.multiply = function(t) {\n          return ae(t)._multiplyBySmall(this)\n        }\n        ,\n        B.prototype.times = B.prototype.multiply,\n        C.prototype.multiply = function(t) {\n          return new C(this.value * ae(t).value)\n        }\n        ,\n        C.prototype.times = C.prototype.multiply;\n      function re(t) {\n        var n = t.length, i = Me(n + n), r = p, s, u, o, l, f;\n        for (o = 0; o < n; o++) {\n          l = t[o],\n            u = 0 - l * l;\n          for (var g = o; g < n; g++)\n            f = t[g],\n              s = 2 * (l * f) + i[o + g] + u,\n              u = Math.floor(s / r),\n              i[o + g] = s - u * r;\n          i[o + n] = u\n        }\n        return Y(i),\n          i\n      }\n      O.prototype.square = function() {\n        return new O(re(this.value),!1)\n      }\n        ,\n        B.prototype.square = function() {\n          var t = this.value * this.value;\n          return Q(t) ? new B(t) : new O(re(J(Math.abs(this.value))),!1)\n        }\n        ,\n        C.prototype.square = function(t) {\n          return new C(this.value * this.value)\n        }\n      ;\n      function Ot(t, n) {\n        var i = t.length, r = n.length, s = p, u = Me(n.length), o = n[r - 1], l = Math.ceil(s / (2 * o)), f = ft(t, l), g = ft(n, l), y, _, v, b, T, x, S;\n        for (f.length <= i && f.push(0),\n               g.push(0),\n               o = g[r - 1],\n               _ = i - r; _ >= 0; _--) {\n          for (y = s - 1,\n               f[_ + r] !== o && (y = Math.floor((f[_ + r] * s + f[_ + r - 1]) / o)),\n                 v = 0,\n                 b = 0,\n                 x = g.length,\n                 T = 0; T < x; T++)\n            v += y * g[T],\n              S = Math.floor(v / s),\n              b += f[_ + T] - (v - S * s),\n              v = S,\n              b < 0 ? (f[_ + T] = b + s,\n                b = -1) : (f[_ + T] = b,\n                b = 0);\n          for (; b !== 0; ) {\n            for (y -= 1,\n                   v = 0,\n                   T = 0; T < x; T++)\n              v += f[_ + T] - s + g[T],\n                v < 0 ? (f[_ + T] = v + s,\n                  v = 0) : (f[_ + T] = v,\n                  v = 1);\n            b += v\n          }\n          u[_] = y\n        }\n        return f = ke(f, l)[0],\n          [ne(u), ne(f)]\n      }\n      function Ft(t, n) {\n        for (var i = t.length, r = n.length, s = [], u = [], o = p, l, f, g, y, _; i; ) {\n          if (u.unshift(t[--i]),\n            Y(u),\n          kt(u, n) < 0) {\n            s.push(0);\n            continue\n          }\n          f = u.length,\n            g = u[f - 1] * o + u[f - 2],\n            y = n[r - 1] * o + n[r - 2],\n          f > r && (g = (g + 1) * o),\n            l = Math.ceil(g / y);\n          do {\n            if (_ = ft(n, l),\n            kt(_, u) <= 0)\n              break;\n            l--\n          } while (l);\n          s.push(l),\n            u = We(u, _)\n        }\n        return s.reverse(),\n          [ne(s), ne(u)]\n      }\n      function ke(t, n) {\n        var i = t.length, r = Me(i), s = p, u, o, l, f;\n        for (l = 0,\n               u = i - 1; u >= 0; --u)\n          f = l * s + t[u],\n            o = le(f / n),\n            l = f - o * n,\n            r[u] = o | 0;\n        return [r, l | 0]\n      }\n      function ot(t, n) {\n        var i, r = ae(n);\n        if (q)\n          return [new C(t.value / r.value), new C(t.value % r.value)];\n        var s = t.value, u = r.value, o;\n        if (u === 0)\n          throw new Error(\"Cannot divide by zero\");\n        if (t.isSmall)\n          return r.isSmall ? [new B(le(s / u)), new B(s % u)] : [k[0], t];\n        if (r.isSmall) {\n          if (u === 1)\n            return [t, k[0]];\n          if (u == -1)\n            return [t.negate(), k[0]];\n          var l = Math.abs(u);\n          if (l < p) {\n            i = ke(s, l),\n              o = ne(i[0]);\n            var f = i[1];\n            return t.sign && (f = -f),\n              typeof o == \"number\" ? (t.sign !== r.sign && (o = -o),\n                [new B(o), new B(f)]) : [new O(o,t.sign !== r.sign), new B(f)]\n          }\n          u = J(l)\n        }\n        var g = kt(s, u);\n        if (g === -1)\n          return [k[0], t];\n        if (g === 0)\n          return [k[t.sign === r.sign ? 1 : -1], k[0]];\n        s.length + u.length <= 200 ? i = Ot(s, u) : i = Ft(s, u),\n          o = i[0];\n        var y = t.sign !== r.sign\n          , _ = i[1]\n          , v = t.sign;\n        return typeof o == \"number\" ? (y && (o = -o),\n          o = new B(o)) : o = new O(o,y),\n          typeof _ == \"number\" ? (v && (_ = -_),\n            _ = new B(_)) : _ = new O(_,v),\n          [o, _]\n      }\n      O.prototype.divmod = function(t) {\n        var n = ot(this, t);\n        return {\n          quotient: n[0],\n          remainder: n[1]\n        }\n      }\n        ,\n        C.prototype.divmod = B.prototype.divmod = O.prototype.divmod,\n        O.prototype.divide = function(t) {\n          return ot(this, t)[0]\n        }\n        ,\n        C.prototype.over = C.prototype.divide = function(t) {\n          return new C(this.value / ae(t).value)\n        }\n        ,\n        B.prototype.over = B.prototype.divide = O.prototype.over = O.prototype.divide,\n        O.prototype.mod = function(t) {\n          return ot(this, t)[1]\n        }\n        ,\n        C.prototype.mod = C.prototype.remainder = function(t) {\n          return new C(this.value % ae(t).value)\n        }\n        ,\n        B.prototype.remainder = B.prototype.mod = O.prototype.remainder = O.prototype.mod,\n        O.prototype.pow = function(t) {\n          var n = ae(t), i = this.value, r = n.value, s, u, o;\n          if (r === 0)\n            return k[1];\n          if (i === 0)\n            return k[0];\n          if (i === 1)\n            return k[1];\n          if (i === -1)\n            return n.isEven() ? k[1] : k[-1];\n          if (n.sign)\n            return k[0];\n          if (!n.isSmall)\n            throw new Error(\"The exponent \" + n.toString() + \" is too large.\");\n          if (this.isSmall && Q(s = Math.pow(i, r)))\n            return new B(le(s));\n          for (u = this,\n                 o = k[1]; r & !0 && (o = o.times(u),\n            --r),\n               r !== 0; )\n            r /= 2,\n              u = u.square();\n          return o\n        }\n        ,\n        B.prototype.pow = O.prototype.pow,\n        C.prototype.pow = function(t) {\n          var n = ae(t)\n            , i = this.value\n            , r = n.value\n            , s = BigInt(0)\n            , u = BigInt(1)\n            , o = BigInt(2);\n          if (r === s)\n            return k[1];\n          if (i === s)\n            return k[0];\n          if (i === u)\n            return k[1];\n          if (i === BigInt(-1))\n            return n.isEven() ? k[1] : k[-1];\n          if (n.isNegative())\n            return new C(s);\n          for (var l = this, f = k[1]; (r & u) === u && (f = f.times(l),\n            --r),\n          r !== s; )\n            r /= o,\n              l = l.square();\n          return f\n        }\n        ,\n        O.prototype.modPow = function(t, n) {\n          if (t = ae(t),\n            n = ae(n),\n            n.isZero())\n            throw new Error(\"Cannot take modPow with modulus 0\");\n          var i = k[1]\n            , r = this.mod(n);\n          for (t.isNegative() && (t = t.multiply(k[-1]),\n            r = r.modInv(n)); t.isPositive(); ) {\n            if (r.isZero())\n              return k[0];\n            t.isOdd() && (i = i.multiply(r).mod(n)),\n              t = t.divide(2),\n              r = r.square().mod(n)\n          }\n          return i\n        }\n        ,\n        C.prototype.modPow = B.prototype.modPow = O.prototype.modPow;\n      function kt(t, n) {\n        if (t.length !== n.length)\n          return t.length > n.length ? 1 : -1;\n        for (var i = t.length - 1; i >= 0; i--)\n          if (t[i] !== n[i])\n            return t[i] > n[i] ? 1 : -1;\n        return 0\n      }\n      O.prototype.compareAbs = function(t) {\n        var n = ae(t)\n          , i = this.value\n          , r = n.value;\n        return n.isSmall ? 1 : kt(i, r)\n      }\n        ,\n        B.prototype.compareAbs = function(t) {\n          var n = ae(t)\n            , i = Math.abs(this.value)\n            , r = n.value;\n          return n.isSmall ? (r = Math.abs(r),\n            i === r ? 0 : i > r ? 1 : -1) : -1\n        }\n        ,\n        C.prototype.compareAbs = function(t) {\n          var n = this.value\n            , i = ae(t).value;\n          return n = n >= 0 ? n : -n,\n            i = i >= 0 ? i : -i,\n            n === i ? 0 : n > i ? 1 : -1\n        }\n        ,\n        O.prototype.compare = function(t) {\n          if (t === 1 / 0)\n            return -1;\n          if (t === -1 / 0)\n            return 1;\n          var n = ae(t)\n            , i = this.value\n            , r = n.value;\n          return this.sign !== n.sign ? n.sign ? 1 : -1 : n.isSmall ? this.sign ? -1 : 1 : kt(i, r) * (this.sign ? -1 : 1)\n        }\n        ,\n        O.prototype.compareTo = O.prototype.compare,\n        B.prototype.compare = function(t) {\n          if (t === 1 / 0)\n            return -1;\n          if (t === -1 / 0)\n            return 1;\n          var n = ae(t)\n            , i = this.value\n            , r = n.value;\n          return n.isSmall ? i == r ? 0 : i > r ? 1 : -1 : i < 0 !== n.sign ? i < 0 ? -1 : 1 : i < 0 ? 1 : -1\n        }\n        ,\n        B.prototype.compareTo = B.prototype.compare,\n        C.prototype.compare = function(t) {\n          if (t === 1 / 0)\n            return -1;\n          if (t === -1 / 0)\n            return 1;\n          var n = this.value\n            , i = ae(t).value;\n          return n === i ? 0 : n > i ? 1 : -1\n        }\n        ,\n        C.prototype.compareTo = C.prototype.compare,\n        O.prototype.equals = function(t) {\n          return this.compare(t) === 0\n        }\n        ,\n        C.prototype.eq = C.prototype.equals = B.prototype.eq = B.prototype.equals = O.prototype.eq = O.prototype.equals,\n        O.prototype.notEquals = function(t) {\n          return this.compare(t) !== 0\n        }\n        ,\n        C.prototype.neq = C.prototype.notEquals = B.prototype.neq = B.prototype.notEquals = O.prototype.neq = O.prototype.notEquals,\n        O.prototype.greater = function(t) {\n          return this.compare(t) > 0\n        }\n        ,\n        C.prototype.gt = C.prototype.greater = B.prototype.gt = B.prototype.greater = O.prototype.gt = O.prototype.greater,\n        O.prototype.lesser = function(t) {\n          return this.compare(t) < 0\n        }\n        ,\n        C.prototype.lt = C.prototype.lesser = B.prototype.lt = B.prototype.lesser = O.prototype.lt = O.prototype.lesser,\n        O.prototype.greaterOrEquals = function(t) {\n          return this.compare(t) >= 0\n        }\n        ,\n        C.prototype.geq = C.prototype.greaterOrEquals = B.prototype.geq = B.prototype.greaterOrEquals = O.prototype.geq = O.prototype.greaterOrEquals,\n        O.prototype.lesserOrEquals = function(t) {\n          return this.compare(t) <= 0\n        }\n        ,\n        C.prototype.leq = C.prototype.lesserOrEquals = B.prototype.leq = B.prototype.lesserOrEquals = O.prototype.leq = O.prototype.lesserOrEquals,\n        O.prototype.isEven = function() {\n          return (this.value[0] & 1) === 0\n        }\n        ,\n        B.prototype.isEven = function() {\n          return (this.value & 1) === 0\n        }\n        ,\n        C.prototype.isEven = function() {\n          return (this.value & BigInt(1)) === BigInt(0)\n        }\n        ,\n        O.prototype.isOdd = function() {\n          return (this.value[0] & 1) === 1\n        }\n        ,\n        B.prototype.isOdd = function() {\n          return (this.value & 1) === 1\n        }\n        ,\n        C.prototype.isOdd = function() {\n          return (this.value & BigInt(1)) === BigInt(1)\n        }\n        ,\n        O.prototype.isPositive = function() {\n          return !this.sign\n        }\n        ,\n        B.prototype.isPositive = function() {\n          return this.value > 0\n        }\n        ,\n        C.prototype.isPositive = B.prototype.isPositive,\n        O.prototype.isNegative = function() {\n          return this.sign\n        }\n        ,\n        B.prototype.isNegative = function() {\n          return this.value < 0\n        }\n        ,\n        C.prototype.isNegative = B.prototype.isNegative,\n        O.prototype.isUnit = function() {\n          return !1\n        }\n        ,\n        B.prototype.isUnit = function() {\n          return Math.abs(this.value) === 1\n        }\n        ,\n        C.prototype.isUnit = function() {\n          return this.abs().value === BigInt(1)\n        }\n        ,\n        O.prototype.isZero = function() {\n          return !1\n        }\n        ,\n        B.prototype.isZero = function() {\n          return this.value === 0\n        }\n        ,\n        C.prototype.isZero = function() {\n          return this.value === BigInt(0)\n        }\n        ,\n        O.prototype.isDivisibleBy = function(t) {\n          var n = ae(t);\n          return n.isZero() ? !1 : n.isUnit() ? !0 : n.compareAbs(2) === 0 ? this.isEven() : this.mod(n).isZero()\n        }\n        ,\n        C.prototype.isDivisibleBy = B.prototype.isDivisibleBy = O.prototype.isDivisibleBy;\n      function yn(t) {\n        var n = t.abs();\n        if (n.isUnit())\n          return !1;\n        if (n.equals(2) || n.equals(3) || n.equals(5))\n          return !0;\n        if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5))\n          return !1;\n        if (n.lesser(49))\n          return !0\n      }\n      function Gt(t, n) {\n        for (var i = t.prev(), r = i, s = 0, u, o, l; r.isEven(); )\n          r = r.divide(2),\n            s++;\n        e: for (o = 0; o < n.length; o++)\n          if (!t.lesser(n[o]) && (l = a(n[o]).modPow(r, t),\n            !(l.isUnit() || l.equals(i)))) {\n            for (u = s - 1; u != 0; u--) {\n              if (l = l.square().mod(t),\n                l.isUnit())\n                return !1;\n              if (l.equals(i))\n                continue e\n            }\n            return !1\n          }\n        return !0\n      }\n      O.prototype.isPrime = function(t) {\n        var n = yn(this);\n        if (n !== h)\n          return n;\n        var i = this.abs()\n          , r = i.bitLength();\n        if (r <= 64)\n          return Gt(i, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);\n        for (var s = Math.log(2) * r.toJSNumber(), u = Math.ceil(t === !0 ? 2 * Math.pow(s, 2) : s), o = [], l = 0; l < u; l++)\n          o.push(a(l + 2));\n        return Gt(i, o)\n      }\n        ,\n        C.prototype.isPrime = B.prototype.isPrime = O.prototype.isPrime,\n        O.prototype.isProbablePrime = function(t, n) {\n          var i = yn(this);\n          if (i !== h)\n            return i;\n          for (var r = this.abs(), s = t === h ? 5 : t, u = [], o = 0; o < s; o++)\n            u.push(a.randBetween(2, r.minus(2), n));\n          return Gt(r, u)\n        }\n        ,\n        C.prototype.isProbablePrime = B.prototype.isProbablePrime = O.prototype.isProbablePrime,\n        O.prototype.modInv = function(t) {\n          for (var n = a.zero, i = a.one, r = ae(t), s = this.abs(), u, o, l; !s.isZero(); )\n            u = r.divide(s),\n              o = n,\n              l = r,\n              n = i,\n              r = s,\n              i = o.subtract(u.multiply(i)),\n              s = l.subtract(u.multiply(s));\n          if (!r.isUnit())\n            throw new Error(this.toString() + \" and \" + t.toString() + \" are not co-prime\");\n          return n.compare(0) === -1 && (n = n.add(t)),\n            this.isNegative() ? n.negate() : n\n        }\n        ,\n        C.prototype.modInv = B.prototype.modInv = O.prototype.modInv,\n        O.prototype.next = function() {\n          var t = this.value;\n          return this.sign ? je(t, 1, this.sign) : new O(oe(t, 1),this.sign)\n        }\n        ,\n        B.prototype.next = function() {\n          var t = this.value;\n          return t + 1 < M ? new B(t + 1) : new O(F,!1)\n        }\n        ,\n        C.prototype.next = function() {\n          return new C(this.value + BigInt(1))\n        }\n        ,\n        O.prototype.prev = function() {\n          var t = this.value;\n          return this.sign ? new O(oe(t, 1),!0) : je(t, 1, this.sign)\n        }\n        ,\n        B.prototype.prev = function() {\n          var t = this.value;\n          return t - 1 > -M ? new B(t - 1) : new O(F,!0)\n        }\n        ,\n        C.prototype.prev = function() {\n          return new C(this.value - BigInt(1))\n        }\n      ;\n      for (var Mt = [1]; 2 * Mt[Mt.length - 1] <= p; )\n        Mt.push(2 * Mt[Mt.length - 1]);\n      var Xe = Mt.length\n        , xt = Mt[Xe - 1];\n      function en(t) {\n        return Math.abs(t) <= p\n      }\n      O.prototype.shiftLeft = function(t) {\n        var n = ae(t).toJSNumber();\n        if (!en(n))\n          throw new Error(String(n) + \" is too large for shifting.\");\n        if (n < 0)\n          return this.shiftRight(-n);\n        var i = this;\n        if (i.isZero())\n          return i;\n        for (; n >= Xe; )\n          i = i.multiply(xt),\n            n -= Xe - 1;\n        return i.multiply(Mt[n])\n      }\n        ,\n        C.prototype.shiftLeft = B.prototype.shiftLeft = O.prototype.shiftLeft,\n        O.prototype.shiftRight = function(t) {\n          var n, i = ae(t).toJSNumber();\n          if (!en(i))\n            throw new Error(String(i) + \" is too large for shifting.\");\n          if (i < 0)\n            return this.shiftLeft(-i);\n          for (var r = this; i >= Xe; ) {\n            if (r.isZero() || r.isNegative() && r.isUnit())\n              return r;\n            n = ot(r, xt),\n              r = n[1].isNegative() ? n[0].prev() : n[0],\n              i -= Xe - 1\n          }\n          return n = ot(r, Mt[i]),\n            n[1].isNegative() ? n[0].prev() : n[0]\n        }\n        ,\n        C.prototype.shiftRight = B.prototype.shiftRight = O.prototype.shiftRight;\n      function Kt(t, n, i) {\n        n = ae(n);\n        for (var r = t.isNegative(), s = n.isNegative(), u = r ? t.not() : t, o = s ? n.not() : n, l = 0, f = 0, g = null, y = null, _ = []; !u.isZero() || !o.isZero(); )\n          g = ot(u, xt),\n            l = g[1].toJSNumber(),\n          r && (l = xt - 1 - l),\n            y = ot(o, xt),\n            f = y[1].toJSNumber(),\n          s && (f = xt - 1 - f),\n            u = g[0],\n            o = y[0],\n            _.push(i(l, f));\n        for (var v = i(r ? 1 : 0, s ? 1 : 0) !== 0 ? a(-1) : a(0), b = _.length - 1; b >= 0; b -= 1)\n          v = v.multiply(xt).add(a(_[b]));\n        return v\n      }\n      O.prototype.not = function() {\n        return this.negate().prev()\n      }\n        ,\n        C.prototype.not = B.prototype.not = O.prototype.not,\n        O.prototype.and = function(t) {\n          return Kt(this, t, function(n, i) {\n            return n & i\n          })\n        }\n        ,\n        C.prototype.and = B.prototype.and = O.prototype.and,\n        O.prototype.or = function(t) {\n          return Kt(this, t, function(n, i) {\n            return n | i\n          })\n        }\n        ,\n        C.prototype.or = B.prototype.or = O.prototype.or,\n        O.prototype.xor = function(t) {\n          return Kt(this, t, function(n, i) {\n            return n ^ i\n          })\n        }\n        ,\n        C.prototype.xor = B.prototype.xor = O.prototype.xor;\n      var Ce = 1 << 30\n        , tt = (p & -p) * (p & -p) | Ce;\n      function Ke(t) {\n        var n = t.value\n          , i = typeof n == \"number\" ? n | Ce : typeof n == \"bigint\" ? n | BigInt(Ce) : n[0] + n[1] * p | tt;\n        return i & -i\n      }\n      function Rt(t, n) {\n        if (n.compareTo(t) <= 0) {\n          var i = Rt(t, n.square(n))\n            , r = i.p\n            , s = i.e\n            , u = r.multiply(n);\n          return u.compareTo(t) <= 0 ? {\n            p: u,\n            e: s * 2 + 1\n          } : {\n            p: r,\n            e: s * 2\n          }\n        }\n        return {\n          p: a(1),\n          e: 0\n        }\n      }\n      O.prototype.bitLength = function() {\n        var t = this;\n        return t.compareTo(a(0)) < 0 && (t = t.negate().subtract(a(1))),\n          t.compareTo(a(0)) === 0 ? a(0) : a(Rt(t, a(2)).e).add(a(1))\n      }\n        ,\n        C.prototype.bitLength = B.prototype.bitLength = O.prototype.bitLength;\n      function Zt(t, n) {\n        return t = ae(t),\n          n = ae(n),\n          t.greater(n) ? t : n\n      }\n      function tn(t, n) {\n        return t = ae(t),\n          n = ae(n),\n          t.lesser(n) ? t : n\n      }\n      function cn(t, n) {\n        if (t = ae(t).abs(),\n          n = ae(n).abs(),\n          t.equals(n))\n          return t;\n        if (t.isZero())\n          return n;\n        if (n.isZero())\n          return t;\n        for (var i = k[1], r, s; t.isEven() && n.isEven(); )\n          r = tn(Ke(t), Ke(n)),\n            t = t.divide(r),\n            n = n.divide(r),\n            i = i.multiply(r);\n        for (; t.isEven(); )\n          t = t.divide(Ke(t));\n        do {\n          for (; n.isEven(); )\n            n = n.divide(Ke(n));\n          t.greater(n) && (s = n,\n            n = t,\n            t = s),\n            n = n.subtract(t)\n        } while (!n.isZero());\n        return i.isUnit() ? t : t.multiply(i)\n      }\n      function wn(t, n) {\n        return t = ae(t).abs(),\n          n = ae(n).abs(),\n          t.divide(cn(t, n)).multiply(n)\n      }\n      function bn(t, n, i) {\n        t = ae(t),\n          n = ae(n);\n        var r = i || Math.random\n          , s = tn(t, n)\n          , u = Zt(t, n)\n          , o = u.subtract(s).add(1);\n        if (o.isSmall)\n          return s.add(Math.floor(r() * o));\n        for (var l = Je(o, p).value, f = [], g = !0, y = 0; y < l.length; y++) {\n          var _ = g ? l[y] : p\n            , v = le(r() * _);\n          f.push(v),\n          v < _ && (g = !1)\n        }\n        return s.add(k.fromArray(f, p, !1))\n      }\n      var kn = function(t, n, i, r) {\n        i = i || Z,\n          t = String(t),\n        r || (t = t.toLowerCase(),\n          i = i.toLowerCase());\n        var s = t.length, u, o = Math.abs(n), l = {};\n        for (u = 0; u < i.length; u++)\n          l[i[u]] = u;\n        for (u = 0; u < s; u++) {\n          var f = t[u];\n          if (f !== \"-\" && f in l && l[f] >= o) {\n            if (f === \"1\" && o === 1)\n              continue;\n            throw new Error(f + \" is not a valid digit in base \" + n + \".\")\n          }\n        }\n        n = ae(n);\n        var g = []\n          , y = t[0] === \"-\";\n        for (u = y ? 1 : 0; u < t.length; u++) {\n          var f = t[u];\n          if (f in l)\n            g.push(ae(l[f]));\n          else if (f === \"<\") {\n            var _ = u;\n            do\n              u++;\n            while (t[u] !== \">\" && u < t.length);\n            g.push(ae(t.slice(_ + 1, u)))\n          } else\n            throw new Error(f + \" is not a valid character\")\n        }\n        return Sn(g, n, y)\n      };\n      function Sn(t, n, i) {\n        var r = k[0], s = k[1], u;\n        for (u = t.length - 1; u >= 0; u--)\n          r = r.add(t[u].times(s)),\n            s = s.times(n);\n        return i ? r.negate() : r\n      }\n      function Bn(t, n) {\n        return n = n || Z,\n          t < n.length ? n[t] : \"<\" + t + \">\"\n      }\n      function Je(t, n) {\n        if (n = a(n),\n          n.isZero()) {\n          if (t.isZero())\n            return {\n              value: [0],\n              isNegative: !1\n            };\n          throw new Error(\"Cannot convert nonzero numbers to base 0.\")\n        }\n        if (n.equals(-1)) {\n          if (t.isZero())\n            return {\n              value: [0],\n              isNegative: !1\n            };\n          if (t.isNegative())\n            return {\n              value: [].concat.apply([], Array.apply(null, Array(-t.toJSNumber())).map(Array.prototype.valueOf, [1, 0])),\n              isNegative: !1\n            };\n          var i = Array.apply(null, Array(t.toJSNumber() - 1)).map(Array.prototype.valueOf, [0, 1]);\n          return i.unshift([1]),\n            {\n              value: [].concat.apply([], i),\n              isNegative: !1\n            }\n        }\n        var r = !1;\n        if (t.isNegative() && n.isPositive() && (r = !0,\n          t = t.abs()),\n          n.isUnit())\n          return t.isZero() ? {\n            value: [0],\n            isNegative: !1\n          } : {\n            value: Array.apply(null, Array(t.toJSNumber())).map(Number.prototype.valueOf, 1),\n            isNegative: r\n          };\n        for (var s = [], u = t, o; u.isNegative() || u.compareAbs(n) >= 0; ) {\n          o = u.divmod(n),\n            u = o.quotient;\n          var l = o.remainder;\n          l.isNegative() && (l = n.minus(l).abs(),\n            u = u.next()),\n            s.push(l.toJSNumber())\n        }\n        return s.push(u.toJSNumber()),\n          {\n            value: s.reverse(),\n            isNegative: r\n          }\n      }\n      function nn(t, n, i) {\n        var r = Je(t, n);\n        return (r.isNegative ? \"-\" : \"\") + r.value.map(function(s) {\n          return Bn(s, i)\n        }).join(\"\")\n      }\n      O.prototype.toArray = function(t) {\n        return Je(this, t)\n      }\n        ,\n        B.prototype.toArray = function(t) {\n          return Je(this, t)\n        }\n        ,\n        C.prototype.toArray = function(t) {\n          return Je(this, t)\n        }\n        ,\n        O.prototype.toString = function(t, n) {\n          if (t === h && (t = 10),\n          t !== 10)\n            return nn(this, t, n);\n          for (var i = this.value, r = i.length, s = String(i[--r]), u = \"0000000\", o; --r >= 0; )\n            o = String(i[r]),\n              s += u.slice(o.length) + o;\n          var l = this.sign ? \"-\" : \"\";\n          return l + s\n        }\n        ,\n        B.prototype.toString = function(t, n) {\n          return t === h && (t = 10),\n            t != 10 ? nn(this, t, n) : String(this.value)\n        }\n        ,\n        C.prototype.toString = B.prototype.toString,\n        C.prototype.toJSON = O.prototype.toJSON = B.prototype.toJSON = function() {\n          return this.toString()\n        }\n        ,\n        O.prototype.valueOf = function() {\n          return parseInt(this.toString(), 10)\n        }\n        ,\n        O.prototype.toJSNumber = O.prototype.valueOf,\n        B.prototype.valueOf = function() {\n          return this.value\n        }\n        ,\n        B.prototype.toJSNumber = B.prototype.valueOf,\n        C.prototype.valueOf = C.prototype.toJSNumber = function() {\n          return parseInt(this.toString(), 10)\n        }\n      ;\n      function Qe(t) {\n        if (Q(+t)) {\n          var n = +t;\n          if (n === le(n))\n            return q ? new C(BigInt(n)) : new B(n);\n          throw new Error(\"Invalid integer: \" + t)\n        }\n        var i = t[0] === \"-\";\n        i && (t = t.slice(1));\n        var r = t.split(/e/i);\n        if (r.length > 2)\n          throw new Error(\"Invalid integer: \" + r.join(\"e\"));\n        if (r.length === 2) {\n          var s = r[1];\n          if (s[0] === \"+\" && (s = s.slice(1)),\n            s = +s,\n          s !== le(s) || !Q(s))\n            throw new Error(\"Invalid integer: \" + s + \" is not a valid exponent.\");\n          var u = r[0]\n            , o = u.indexOf(\".\");\n          if (o >= 0 && (s -= u.length - o - 1,\n            u = u.slice(0, o) + u.slice(o + 1)),\n          s < 0)\n            throw new Error(\"Cannot include negative exponent part for integers\");\n          u += new Array(s + 1).join(\"0\"),\n            t = u\n        }\n        var l = /^([0-9][0-9]*)$/.test(t);\n        if (!l)\n          throw new Error(\"Invalid integer: \" + t);\n        if (q)\n          return new C(BigInt(i ? \"-\" + t : t));\n        for (var f = [], g = t.length, y = d, _ = g - y; g > 0; )\n          f.push(+t.slice(_, g)),\n            _ -= y,\n          _ < 0 && (_ = 0),\n            g -= y;\n        return Y(f),\n          new O(f,i)\n      }\n      function En(t) {\n        if (q)\n          return new C(BigInt(t));\n        if (Q(t)) {\n          if (t !== le(t))\n            throw new Error(t + \" is not an integer.\");\n          return new B(t)\n        }\n        return Qe(t.toString())\n      }\n      function ae(t) {\n        return typeof t == \"number\" ? En(t) : typeof t == \"string\" ? Qe(t) : typeof t == \"bigint\" ? new C(t) : t\n      }\n      for (var e = 0; e < 1e3; e++)\n        k[e] = ae(e),\n        e > 0 && (k[-e] = ae(-e));\n      return k.one = k[1],\n        k.zero = k[0],\n        k.minusOne = k[-1],\n        k.max = Zt,\n        k.min = tn,\n        k.gcd = cn,\n        k.lcm = wn,\n        k.isInstance = function(t) {\n          return t instanceof O || t instanceof B || t instanceof C\n        }\n        ,\n        k.randBetween = bn,\n        k.fromArray = function(t, n, i) {\n          return Sn(t.map(ae), ae(n || 10), i)\n        }\n        ,\n        k\n    }();\n    c.hasOwnProperty(\"exports\") && (c.exports = a)\n  }\n)(Kr);\nvar Qa = Kr.exports\n  , Yr = 64\n  , Vi = 16\n  , an = Yr / Vi;\nfunction eo() {\n  try {\n    return !0\n  } catch {\n    return !1\n  }\n}\nfunction to(c, a, h) {\n  let p = 0;\n  for (let d = 0; d < h; d++) {\n    let M = c[a + d];\n    if (M === void 0)\n      break;\n    p += M * Math.pow(16, d)\n  }\n  return p\n}\nfunction $r(c) {\n  let a = [];\n  for (let h = 0; h < c.length; h++) {\n    let p = Number(c[h]);\n    for (let d = 0; p || d < a.length; d++)\n      p += (a[d] || 0) * 10,\n        a[d] = p % 16,\n        p = (p - a[d]) / 16\n  }\n  return a\n}\nfunction no(c) {\n  let a = $r(c)\n    , h = Array(an);\n  for (let p = 0; p < an; p++)\n    h[an - 1 - p] = to(a, p * an, an);\n  return h\n}\nvar Hn = class c {\n  constructor(a, h) {\n    this.parts = a,\n      this.str = h\n  }\n  static fromString(a) {\n    return new c(no(a),a)\n  }\n  static fromBit(a) {\n    let h = Array(an)\n      , p = Math.floor(a / Vi);\n    for (let d = 0; d < an; d++)\n      h[an - 1 - d] = d === p ? 1 << a - p * Vi : 0;\n    return new c(h)\n  }\n  and({parts: a}) {\n    return new c(this.parts.map((h,p)=>h & a[p]))\n  }\n  or({parts: a}) {\n    return new c(this.parts.map((h,p)=>h | a[p]))\n  }\n  xor({parts: a}) {\n    return new c(this.parts.map((h,p)=>h ^ a[p]))\n  }\n  not() {\n    return new c(this.parts.map(a=>~a))\n  }\n  equals({parts: a}) {\n    return this.parts.every((h,p)=>h === a[p])\n  }\n  toString() {\n    if (this.str != null)\n      return this.str;\n    let a = new Array(Yr / 4);\n    return this.parts.forEach((h,p)=>{\n        let d = $r(h.toString());\n        for (let M = 0; M < 4; M++)\n          a[M + p * 4] = d[4 - 1 - M] || 0\n      }\n    ),\n      this.str = Qa.fromArray(a, 16).toString()\n  }\n  toJSON() {\n    return this.toString()\n  }\n}\n  , ln = eo();\nln && BigInt.prototype.toJSON == null && (BigInt.prototype.toJSON = function() {\n    return this.toString()\n  }\n);\nvar si = {}\n  , Wr = ln ? function(a) {\n      return BigInt(a)\n    }\n    : function(a) {\n      return a instanceof Hn ? a : (typeof a == \"number\" && (a = a.toString()),\n      si[a] != null || (si[a] = Hn.fromString(a)),\n        si[a])\n    }\n  , St = Wr(0)\n  , gi = ln ? function(a=St, h=St) {\n      return a & h\n    }\n    : function(a=St, h=St) {\n      return a.and(h)\n    }\n  , Jr = ln ? function(a=St, h=St) {\n      return a | h\n    }\n    : function(a=St, h=St) {\n      return a.or(h)\n    }\n  , io = ln ? function(a=St, h=St) {\n      return a ^ h\n    }\n    : function(a=St, h=St) {\n      return a.xor(h)\n    }\n  , ro = ln ? function(a=St) {\n      return ~a\n    }\n    : function(a=St) {\n      return a.not()\n    }\n  , Xi = ln ? function(a, h) {\n      return a === h\n    }\n    : function(a, h) {\n      return a == null || h == null ? a == h : a.equals(h)\n    }\n;\nfunction so(...c) {\n  let a = c[0];\n  for (let h = 1; h < c.length; h++)\n    a = Jr(a, c[h]);\n  return a\n}\nfunction ao(c, a) {\n  return Xi(gi(c, a), a)\n}\nfunction oo(c, a) {\n  return !Xi(gi(c, a), St)\n}\nfunction uo(c, a) {\n  return a === St ? c : Jr(c, a)\n}\nfunction lo(c, a) {\n  return a === St ? c : io(c, gi(c, a))\n}\nvar ho = ln ? function(a) {\n    return BigInt(1) << BigInt(a)\n  }\n  : function(a) {\n    return Hn.fromBit(a)\n  }\n  , co = {\n  combine: so,\n  add: uo,\n  remove: lo,\n  filter: gi,\n  invert: ro,\n  has: ao,\n  hasAny: oo,\n  equals: Xi,\n  deserialize: Wr,\n  getFlag: ho\n}, ci;\n(function(c) {\n    c[c.CLOSE_NORMAL = 1e3] = \"CLOSE_NORMAL\",\n      c[c.CLOSE_UNSUPPORTED = 1003] = \"CLOSE_UNSUPPORTED\",\n      c[c.CLOSE_ABNORMAL = 1006] = \"CLOSE_ABNORMAL\",\n      c[c.INVALID_CLIENTID = 4e3] = \"INVALID_CLIENTID\",\n      c[c.INVALID_ORIGIN = 4001] = \"INVALID_ORIGIN\",\n      c[c.RATELIMITED = 4002] = \"RATELIMITED\",\n      c[c.TOKEN_REVOKED = 4003] = \"TOKEN_REVOKED\",\n      c[c.INVALID_VERSION = 4004] = \"INVALID_VERSION\",\n      c[c.INVALID_ENCODING = 4005] = \"INVALID_ENCODING\"\n  }\n)(ci || (ci = {}));\nvar jn;\n(function(c) {\n    c[c.INVALID_PAYLOAD = 4e3] = \"INVALID_PAYLOAD\",\n      c[c.INVALID_COMMAND = 4002] = \"INVALID_COMMAND\",\n      c[c.INVALID_EVENT = 4004] = \"INVALID_EVENT\",\n      c[c.INVALID_PERMISSIONS = 4006] = \"INVALID_PERMISSIONS\"\n  }\n)(jn || (jn = {}));\nvar Fi;\n(function(c) {\n    c.LANDSCAPE = \"landscape\",\n      c.PORTRAIT = \"portrait\"\n  }\n)(Fi || (Fi = {}));\nvar gn;\n(function(c) {\n    c.MOBILE = \"mobile\",\n      c.DESKTOP = \"desktop\"\n  }\n)(gn || (gn = {}));\nvar ju = Object.freeze({\n  CREATE_INSTANT_INVITE: co.getFlag(0)\n});\nfunction pt(c) {\n  return qr(a=>{\n      var h;\n      let[p] = (h = Object.entries(c).find(([,d])=>d === a)) !== null && h !== void 0 ? h : [];\n      return a != null && p === void 0 ? c.UNHANDLED : a\n    }\n    , j().or(fe()))\n}\nvar Xr = \"DISPATCH\", ge;\n(function(c) {\n    c.AUTHORIZE = \"AUTHORIZE\",\n      c.AUTHENTICATE = \"AUTHENTICATE\",\n      c.GET_GUILDS = \"GET_GUILDS\",\n      c.GET_GUILD = \"GET_GUILD\",\n      c.GET_CHANNEL = \"GET_CHANNEL\",\n      c.GET_CHANNELS = \"GET_CHANNELS\",\n      c.SET_USER_VOICE_SETTINGS = \"SET_USER_VOICE_SETTINGS\",\n      c.SELECT_VOICE_CHANNEL = \"SELECT_VOICE_CHANNEL\",\n      c.GET_SELECTED_VOICE_CHANNEL = \"GET_SELECTED_VOICE_CHANNEL\",\n      c.SELECT_TEXT_CHANNEL = \"SELECT_TEXT_CHANNEL\",\n      c.GET_VOICE_SETTINGS = \"GET_VOICE_SETTINGS\",\n      c.SET_VOICE_SETTINGS = \"SET_VOICE_SETTINGS\",\n      c.SUBSCRIBE = \"SUBSCRIBE\",\n      c.UNSUBSCRIBE = \"UNSUBSCRIBE\",\n      c.CAPTURE_SHORTCUT = \"CAPTURE_SHORTCUT\",\n      c.SET_CERTIFIED_DEVICES = \"SET_CERTIFIED_DEVICES\",\n      c.SET_ACTIVITY = \"SET_ACTIVITY\",\n      c.GET_SKUS = \"GET_SKUS\",\n      c.GET_ENTITLEMENTS = \"GET_ENTITLEMENTS\",\n      c.GET_SKUS_EMBEDDED = \"GET_SKUS_EMBEDDED\",\n      c.GET_ENTITLEMENTS_EMBEDDED = \"GET_ENTITLEMENTS_EMBEDDED\",\n      c.START_PURCHASE = \"START_PURCHASE\",\n      c.START_PREMIUM_PURCHASE = \"START_PREMIUM_PURCHASE\",\n      c.SET_CONFIG = \"SET_CONFIG\",\n      c.SEND_ANALYTICS_EVENT = \"SEND_ANALYTICS_EVENT\",\n      c.USER_SETTINGS_GET_LOCALE = \"USER_SETTINGS_GET_LOCALE\",\n      c.OPEN_EXTERNAL_LINK = \"OPEN_EXTERNAL_LINK\",\n      c.ENCOURAGE_HW_ACCELERATION = \"ENCOURAGE_HW_ACCELERATION\",\n      c.CAPTURE_LOG = \"CAPTURE_LOG\",\n      c.SET_ORIENTATION_LOCK_STATE = \"SET_ORIENTATION_LOCK_STATE\",\n      c.OPEN_INVITE_DIALOG = \"OPEN_INVITE_DIALOG\",\n      c.GET_PLATFORM_BEHAVIORS = \"GET_PLATFORM_BEHAVIORS\",\n      c.GET_CHANNEL_PERMISSIONS = \"GET_CHANNEL_PERMISSIONS\",\n      c.OPEN_SHARE_MOMENT_DIALOG = \"OPEN_SHARE_MOMENT_DIALOG\",\n      c.INITIATE_IMAGE_UPLOAD = \"INITIATE_IMAGE_UPLOAD\"\n  }\n)(ge || (ge = {}));\nvar Dn = he({\n  cmd: j(),\n  data: Zn(),\n  evt: Wi(),\n  nonce: j()\n}).passthrough()\n  , Qr = {\n  UNHANDLED: -1,\n  bot: \"bot\",\n  rpc: \"rpc\",\n  identify: \"identify\",\n  connections: \"connections\",\n  email: \"email\",\n  guilds: \"guilds\",\n  \"guilds.join\": \"guilds.join\",\n  \"guilds.members.read\": \"guilds.members.read\",\n  \"gdm.join\": \"gdm.join\",\n  \"messages.read\": \"messages.read\",\n  \"rpc.notifications.read\": \"rpc.notifications.read\",\n  \"rpc.voice.write\": \"rpc.voice.write\",\n  \"rpc.voice.read\": \"rpc.voice.read\",\n  \"rpc.activities.write\": \"rpc.activities.write\",\n  \"webhook.incoming\": \"webhook.incoming\",\n  \"applications.builds.upload\": \"applications.builds.upload\",\n  \"applications.builds.read\": \"applications.builds.read\",\n  \"applications.store.update\": \"applications.store.update\",\n  \"applications.entitlements\": \"applications.entitlements\",\n  \"relationships.read\": \"relationships.read\",\n  \"activities.read\": \"activities.read\",\n  \"activities.write\": \"activities.write\"\n}\n  , es = pt(Qr)\n  , qt = he({\n  id: j(),\n  username: j(),\n  discriminator: j(),\n  avatar: j().optional().nullable(),\n  publicFlags: fe().optional().nullable()\n})\n  , vi = he({\n  user: qt,\n  nick: j().optional().nullable(),\n  roles: Be(j()),\n  joined_at: j(),\n  deaf: Ae(),\n  mute: Ae()\n})\n  , mi = he({\n  id: j(),\n  name: j().optional().nullable(),\n  roles: Be(j()).optional().nullable(),\n  user: qt.optional().nullable(),\n  require_colons: Ae().optional().nullable(),\n  managed: Ae().optional().nullable(),\n  animated: Ae().optional().nullable(),\n  available: Ae().optional().nullable()\n})\n  , yi = he({\n  mute: Ae(),\n  deaf: Ae(),\n  self_mute: Ae(),\n  self_deaf: Ae(),\n  suppress: Ae()\n})\n  , ts = he({\n  mute: Ae(),\n  nick: j(),\n  user: qt,\n  voice_state: yi,\n  volume: fe()\n})\n  , ns = {\n  UNHANDLED: -1,\n  IDLE: \"idle\",\n  DND: \"dnd\",\n  ONLINE: \"online\",\n  OFFLINE: \"offline\"\n}\n  , Un = pt(ns)\n  , xn = he({\n  name: j(),\n  type: fe(),\n  url: j().optional().nullable(),\n  created_at: fe().optional().nullable(),\n  timestamps: he({\n    start: fe(),\n    end: fe()\n  }).partial().optional().nullable(),\n  application_id: j().optional().nullable(),\n  details: j().optional().nullable(),\n  state: j().optional().nullable(),\n  emoji: mi.optional().nullable(),\n  party: he({\n    id: j().optional().nullable(),\n    size: Be(fe()).optional().nullable()\n  }).optional().nullable(),\n  assets: he({\n    large_image: j().nullable(),\n    large_text: j().nullable(),\n    small_image: j().nullable(),\n    small_text: j().nullable()\n  }).partial().optional().nullable(),\n  secrets: he({\n    join: j(),\n    match: j()\n  }).partial().optional().nullable(),\n  instance: Ae().optional().nullable(),\n  flags: fe().optional().nullable()\n})\n  , is = {\n  UNHANDLED: -1,\n  ROLE: 0,\n  MEMBER: 1\n}\n  , rs = he({\n  id: j(),\n  type: pt(is),\n  allow: j(),\n  deny: j()\n})\n  , wi = {\n  UNHANDLED: -1,\n  DM: 1,\n  GROUP_DM: 3,\n  GUILD_TEXT: 0,\n  GUILD_VOICE: 2,\n  GUILD_CATEGORY: 4,\n  GUILD_ANNOUNCEMENT: 5,\n  GUILD_STORE: 6,\n  ANNOUNCEMENT_THREAD: 10,\n  PUBLIC_THREAD: 11,\n  PRIVATE_THREAD: 12,\n  GUILD_STAGE_VOICE: 13,\n  GUILD_DIRECTORY: 14,\n  GUILD_FORUM: 15\n}\n  , Qi = he({\n  id: j(),\n  type: pt(wi),\n  guild_id: j().optional().nullable(),\n  position: fe().optional().nullable(),\n  permission_overwrites: Be(rs).optional().nullable(),\n  name: j().optional().nullable(),\n  topic: j().optional().nullable(),\n  nsfw: Ae().optional().nullable(),\n  last_message_id: j().optional().nullable(),\n  bitrate: fe().optional().nullable(),\n  user_limit: fe().optional().nullable(),\n  rate_limit_per_user: fe().optional().nullable(),\n  recipients: Be(qt).optional().nullable(),\n  icon: j().optional().nullable(),\n  owner_id: j().optional().nullable(),\n  application_id: j().optional().nullable(),\n  parent_id: j().optional().nullable(),\n  last_pin_timestamp: j().optional().nullable()\n})\n  , ss = he({\n  user: qt,\n  guild_id: j(),\n  status: Un,\n  activities: Be(xn),\n  client_status: he({\n    desktop: Un,\n    mobile: Un,\n    web: Un\n  }).partial()\n})\n  , as = he({\n  id: j(),\n  name: j(),\n  color: fe(),\n  hoist: Ae(),\n  position: fe(),\n  permissions: j(),\n  managed: Ae(),\n  mentionable: Ae()\n})\n  , os = he({\n  id: j(),\n  name: j(),\n  owner_id: j(),\n  icon: j().nullable(),\n  icon_hash: j().optional().nullable(),\n  splash: j().nullable(),\n  discovery_splash: j().nullable(),\n  owner: Ae().optional().nullable(),\n  permissions: j().optional().nullable(),\n  region: j(),\n  afk_channel_id: j().nullable(),\n  afk_timeout: fe(),\n  widget_enabled: Ae().optional().nullable(),\n  widget_channel_id: j().optional().nullable(),\n  verification_level: fe(),\n  default_message_notifications: fe(),\n  explicit_content_filter: fe(),\n  roles: Be(as),\n  emojis: Be(mi),\n  features: Be(j()),\n  mfa_level: fe(),\n  application_id: j().nullable(),\n  system_channel_id: j().nullable(),\n  system_channel_flags: fe(),\n  rules_channel_id: j().nullable(),\n  joined_at: j().optional().nullable(),\n  large: Ae().optional().nullable(),\n  unavailable: Ae().optional().nullable(),\n  member_count: fe().optional().nullable(),\n  voice_states: Be(yi).optional().nullable(),\n  members: Be(vi).optional().nullable(),\n  channels: Be(Qi).optional().nullable(),\n  presences: Be(ss).optional().nullable(),\n  max_presences: fe().optional().nullable(),\n  max_members: fe().optional().nullable(),\n  vanity_url_code: j().nullable(),\n  description: j().nullable(),\n  banner: j().nullable(),\n  premium_tier: fe(),\n  premium_subscription_count: fe().optional().nullable(),\n  preferred_locale: j(),\n  public_updates_channel_id: j().nullable(),\n  max_video_channel_users: fe().optional().nullable(),\n  approximate_member_count: fe().optional().nullable(),\n  approximate_presence_count: fe().optional().nullable()\n})\n  , us = he({\n  id: j(),\n  guild_id: j(),\n  type: fe(),\n  name: j()\n})\n  , ls = he({\n  id: j(),\n  filename: j(),\n  size: fe(),\n  url: j(),\n  proxy_url: j(),\n  height: fe().optional().nullable(),\n  width: fe().optional().nullable()\n})\n  , hs = he({\n  text: j(),\n  icon_url: j().optional().nullable(),\n  proxy_icon_url: j().optional().nullable()\n})\n  , fi = he({\n  url: j().optional().nullable(),\n  proxy_url: j().optional().nullable(),\n  height: fe().optional().nullable(),\n  width: fe().optional().nullable()\n})\n  , cs = fi.omit({\n  proxy_url: !0\n})\n  , fs = he({\n  name: j().optional().nullable(),\n  url: j().optional().nullable()\n})\n  , ds = he({\n  name: j().optional().nullable(),\n  url: j().optional().nullable(),\n  icon_url: j().optional().nullable(),\n  proxy_icon_url: j().optional().nullable()\n})\n  , ps = he({\n  name: j(),\n  value: j(),\n  inline: Ae()\n})\n  , _s = he({\n  title: j().optional().nullable(),\n  type: j().optional().nullable(),\n  description: j().optional().nullable(),\n  url: j().optional().nullable(),\n  timestamp: j().optional().nullable(),\n  color: fe().optional().nullable(),\n  footer: hs.optional().nullable(),\n  image: fi.optional().nullable(),\n  thumbnail: fi.optional().nullable(),\n  video: cs.optional().nullable(),\n  provider: fs.optional().nullable(),\n  author: ds.optional().nullable(),\n  fields: Be(ps).optional().nullable()\n})\n  , gs = he({\n  count: fe(),\n  me: Ae(),\n  emoji: mi\n})\n  , vs = he({\n  type: fe(),\n  party_id: j().optional().nullable()\n})\n  , ms = he({\n  id: j(),\n  cover_image: j().optional().nullable(),\n  description: j(),\n  icon: j().optional().nullable(),\n  name: j()\n})\n  , ys = he({\n  message_id: j().optional().nullable(),\n  channel_id: j().optional().nullable(),\n  guild_id: j().optional().nullable()\n})\n  , bi = he({\n  id: j(),\n  channel_id: j(),\n  guild_id: j().optional().nullable(),\n  author: qt.optional().nullable(),\n  member: vi.optional().nullable(),\n  content: j(),\n  timestamp: j(),\n  edited_timestamp: j().optional().nullable(),\n  tts: Ae(),\n  mention_everyone: Ae(),\n  mentions: Be(qt),\n  mention_roles: Be(j()),\n  mention_channels: Be(us),\n  attachments: Be(ls),\n  embeds: Be(_s),\n  reactions: Be(gs).optional().nullable(),\n  nonce: Ji([j(), fe()]).optional().nullable(),\n  pinned: Ae(),\n  webhook_id: j().optional().nullable(),\n  type: fe(),\n  activity: vs.optional().nullable(),\n  application: ms.optional().nullable(),\n  message_reference: ys.optional().nullable(),\n  flags: fe().optional().nullable(),\n  stickers: Be(Zn()).optional().nullable(),\n  referenced_message: Zn().optional().nullable()\n})\n  , ws = he({\n  id: j(),\n  name: j()\n})\n  , bs = {\n  UNHANDLED: -1,\n  KEYBOARD_KEY: 0,\n  MOUSE_BUTTON: 1,\n  KEYBOARD_MODIFIER_KEY: 2,\n  GAMEPAD_BUTTON: 3\n}\n  , Si = he({\n  type: pt(bs),\n  code: fe(),\n  name: j()\n})\n  , Ss = {\n  UNHANDLED: -1,\n  PUSH_TO_TALK: \"PUSH_TO_TALK\",\n  VOICE_ACTIVITY: \"VOICE_ACTIVITY\"\n}\n  , Es = he({\n  type: pt(Ss),\n  auto_threshold: Ae(),\n  threshold: fe(),\n  shortcut: Be(Si),\n  delay: fe()\n})\n  , Gi = he({\n  device_id: j(),\n  volume: fe(),\n  available_devices: Be(ws)\n})\n  , Ts = {\n  UNHANDLED: -1,\n  AUDIO_INPUT: \"AUDIO_INPUT\",\n  AUDIO_OUTPUT: \"AUDIO_OUTPUT\",\n  VIDEO_INPUT: \"VIDEO_INPUT\"\n}\n  , fo = he({\n  type: pt(Ts),\n  id: j(),\n  vendor: he({\n    name: j(),\n    url: j()\n  }),\n  model: he({\n    name: j(),\n    url: j()\n  }),\n  related: Be(j()),\n  echo_cancellation: Ae().optional().nullable(),\n  noise_suppression: Ae().optional().nullable(),\n  automatic_gain_control: Ae().optional().nullable(),\n  hardware_mute: Ae().optional().nullable()\n})\n  , Is = {\n  UNHANDLED: -1,\n  APPLICATION: 1,\n  DLC: 2,\n  CONSUMABLE: 3,\n  BUNDLE: 4,\n  SUBSCRIPTION: 5\n}\n  , Cs = he({\n  id: j(),\n  name: j(),\n  type: pt(Is),\n  price: he({\n    amount: fe(),\n    currency: j()\n  }),\n  application_id: j(),\n  flags: fe(),\n  release_date: j().nullable()\n})\n  , As = {\n  UNHANDLED: -1,\n  PURCHASE: 1,\n  PREMIUM_SUBSCRIPTION: 2,\n  DEVELOPER_GIFT: 3,\n  TEST_MODE_PURCHASE: 4,\n  FREE_PURCHASE: 5,\n  USER_GIFT: 6,\n  PREMIUM_PURCHASE: 7\n}\n  , Ei = he({\n  id: j(),\n  sku_id: j(),\n  application_id: j(),\n  user_id: j(),\n  gift_code_flags: fe(),\n  type: pt(As),\n  gifter_user_id: j().optional().nullable(),\n  branches: Be(j()).optional().nullable(),\n  starts_at: j().optional().nullable(),\n  ends_at: j().optional().nullable(),\n  parent_id: j().optional().nullable(),\n  consumed: Ae().optional().nullable(),\n  deleted: Ae().optional().nullable(),\n  gift_code_batch_id: j().optional().nullable()\n})\n  , Ps = {\n  UNHANDLED: -1,\n  UNLOCKED: 1,\n  PORTRAIT: 2,\n  LANDSCAPE: 3\n}\n  , po = pt(Ps)\n  , Os = {\n  UNHANDLED: -1,\n  NOMINAL: 0,\n  FAIR: 1,\n  SERIOUS: 2,\n  CRITICAL: 3\n}\n  , xs = pt(Os)\n  , er = {\n  UNHANDLED: -1,\n  PORTRAIT: 0,\n  LANDSCAPE: 1\n}\n  , _o = pt(er)\n  , qn = {\n  UNHANDLED: -1,\n  FOCUSED: 0,\n  PIP: 1,\n  GRID: 2\n}\n  , go = pt(qn)\n  , vo = Object.freeze({\n  __proto__: null,\n  DISPATCH: Xr,\n  get Commands() {\n    return ge\n  },\n  ReceiveFramePayload: Dn,\n  ScopesObject: Qr,\n  Scopes: es,\n  User: qt,\n  GuildMember: vi,\n  Emoji: mi,\n  VoiceState: yi,\n  UserVoiceState: ts,\n  StatusObject: ns,\n  Status: Un,\n  Activity: xn,\n  PermissionOverwriteTypeObject: is,\n  PermissionOverwrite: rs,\n  ChannelTypesObject: wi,\n  Channel: Qi,\n  PresenceUpdate: ss,\n  Role: as,\n  Guild: os,\n  ChannelMention: us,\n  Attachment: ls,\n  EmbedFooter: hs,\n  Image: fi,\n  Video: cs,\n  EmbedProvider: fs,\n  EmbedAuthor: ds,\n  EmbedField: ps,\n  Embed: _s,\n  Reaction: gs,\n  MessageActivity: vs,\n  MessageApplication: ms,\n  MessageReference: ys,\n  Message: bi,\n  VoiceDevice: ws,\n  KeyTypesObject: bs,\n  ShortcutKey: Si,\n  VoiceSettingModeTypeObject: Ss,\n  VoiceSettingsMode: Es,\n  VoiceSettingsIO: Gi,\n  CertifiedDeviceTypeObject: Ts,\n  CertifiedDevice: fo,\n  SkuTypeObject: Is,\n  Sku: Cs,\n  EntitlementTypesObject: As,\n  Entitlement: Ei,\n  OrientationLockStateTypeObject: Ps,\n  OrientationLockState: po,\n  ThermalStateTypeObject: Os,\n  ThermalState: xs,\n  OrientationTypeObject: er,\n  Orientation: _o,\n  LayoutModeTypeObject: qn,\n  LayoutMode: go\n})\n  , mn = he({}).nullable()\n  , Ns = he({\n  code: j()\n})\n  , Ls = he({\n  access_token: j(),\n  user: he({\n    username: j(),\n    discriminator: j(),\n    id: j(),\n    avatar: j().nullable(),\n    public_flags: fe()\n  }),\n  scopes: Be(es),\n  expires: j(),\n  application: he({\n    description: j(),\n    icon: j().nullable(),\n    id: j(),\n    rpc_origins: Be(j()).optional(),\n    name: j()\n  })\n})\n  , mo = he({\n  guilds: Be(he({\n    id: j(),\n    name: j()\n  }))\n})\n  , yo = he({\n  id: j(),\n  name: j(),\n  icon_url: j().optional(),\n  members: Be(vi)\n})\n  , Kn = he({\n  id: j(),\n  type: pt(wi),\n  guild_id: j().optional().nullable(),\n  name: j().optional().nullable(),\n  topic: j().optional().nullable(),\n  bitrate: fe().optional().nullable(),\n  user_limit: fe().optional().nullable(),\n  position: fe().optional().nullable(),\n  voice_states: Be(ts),\n  messages: Be(bi)\n})\n  , wo = he({\n  channels: Be(Qi)\n})\n  , Ms = he({\n  user_id: j(),\n  pan: he({\n    left: fe(),\n    right: fe()\n  }).optional(),\n  volume: fe().optional(),\n  mute: Ae().optional()\n})\n  , qu = Kn.nullable()\n  , bo = Kn.nullable()\n  , Rs = Kn.nullable()\n  , So = Kn.nullable()\n  , tr = he({\n  input: Gi,\n  output: Gi,\n  mode: Es,\n  automatic_gain_control: Ae(),\n  echo_cancellation: Ae(),\n  noise_suppression: Ae(),\n  qos: Ae(),\n  silence_warning: Ae(),\n  deaf: Ae(),\n  mute: Ae()\n})\n  , Eo = he({\n  evt: j()\n})\n  , To = he({\n  shortcut: Si\n})\n  , Ds = xn\n  , ks = he({\n  skus: Be(Cs)\n})\n  , Bs = he({\n  entitlements: Be(Ei)\n})\n  , Us = Be(Ei).nullable()\n  , zs = he({\n  use_interactive_pip: Ae()\n})\n  , Vs = he({\n  locale: j()\n})\n  , Fs = he({\n  enabled: Ae()\n})\n  , Gs = he({\n  permissions: Hr().or(j())\n})\n  , Zs = he({\n  image_url: j()\n}).nullable()\n  , Hs = he({\n  iosKeyboardResizesView: jr(Ae())\n})\n  , Io = Dn.extend({\n  cmd: Rn(ge),\n  evt: Wi()\n});\nfunction Co({cmd: c, data: a}) {\n  switch (c) {\n    case ge.AUTHENTICATE:\n      return Ls.parse(a);\n    case ge.AUTHORIZE:\n      return Ns.parse(a);\n    case ge.CAPTURE_SHORTCUT:\n      return To.parse(a);\n    case ge.ENCOURAGE_HW_ACCELERATION:\n      return Fs.parse(a);\n    case ge.GET_CHANNEL:\n      return Kn.parse(a);\n    case ge.GET_CHANNELS:\n      return wo.parse(a);\n    case ge.GET_CHANNEL_PERMISSIONS:\n      return Gs.parse(a);\n    case ge.GET_GUILD:\n      return yo.parse(a);\n    case ge.GET_GUILDS:\n      return mo.parse(a);\n    case ge.GET_PLATFORM_BEHAVIORS:\n      return Hs.parse(a);\n    case ge.GET_SELECTED_VOICE_CHANNEL:\n      return Rs.parse(a);\n    case ge.GET_VOICE_SETTINGS:\n    case ge.SET_VOICE_SETTINGS:\n      return tr.parse(a);\n    case ge.SELECT_TEXT_CHANNEL:\n      return So.parse(a);\n    case ge.SELECT_VOICE_CHANNEL:\n      return bo.parse(a);\n    case ge.SET_ACTIVITY:\n      return Ds.parse(a);\n    case ge.GET_SKUS_EMBEDDED:\n      return ks.parse(a);\n    case ge.GET_ENTITLEMENTS_EMBEDDED:\n      return Bs.parse(a);\n    case ge.SET_CONFIG:\n      return zs.parse(a);\n    case ge.SET_USER_VOICE_SETTINGS:\n      return Ms.parse(a);\n    case ge.START_PURCHASE:\n      return Us.parse(a);\n    case ge.SUBSCRIBE:\n    case ge.UNSUBSCRIBE:\n      return Eo.parse(a);\n    case ge.USER_SETTINGS_GET_LOCALE:\n      return Vs.parse(a);\n    case ge.INITIATE_IMAGE_UPLOAD:\n      return Zs.parse(a);\n    case ge.START_PREMIUM_PURCHASE:\n    case ge.OPEN_EXTERNAL_LINK:\n    case ge.SET_ORIENTATION_LOCK_STATE:\n    case ge.SET_CERTIFIED_DEVICES:\n    case ge.SEND_ANALYTICS_EVENT:\n    case ge.OPEN_INVITE_DIALOG:\n    case ge.CAPTURE_LOG:\n    case ge.OPEN_SHARE_MOMENT_DIALOG:\n      return mn.parse(a);\n    default:\n      throw new Error(`Unrecognized command ${c}`)\n  }\n}\nfunction Ao(c) {\n  return Object.assign(Object.assign({}, c), {\n    data: Co(c)\n  })\n}\nvar nr = \"ERROR\", _e;\n(function(c) {\n    c.READY = \"READY\",\n      c.GUILD_STATUS = \"GUILD_STATUS\",\n      c.GUILD_CREATE = \"GUILD_CREATE\",\n      c.CHANNEL_CREATE = \"CHANNEL_CREATE\",\n      c.VOICE_CHANNEL_SELECT = \"VOICE_CHANNEL_SELECT\",\n      c.VOICE_SETTINGS_UPDATE = \"VOICE_SETTINGS_UPDATE\",\n      c.VOICE_STATE_CREATE = \"VOICE_STATE_CREATE\",\n      c.VOICE_STATE_UPDATE = \"VOICE_STATE_UPDATE\",\n      c.VOICE_STATE_DELETE = \"VOICE_STATE_DELETE\",\n      c.VOICE_CONNECTION_STATUS = \"VOICE_CONNECTION_STATUS\",\n      c.MESSAGE_CREATE = \"MESSAGE_CREATE\",\n      c.MESSAGE_UPDATE = \"MESSAGE_UPDATE\",\n      c.MESSAGE_DELETE = \"MESSAGE_DELETE\",\n      c.SPEAKING_START = \"SPEAKING_START\",\n      c.SPEAKING_STOP = \"SPEAKING_STOP\",\n      c.NOTIFICATION_CREATE = \"NOTIFICATION_CREATE\",\n      c.CAPTURE_SHORTCUT_CHANGE = \"CAPTURE_SHORTCUT_CHANGE\",\n      c.ACTIVITY_JOIN = \"ACTIVITY_JOIN\",\n      c.ACTIVITY_JOIN_REQUEST = \"ACTIVITY_JOIN_REQUEST\",\n      c.ACTIVITY_PIP_MODE_UPDATE = \"ACTIVITY_PIP_MODE_UPDATE\",\n      c.ACTIVITY_LAYOUT_MODE_UPDATE = \"ACTIVITY_LAYOUT_MODE_UPDATE\",\n      c.ORIENTATION_UPDATE = \"ORIENTATION_UPDATE\",\n      c.CURRENT_USER_UPDATE = \"CURRENT_USER_UPDATE\",\n      c.ENTITLEMENT_CREATE = \"ENTITLEMENT_CREATE\",\n      c.THERMAL_STATE_UPDATE = \"THERMAL_STATE_UPDATE\"\n  }\n)(_e || (_e = {}));\nvar js = Dn.extend({\n  evt: zt(nr),\n  data: he({\n    code: fe(),\n    message: j().optional()\n  }).passthrough(),\n  cmd: Rn(ge),\n  nonce: j().nullable()\n})\n  , ir = Dn.extend({\n  evt: Rn(_e),\n  nonce: j().nullable(),\n  cmd: zt(Xr),\n  data: he({}).passthrough()\n})\n  , Po = ir.extend({\n  evt: j()\n})\n  , Oo = Ji([ir, Po, js]);\nfunction at(c, a) {\n  return ir.extend({\n    evt: zt(c),\n    data: he(a)\n  })\n}\nvar xo = at(_e.READY, {\n  v: fe(),\n  config: he({\n    cdn_host: j().optional(),\n    api_endpoint: j(),\n    environment: j()\n  }),\n  user: he({\n    id: j(),\n    username: j(),\n    discriminator: j(),\n    avatar: j().optional()\n  }).optional()\n})\n  , No = at(_e.GUILD_STATUS, {\n  guild: os,\n  online: fe().optional()\n})\n  , Lo = at(_e.GUILD_CREATE, {\n  id: j(),\n  name: j()\n})\n  , Mo = at(_e.CHANNEL_CREATE, {\n  id: j(),\n  name: j(),\n  type: pt(wi)\n})\n  , Ro = at(_e.VOICE_CHANNEL_SELECT, {\n  channel_id: j().nullable(),\n  guild_id: j().nullable().optional()\n})\n  , Do = at(_e.VOICE_STATE_UPDATE, {\n  data: tr\n})\n  , rr = at(_e.VOICE_STATE_CREATE, {\n  voice_state: yi,\n  user: qt,\n  nick: j(),\n  volume: fe(),\n  mute: Ae(),\n  pan: he({\n    left: fe(),\n    right: fe()\n  })\n})\n  , ko = rr.extend({\n  evt: zt(_e.VOICE_STATE_UPDATE)\n})\n  , Bo = rr.extend({\n  evt: zt(_e.VOICE_STATE_DELETE)\n})\n  , Uo = {\n  UNHANDLED: -1,\n  DISCONNECTED: \"DISCONNECTED\",\n  AWAITING_ENDPOINT: \"AWAITING_ENDPOINT\",\n  AUTHENTICATING: \"AUTHENTICATING\",\n  CONNECTING: \"CONNECTING\",\n  CONNECTED: \"CONNECTED\",\n  VOICE_DISCONNECTED: \"VOICE_DISCONNECTED\",\n  VOICE_CONNECTING: \"VOICE_CONNECTING\",\n  VOICE_CONNECTED: \"VOICE_CONNECTED\",\n  NO_ROUTE: \"NO_ROUTE\",\n  ICE_CHECKING: \"ICE_CHECKING\"\n}\n  , zo = at(_e.VOICE_CONNECTION_STATUS, {\n  state: pt(Uo),\n  hostname: j(),\n  pings: Be(fe()),\n  average_ping: fe(),\n  last_ping: fe()\n})\n  , sr = at(_e.MESSAGE_CREATE, {\n  channel_id: j(),\n  message: bi\n})\n  , Vo = sr.extend({\n  evt: zt(_e.MESSAGE_UPDATE)\n})\n  , Fo = sr.extend({\n  evt: zt(_e.MESSAGE_DELETE)\n})\n  , Go = at(_e.SPEAKING_START, {\n  user_id: j()\n})\n  , Zo = at(_e.SPEAKING_STOP, {\n  user_id: j()\n})\n  , Ho = at(_e.NOTIFICATION_CREATE, {\n  channel_id: j(),\n  message: bi,\n  icon_url: j(),\n  title: j(),\n  body: j()\n})\n  , jo = at(_e.CAPTURE_SHORTCUT_CHANGE, {\n  shortcut: Si\n})\n  , qo = {\n  UNHANDLED: -1,\n  PLAY: 0,\n  SPECTATE: 1\n}\n  , Ko = at(_e.ACTIVITY_JOIN, {\n  secret: j(),\n  intent: pt(qo).optional()\n})\n  , Yo = at(_e.ACTIVITY_JOIN_REQUEST, {\n  user: qt\n})\n  , $o = at(_e.ACTIVITY_PIP_MODE_UPDATE, {\n  is_pip_mode: Ae()\n})\n  , Wo = at(_e.ACTIVITY_LAYOUT_MODE_UPDATE, {\n  layout_mode: pt(qn)\n})\n  , Jo = at(_e.ORIENTATION_UPDATE, {\n  screen_orientation: pt(er),\n  orientation: Rn(Fi)\n})\n  , Xo = at(_e.CURRENT_USER_UPDATE, {\n  avatar: j().optional().nullable(),\n  bot: Ae(),\n  discriminator: j(),\n  flags: fe().optional().nullable(),\n  id: j(),\n  premium_type: fe().optional().nullable(),\n  username: j()\n})\n  , Qo = at(_e.ENTITLEMENT_CREATE, {\n  entitlement: Ei\n})\n  , eu = at(_e.THERMAL_STATE_UPDATE, {\n  thermal_state: xs\n});\nfunction tu(c) {\n  switch (c.evt) {\n    case _e.ACTIVITY_JOIN:\n      return Ko.parse(c);\n    case _e.ACTIVITY_JOIN_REQUEST:\n      return Yo.parse(c);\n    case _e.ACTIVITY_PIP_MODE_UPDATE:\n      return $o.parse(c);\n    case _e.ACTIVITY_LAYOUT_MODE_UPDATE:\n      return Wo.parse(c);\n    case _e.CAPTURE_SHORTCUT_CHANGE:\n      return jo.parse(c);\n    case _e.CHANNEL_CREATE:\n      return Mo.parse(c);\n    case nr:\n      return js.parse(c);\n    case _e.GUILD_CREATE:\n      return Lo.parse(c);\n    case _e.GUILD_STATUS:\n      return No.parse(c);\n    case _e.MESSAGE_CREATE:\n      return sr.parse(c);\n    case _e.MESSAGE_DELETE:\n      return Fo.parse(c);\n    case _e.MESSAGE_UPDATE:\n      return Vo.parse(c);\n    case _e.NOTIFICATION_CREATE:\n      return Ho.parse(c);\n    case _e.ORIENTATION_UPDATE:\n      return Jo.parse(c);\n    case _e.READY:\n      return xo.parse(c);\n    case _e.SPEAKING_START:\n      return Go.parse(c);\n    case _e.SPEAKING_STOP:\n      return Zo.parse(c);\n    case _e.VOICE_CHANNEL_SELECT:\n      return Ro.parse(c);\n    case _e.VOICE_CONNECTION_STATUS:\n      return zo.parse(c);\n    case _e.VOICE_SETTINGS_UPDATE:\n      return Do.parse(c);\n    case _e.VOICE_STATE_CREATE:\n      return rr.parse(c);\n    case _e.VOICE_STATE_DELETE:\n      return Bo.parse(c);\n    case _e.VOICE_STATE_UPDATE:\n      return ko.parse(c);\n    case _e.CURRENT_USER_UPDATE:\n      return Xo.parse(c);\n    case _e.ENTITLEMENT_CREATE:\n      return Qo.parse(c);\n    case _e.THERMAL_STATE_UPDATE:\n      return eu.parse(c);\n    default:\n      throw new Error(`Unrecognized event type ${c.evt}`)\n  }\n}\nhe({\n  frame_id: j(),\n  platform: Rn(gn).optional().nullable()\n});\nhe({\n  v: zt(1),\n  encoding: zt(\"json\").optional(),\n  client_id: j(),\n  frame_id: j()\n});\nvar nu = he({\n  code: fe(),\n  message: j().optional()\n})\n  , iu = he({\n  evt: j().nullable(),\n  nonce: j().nullable(),\n  data: Zn().nullable(),\n  cmd: j()\n}).passthrough();\nfunction ru(c) {\n  let a = iu.parse(c);\n  return a.evt != null ? tu(Oo.parse(a)) : Ao(Io.passthrough().parse(a))\n}\nfunction ht(c, a, h, p=()=>{}\n) {\n  let d = Dn.extend({\n    cmd: zt(a),\n    data: h\n  });\n  return M=>_n(this, void 0, void 0, function*() {\n    let F = yield c({\n      cmd: a,\n      args: M,\n      transfer: p(M)\n    });\n    return d.parse(F).data\n  })\n}\nvar su = c=>ht(c, ge.AUTHENTICATE, Ls)\n  , au = c=>ht(c, ge.AUTHORIZE, Ns)\n  , ou = c=>ht(c, ge.CAPTURE_LOG, mn)\n  , uu = c=>ht(c, ge.ENCOURAGE_HW_ACCELERATION, Fs)\n  , lu = c=>ht(c, ge.GET_ENTITLEMENTS_EMBEDDED, Bs)\n  , hu = c=>ht(c, ge.GET_SELECTED_VOICE_CHANNEL, Rs)\n  , cu = c=>ht(c, ge.GET_SKUS_EMBEDDED, ks)\n  , fu = c=>ht(c, ge.GET_VOICE_SETTINGS, tr)\n  , du = c=>ht(c, ge.GET_CHANNEL_PERMISSIONS, Gs)\n  , pu = c=>ht(c, ge.GET_PLATFORM_BEHAVIORS, Hs)\n  , _u = c=>ht(c, ge.OPEN_EXTERNAL_LINK, mn)\n  , gu = c=>ht(c, ge.OPEN_INVITE_DIALOG, mn)\n  , vu = c=>ht(c, ge.OPEN_SHARE_MOMENT_DIALOG, mn);\nxn.pick({\n  state: !0,\n  details: !0,\n  timestamps: !0,\n  assets: !0,\n  party: !0,\n  secrets: !0,\n  buttons: !0,\n  instance: !0,\n  supported_platforms: !0,\n  type: !0\n}).extend({\n  type: xn.shape.type.optional(),\n  instance: xn.shape.instance.optional()\n}).nullable();\nvar mu = c=>ht(c, ge.SET_ACTIVITY, Ds)\n  , yu = c=>ht(c, ge.SET_CONFIG, zs);\nfunction wu({sendCommand: c, cmd: a, response: h, fallbackTransform: p, transferTransform: d=()=>{}\n            }) {\n  let M = Dn.extend({\n    cmd: zt(a),\n    data: h\n  });\n  return F=>_n(this, void 0, void 0, function*() {\n    try {\n      let Z = yield c({\n        cmd: a,\n        args: F,\n        transfer: d(F)\n      });\n      return M.parse(Z).data\n    } catch (Z) {\n      if (Z.code === jn.INVALID_PAYLOAD) {\n        let q = p(F)\n          , k = yield c({\n          cmd: a,\n          args: q,\n          transfer: d(q)\n        });\n        return M.parse(k).data\n      } else\n        throw Z\n    }\n  })\n}\nvar bu = c=>({\n  lock_state: c.lock_state,\n  picture_in_picture_lock_state: c.picture_in_picture_lock_state\n})\n  , Su = c=>wu({\n  sendCommand: c,\n  cmd: ge.SET_ORIENTATION_LOCK_STATE,\n  response: mn,\n  fallbackTransform: bu\n})\n  , Eu = c=>ht(c, ge.SET_USER_VOICE_SETTINGS, Ms)\n  , Tu = c=>ht(c, ge.START_PREMIUM_PURCHASE, mn)\n  , Iu = c=>ht(c, ge.START_PURCHASE, Us)\n  , Cu = c=>ht(c, ge.USER_SETTINGS_GET_LOCALE, Vs)\n  , Au = c=>ht(c, ge.INITIATE_IMAGE_UPLOAD, Zs);\nfunction Pu(c) {\n  return {\n    authenticate: su(c),\n    authorize: au(c),\n    captureLog: ou(c),\n    encourageHardwareAcceleration: uu(c),\n    getChannelPermissions: du(c),\n    getEntitlements: lu(c),\n    getPlatformBehaviors: pu(c),\n    getSelectedVoiceChannel: hu(c),\n    getSkus: cu(c),\n    getVoiceSettings: fu(c),\n    openExternalLink: _u(c),\n    openInviteDialog: gu(c),\n    openShareMomentDialog: vu(c),\n    setActivity: mu(c),\n    setConfig: yu(c),\n    setOrientationLockState: Su(c),\n    setUserVoiceSettings: Eu(c),\n    startPremiumPurchase: Tu(c),\n    startPurchase: Iu(c),\n    userSettingsGetLocale: Cu(c),\n    initiateImageUpload: Au(c)\n  }\n}\nvar ai, Ou = new Uint8Array(16);\nfunction xu() {\n  if (!ai && (ai = typeof crypto < \"u\" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto < \"u\" && typeof msCrypto.getRandomValues == \"function\" && msCrypto.getRandomValues.bind(msCrypto),\n    !ai))\n    throw new Error(\"crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported\");\n  return ai(Ou)\n}\nvar Nu = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;\nfunction Lu(c) {\n  return typeof c == \"string\" && Nu.test(c)\n}\nvar bt = [];\nfor (oi = 0; oi < 256; ++oi)\n  bt.push((oi + 256).toString(16).substr(1));\nvar oi;\nfunction Mu(c) {\n  var a = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0\n    , h = (bt[c[a + 0]] + bt[c[a + 1]] + bt[c[a + 2]] + bt[c[a + 3]] + \"-\" + bt[c[a + 4]] + bt[c[a + 5]] + \"-\" + bt[c[a + 6]] + bt[c[a + 7]] + \"-\" + bt[c[a + 8]] + bt[c[a + 9]] + \"-\" + bt[c[a + 10]] + bt[c[a + 11]] + bt[c[a + 12]] + bt[c[a + 13]] + bt[c[a + 14]] + bt[c[a + 15]]).toLowerCase();\n  if (!Lu(h))\n    throw TypeError(\"Stringified UUID is invalid\");\n  return h\n}\nfunction Tr(c, a, h) {\n  c = c || {};\n  var p = c.random || (c.rng || xu)();\n  if (p[6] = p[6] & 15 | 64,\n    p[8] = p[8] & 63 | 128,\n    a) {\n    h = h || 0;\n    for (var d = 0; d < 16; ++d)\n      a[h + d] = p[d];\n    return a\n  }\n  return Mu(p)\n}\nvar Zi = class extends Error {\n  constructor(a, h=\"\") {\n    super(h),\n      this.code = a,\n      this.message = h,\n      this.name = \"Discord SDK Error\"\n  }\n}\n  , qs = /\\{([a-z]+)\\}/g;\nfunction Ru(c) {\n  let a = c.replace(qs, (h,p)=>`(?<${p}>[\\\\w-]+)`);\n  return new RegExp(`${a}(/|$)`)\n}\nfunction Du({originalURL: c, prefix: a, prefixHost: h, target: p}) {\n  let d = new URL(`https://${p}`)\n    , M = Ru(d.host)\n    , F = c.toString().match(M);\n  if (F == null)\n    return c;\n  let Z = new URL(c.toString());\n  return Z.host = h,\n    Z.pathname = a.replace(qs, (q,k)=>{\n        var O;\n        let B = (O = F.groups) === null || O === void 0 ? void 0 : O[k];\n        if (B == null)\n          throw new Error(\"Misconfigured route.\");\n        return B\n      }\n    ),\n    Z.pathname += Z.pathname === \"/\" ? c.pathname.slice(1) : c.pathname,\n    Z.pathname = Z.pathname.replace(d.pathname, \"\"),\n    Z.pathname += Z.pathname.endsWith(\"/\") ? \"\" : \"/\",\n    Z\n}\nfunction Di(c, a=window.location.protocol, h=window.location.host) {\n  return c.startsWith(\"/\") ? new URL(`${a}//${h}${c}`) : new URL(c)\n}\nfunction ki({url: c, mappings: a}) {\n  for (let h of a) {\n    let p = Du({\n      originalURL: c,\n      prefix: h.prefix,\n      target: h.target,\n      prefixHost: window.location.host\n    });\n    if (p)\n      return p\n  }\n  return c\n}\nfunction ku(c, a) {\n  let h = window.fetch;\n  window.fetch = function(M, F) {\n    let Z = ki({\n      url: Di(M.toString()),\n      mappings: a\n    });\n    return h(Z.toString(), F)\n  }\n  ;\n  let p = XMLHttpRequest.prototype.open;\n  XMLHttpRequest.prototype.open = function(M, F, Z, q, k) {\n    let O = ki({\n      url: Di(F),\n      mappings: a\n    });\n    p.apply(this, [M, O.toString(), Z, q, k])\n  }\n  ;\n  class d extends WebSocket {\n    constructor(F, Z) {\n      let q = F instanceof URL ? F.toString() : F\n        , k = ki({\n        url: Di(q, \"wss:\"),\n        mappings: a\n      });\n      super(k.toString(), Z)\n    }\n  }\n  window.WebSocket = d\n}\nfunction Bu() {\n  return {\n    disableConsoleLogOverride: !1\n  }\n}\nvar Uu = [\"log\", \"warn\", \"debug\", \"info\", \"error\"];\nfunction zu(c, a, h) {\n  let p = c[a]\n    , d = c;\n  p && (c[a] = function() {\n      let M = [].slice.call(arguments)\n        , F = \"\" + M.join(\" \");\n      h(a, F),\n        p.apply(d, M)\n    }\n  )\n}\nvar Xt;\n(function(c) {\n    c[c.HANDSHAKE = 0] = \"HANDSHAKE\",\n      c[c.FRAME = 1] = \"FRAME\",\n      c[c.CLOSE = 2] = \"CLOSE\",\n      c[c.HELLO = 3] = \"HELLO\"\n  }\n)(Xt || (Xt = {}));\nvar Vu = new Set([window.location.origin, \"https://discord.com\", \"https://discordapp.com\", \"https://ptb.discord.com\", \"https://ptb.discordapp.com\", \"https://canary.discord.com\", \"https://canary.discordapp.com\", \"https://staging.discord.co\", \"http://localhost:3333\", \"https://pax.discord.com\", \"null\"]);\nfunction Fu() {\n  var c;\n  return [(c = window.parent.opener) !== null && c !== void 0 ? c : window.parent, document.referrer ? document.referrer : \"*\"]\n}\nvar di = class {\n    constructor(a, h) {\n      this.eventBus = new Ea,\n        this.source = null,\n        this.sourceOrigin = \"\",\n        this.pendingCommands = new Map,\n        this.layoutModeUpdateListenerMap = new Map,\n        this.sendCommand = Z=>{\n          var q;\n          if (this.source == null)\n            throw new Error(\"Attempting to send message before initialization\");\n          let k = Tr();\n          return (q = this.source) === null || q === void 0 || q.postMessage([Xt.FRAME, Object.assign(Object.assign({}, Z), {\n            nonce: k\n          })], this.sourceOrigin, this.getTransfer(Z)),\n            new Promise((B,C)=>{\n                this.pendingCommands.set(k, {\n                  resolve: B,\n                  reject: C\n                })\n              }\n            )\n        }\n        ,\n        this.commands = Pu(this.sendCommand),\n        this.initializeNetworkShims = ku,\n        this.handleMessage = Z=>{\n          if (!Vu.has(Z.origin))\n            return;\n          let q = Z.data;\n          if (!Array.isArray(q))\n            return;\n          let[k,O] = q;\n          switch (k) {\n            case Xt.HELLO:\n              return;\n            case Xt.CLOSE:\n              return this.handleClose(O);\n            case Xt.HANDSHAKE:\n              return this.handleHandshake();\n            case Xt.FRAME:\n              return this.handleFrame(O);\n            default:\n              throw new Error(\"Invalid message format\")\n          }\n        }\n        ,\n        this.isReady = !1,\n        this.clientId = a,\n        this.configuration = h ?? Bu(),\n        window.addEventListener(\"message\", this.handleMessage);\n      let p = new URLSearchParams(window.location.search)\n        , d = p.get(\"frame_id\");\n      if (!d)\n        throw new Error(\"frame_id query param is not defined\");\n      this.frameId = d;\n      let M = p.get(\"instance_id\");\n      if (!M)\n        throw new Error(\"instance_id query param is not defined\");\n      this.instanceId = M;\n      let F = p.get(\"platform\");\n      if (F) {\n        if (F !== gn.DESKTOP && F !== gn.MOBILE)\n          throw new Error(`Invalid query param \"platform\" of \"${F}\". Valid values are \"${gn.DESKTOP}\" or \"${gn.MOBILE}\"`)\n      } else\n        throw new Error(\"platform query param is not defined\");\n      this.platform = F,\n        this.guildId = p.get(\"guild_id\"),\n        this.channelId = p.get(\"channel_id\"),\n        [this.source,this.sourceOrigin] = Fu(),\n        this.addOnReadyListener(),\n        this.handshake()\n    }\n    getTransfer(a) {\n      var h;\n      switch (a.cmd) {\n        case ge.SUBSCRIBE:\n        case ge.UNSUBSCRIBE:\n          return;\n        default:\n          return (h = a.transfer) !== null && h !== void 0 ? h : void 0\n      }\n    }\n    close(a, h) {\n      var p;\n      window.removeEventListener(\"message\", this.handleMessage);\n      let d = Tr();\n      (p = this.source) === null || p === void 0 || p.postMessage([Xt.CLOSE, {\n        code: a,\n        message: h,\n        nonce: d\n      }], this.sourceOrigin)\n    }\n    subscribe(a, h, p) {\n      return _n(this, void 0, void 0, function*() {\n        let d = this.eventBus.listenerCount(a)\n          , M = this.eventBus.on(a, h);\n        return Object.values(_e).includes(a) && a !== _e.READY && d === 0 && (yield this.sendCommand({\n          cmd: ge.SUBSCRIBE,\n          args: p,\n          evt: a\n        })),\n          M\n      })\n    }\n    unsubscribe(a, h) {\n      return _n(this, void 0, void 0, function*() {\n        return Object.values(_e).includes(a) && a !== _e.READY && this.eventBus.listenerCount(a) === 1 && (yield this.sendCommand({\n          cmd: ge.UNSUBSCRIBE,\n          evt: a\n        })),\n          this.eventBus.off(a, h)\n      })\n    }\n    ready() {\n      return _n(this, void 0, void 0, function*() {\n        this.isReady || (yield new Promise(a=>{\n            this.eventBus.once(_e.READY, a)\n          }\n        ))\n      })\n    }\n    subscribeToLayoutModeUpdatesCompat(a) {\n      return _n(this, void 0, void 0, function*() {\n        let h = M=>{\n            let F = M.is_pip_mode ? qn.PIP : qn.FOCUSED;\n            a({\n              layout_mode: F\n            })\n          }\n          , p = yield this.subscribe(_e.ACTIVITY_PIP_MODE_UPDATE, h)\n          , d = M=>{\n            this.unsubscribe(_e.ACTIVITY_PIP_MODE_UPDATE, h),\n              a(M)\n          }\n        ;\n        this.layoutModeUpdateListenerMap.set(a, {\n          layoutModeListener: d,\n          pipModeListener: h\n        });\n        try {\n          return yield this.subscribe(_e.ACTIVITY_LAYOUT_MODE_UPDATE, d)\n        } catch (M) {\n          if (M.code === jn.INVALID_EVENT)\n            return p;\n          throw M\n        }\n      })\n    }\n    unsubscribeFromLayoutModeUpdatesCompat(a) {\n      return _n(this, void 0, void 0, function*() {\n        let h = this.layoutModeUpdateListenerMap.get(a);\n        if (this.layoutModeUpdateListenerMap.delete(a),\n        h != null) {\n          let {layoutModeListener: p, pipModeListener: d} = h\n            , M = null\n            , F = null;\n          if (p != null)\n            try {\n              M = yield this.unsubscribe(_e.ACTIVITY_LAYOUT_MODE_UPDATE, p)\n            } catch (Z) {\n              if (Z.code !== jn.INVALID_EVENT)\n                throw Z\n            }\n          return d != null && (F = yield this.unsubscribe(_e.ACTIVITY_PIP_MODE_UPDATE, d)),\n          M ?? F\n        }\n      })\n    }\n    handshake() {\n      var a;\n      (a = this.source) === null || a === void 0 || a.postMessage([Xt.HANDSHAKE, {\n        v: 1,\n        encoding: \"json\",\n        client_id: this.clientId,\n        frame_id: this.frameId\n      }], this.sourceOrigin)\n    }\n    addOnReadyListener() {\n      this.eventBus.once(_e.READY, ()=>{\n          this.overrideConsoleLogging(),\n            this.isReady = !0\n        }\n      )\n    }\n    overrideConsoleLogging() {\n      if (this.configuration.disableConsoleLogOverride)\n        return;\n      let a = (h,p)=>{\n          this.commands.captureLog({\n            level: h,\n            message: p\n          })\n        }\n      ;\n      Uu.forEach(h=>{\n          zu(console, h, a)\n        }\n      )\n    }\n    handleClose(a) {\n      nu.parse(a)\n    }\n    handleHandshake() {}\n    handleFrame(a) {\n      var h, p;\n      let d;\n      try {\n        d = ru(a)\n      } catch (M) {\n        console.error(\"Failed to parse\", a),\n          console.error(M);\n        return\n      }\n      if (d.cmd === \"DISPATCH\")\n        this.eventBus.emit(d.evt, d.data);\n      else {\n        if (d.evt === nr) {\n          if (d.nonce != null) {\n            (h = this.pendingCommands.get(d.nonce)) === null || h === void 0 || h.reject(d.data),\n              this.pendingCommands.delete(d.nonce);\n            return\n          }\n          this.eventBus.emit(\"error\", new Zi(d.data.code,d.data.message))\n        }\n        if (d.nonce == null) {\n          console.error(\"Missing nonce\", a);\n          return\n        }\n        (p = this.pendingCommands.get(d.nonce)) === null || p === void 0 || p.resolve(d),\n          this.pendingCommands.delete(d.nonce)\n      }\n    }\n  }\n;\nvar Hi = {\n  exports: {}\n};\n(function(c, a) {\n    var h = 200\n      , p = \"Expected a function\"\n      , d = \"__lodash_hash_undefined__\"\n      , M = 1\n      , F = 2\n      , Z = 1 / 0\n      , q = 9007199254740991\n      , k = \"[object Arguments]\"\n      , O = \"[object Array]\"\n      , B = \"[object Boolean]\"\n      , C = \"[object Date]\"\n      , Q = \"[object Error]\"\n      , J = \"[object Function]\"\n      , ne = \"[object GeneratorFunction]\"\n      , Y = \"[object Map]\"\n      , Me = \"[object Number]\"\n      , le = \"[object Object]\"\n      , Se = \"[object Promise]\"\n      , ye = \"[object RegExp]\"\n      , oe = \"[object Set]\"\n      , We = \"[object String]\"\n      , ct = \"[object Symbol]\"\n      , je = \"[object WeakMap]\"\n      , Pt = \"[object ArrayBuffer]\"\n      , ft = \"[object DataView]\"\n      , dt = \"[object Float32Array]\"\n      , qe = \"[object Float64Array]\"\n      , pe = \"[object Int8Array]\"\n      , Vt = \"[object Int16Array]\"\n      , re = \"[object Int32Array]\"\n      , Ot = \"[object Uint8Array]\"\n      , Ft = \"[object Uint8ClampedArray]\"\n      , ke = \"[object Uint16Array]\"\n      , ot = \"[object Uint32Array]\"\n      , kt = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/\n      , yn = /^\\w*$/\n      , Gt = /^\\./\n      , Mt = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g\n      , Xe = /[\\\\^$.*+?()[\\]{}|]/g\n      , xt = /\\\\(\\\\)?/g\n      , en = /^\\[object .+?Constructor\\]$/\n      , Kt = /^(?:0|[1-9]\\d*)$/\n      , Ce = {};\n    Ce[dt] = Ce[qe] = Ce[pe] = Ce[Vt] = Ce[re] = Ce[Ot] = Ce[Ft] = Ce[ke] = Ce[ot] = !0,\n      Ce[k] = Ce[O] = Ce[Pt] = Ce[B] = Ce[ft] = Ce[C] = Ce[Q] = Ce[J] = Ce[Y] = Ce[Me] = Ce[le] = Ce[ye] = Ce[oe] = Ce[We] = Ce[je] = !1;\n    var tt = typeof ri == \"object\" && ri && ri.Object === Object && ri\n      , Ke = typeof self == \"object\" && self && self.Object === Object && self\n      , Rt = tt || Ke || Function(\"return this\")()\n      , Zt = a && !a.nodeType && a\n      , tn = Zt && !0 && c && !c.nodeType && c\n      , cn = tn && tn.exports === Zt\n      , wn = cn && tt.process\n      , bn = function() {\n      try {\n        return wn && wn.binding(\"util\")\n      } catch {}\n    }()\n      , kn = bn && bn.isTypedArray;\n    function Sn(P, U) {\n      for (var X = -1, ie = P ? P.length : 0; ++X < ie && U(P[X], X, P) !== !1; )\n        ;\n      return P\n    }\n    function Bn(P, U) {\n      for (var X = -1, ie = P ? P.length : 0; ++X < ie; )\n        if (U(P[X], X, P))\n          return !0;\n      return !1\n    }\n    function Je(P) {\n      return function(U) {\n        return U?.[P]\n      }\n    }\n    function nn(P, U) {\n      for (var X = -1, ie = Array(P); ++X < P; )\n        ie[X] = U(X);\n      return ie\n    }\n    function Qe(P) {\n      return function(U) {\n        return P(U)\n      }\n    }\n    function En(P, U) {\n      return P?.[U]\n    }\n    function ae(P) {\n      var U = !1;\n      if (P != null && typeof P.toString != \"function\")\n        try {\n          U = !!(P + \"\")\n        } catch {}\n      return U\n    }\n    function e(P) {\n      var U = -1\n        , X = Array(P.size);\n      return P.forEach(function(ie, Ne) {\n        X[++U] = [Ne, ie]\n      }),\n        X\n    }\n    function t(P, U) {\n      return function(X) {\n        return P(U(X))\n      }\n    }\n    function n(P) {\n      var U = -1\n        , X = Array(P.size);\n      return P.forEach(function(ie) {\n        X[++U] = ie\n      }),\n        X\n    }\n    var i = Array.prototype\n      , r = Function.prototype\n      , s = Object.prototype\n      , u = Rt[\"__core-js_shared__\"]\n      , o = function() {\n      var P = /[^.]+$/.exec(u && u.keys && u.keys.IE_PROTO || \"\");\n      return P ? \"Symbol(src)_1.\" + P : \"\"\n    }()\n      , l = r.toString\n      , f = s.hasOwnProperty\n      , g = s.toString\n      , y = RegExp(\"^\" + l.call(f).replace(Xe, \"\\\\$&\").replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, \"$1.*?\") + \"$\")\n      , _ = Rt.Symbol\n      , v = Rt.Uint8Array\n      , b = t(Object.getPrototypeOf, Object)\n      , T = Object.create\n      , x = s.propertyIsEnumerable\n      , S = i.splice\n      , I = t(Object.keys, Object)\n      , m = In(Rt, \"DataView\")\n      , w = In(Rt, \"Map\")\n      , E = In(Rt, \"Promise\")\n      , A = In(Rt, \"Set\")\n      , N = In(Rt, \"WeakMap\")\n      , L = In(Object, \"create\")\n      , R = dn(m)\n      , D = dn(w)\n      , V = dn(E)\n      , z = dn(A)\n      , G = dn(N)\n      , H = _ ? _.prototype : void 0\n      , K = H ? H.valueOf : void 0\n      , $ = H ? H.toString : void 0;\n    function W(P) {\n      var U = -1\n        , X = P ? P.length : 0;\n      for (this.clear(); ++U < X; ) {\n        var ie = P[U];\n        this.set(ie[0], ie[1])\n      }\n    }\n    function te() {\n      this.__data__ = L ? L(null) : {}\n    }\n    function se(P) {\n      return this.has(P) && delete this.__data__[P]\n    }\n    function ue(P) {\n      var U = this.__data__;\n      if (L) {\n        var X = U[P];\n        return X === d ? void 0 : X\n      }\n      return f.call(U, P) ? U[P] : void 0\n    }\n    function Ie(P) {\n      var U = this.__data__;\n      return L ? U[P] !== void 0 : f.call(U, P)\n    }\n    function Ee(P, U) {\n      var X = this.__data__;\n      return X[P] = L && U === void 0 ? d : U,\n        this\n    }\n    W.prototype.clear = te,\n      W.prototype.delete = se,\n      W.prototype.get = ue,\n      W.prototype.has = Ie,\n      W.prototype.set = Ee;\n    function de(P) {\n      var U = -1\n        , X = P ? P.length : 0;\n      for (this.clear(); ++U < X; ) {\n        var ie = P[U];\n        this.set(ie[0], ie[1])\n      }\n    }\n    function ve() {\n      this.__data__ = []\n    }\n    function Oe(P) {\n      var U = this.__data__\n        , X = Ct(U, P);\n      if (X < 0)\n        return !1;\n      var ie = U.length - 1;\n      return X == ie ? U.pop() : S.call(U, X, 1),\n        !0\n    }\n    function Te(P) {\n      var U = this.__data__\n        , X = Ct(U, P);\n      return X < 0 ? void 0 : U[X][1]\n    }\n    function Ge(P) {\n      return Ct(this.__data__, P) > -1\n    }\n    function Re(P, U) {\n      var X = this.__data__\n        , ie = Ct(X, P);\n      return ie < 0 ? X.push([P, U]) : X[ie][1] = U,\n        this\n    }\n    de.prototype.clear = ve,\n      de.prototype.delete = Oe,\n      de.prototype.get = Te,\n      de.prototype.has = Ge,\n      de.prototype.set = Re;\n    function xe(P) {\n      var U = -1\n        , X = P ? P.length : 0;\n      for (this.clear(); ++U < X; ) {\n        var ie = P[U];\n        this.set(ie[0], ie[1])\n      }\n    }\n    function ze() {\n      this.__data__ = {\n        hash: new W,\n        map: new (w || de),\n        string: new W\n      }\n    }\n    function De(P) {\n      return Jn(this, P).delete(P)\n    }\n    function _t(P) {\n      return Jn(this, P).get(P)\n    }\n    function gt(P) {\n      return Jn(this, P).has(P)\n    }\n    function Et(P, U) {\n      return Jn(this, P).set(P, U),\n        this\n    }\n    xe.prototype.clear = ze,\n      xe.prototype.delete = De,\n      xe.prototype.get = _t,\n      xe.prototype.has = gt,\n      xe.prototype.set = Et;\n    function nt(P) {\n      var U = -1\n        , X = P ? P.length : 0;\n      for (this.__data__ = new xe; ++U < X; )\n        this.add(P[U])\n    }\n    function Ye(P) {\n      return this.__data__.set(P, d),\n        this\n    }\n    function ut(P) {\n      return this.__data__.has(P)\n    }\n    nt.prototype.add = nt.prototype.push = Ye,\n      nt.prototype.has = ut;\n    function st(P) {\n      this.__data__ = new de(P)\n    }\n    function vt() {\n      this.__data__ = new de\n    }\n    function Ht(P) {\n      return this.__data__.delete(P)\n    }\n    function fn(P) {\n      return this.__data__.get(P)\n    }\n    function jt(P) {\n      return this.__data__.has(P)\n    }\n    function Yt(P, U) {\n      var X = this.__data__;\n      if (X instanceof de) {\n        var ie = X.__data__;\n        if (!w || ie.length < h - 1)\n          return ie.push([P, U]),\n            this;\n        X = this.__data__ = new xe(ie)\n      }\n      return X.set(P, U),\n        this\n    }\n    st.prototype.clear = vt,\n      st.prototype.delete = Ht,\n      st.prototype.get = fn,\n      st.prototype.has = jt,\n      st.prototype.set = Yt;\n    function Dt(P, U) {\n      var X = Wt(P) || gr(P) ? nn(P.length, String) : []\n        , ie = X.length\n        , Ne = !!ie;\n      for (var me in P)\n        (U || f.call(P, me)) && !(Ne && (me == \"length\" || fr(me, ie))) && X.push(me);\n      return X\n    }\n    function Ct(P, U) {\n      for (var X = P.length; X--; )\n        if (_r(P[X][0], U))\n          return X;\n      return -1\n    }\n    function Tn(P) {\n      return Cn(P) ? T(P) : {}\n    }\n    var $t = aa();\n    function Oi(P, U) {\n      return P && $t(P, U, ti)\n    }\n    function lr(P, U) {\n      U = Xn(U, P) ? [U] : hr(U);\n      for (var X = 0, ie = U.length; P != null && X < ie; )\n        P = P[Qn(U[X++])];\n      return X && X == ie ? P : void 0\n    }\n    function Ys(P) {\n      return g.call(P)\n    }\n    function $s(P, U) {\n      return P != null && U in Object(P)\n    }\n    function xi(P, U, X, ie, Ne) {\n      return P === U ? !0 : P == null || U == null || !Cn(P) && !ei(U) ? P !== P && U !== U : Ws(P, U, xi, X, ie, Ne)\n    }\n    function Ws(P, U, X, ie, Ne, me) {\n      var Ze = Wt(P)\n        , $e = Wt(U)\n        , it = O\n        , mt = O;\n      Ze || (it = rn(P),\n        it = it == k ? le : it),\n      $e || (mt = rn(U),\n        mt = mt == k ? le : mt);\n      var At = it == le && !ae(P)\n        , Nt = mt == le && !ae(U)\n        , yt = it == mt;\n      if (yt && !At)\n        return me || (me = new st),\n          Ze || mr(P) ? cr(P, U, X, ie, Ne, me) : oa(P, U, it, X, ie, Ne, me);\n      if (!(Ne & F)) {\n        var Bt = At && f.call(P, \"__wrapped__\")\n          , Ut = Nt && f.call(U, \"__wrapped__\");\n        if (Bt || Ut) {\n          var sn = Bt ? P.value() : P\n            , Jt = Ut ? U.value() : U;\n          return me || (me = new st),\n            X(sn, Jt, ie, Ne, me)\n        }\n      }\n      return yt ? (me || (me = new st),\n        ua(P, U, X, ie, Ne, me)) : !1\n    }\n    function Js(P, U, X, ie) {\n      var Ne = X.length\n        , me = Ne\n        , Ze = !ie;\n      if (P == null)\n        return !me;\n      for (P = Object(P); Ne--; ) {\n        var $e = X[Ne];\n        if (Ze && $e[2] ? $e[1] !== P[$e[0]] : !($e[0]in P))\n          return !1\n      }\n      for (; ++Ne < me; ) {\n        $e = X[Ne];\n        var it = $e[0]\n          , mt = P[it]\n          , At = $e[1];\n        if (Ze && $e[2]) {\n          if (mt === void 0 && !(it in P))\n            return !1\n        } else {\n          var Nt = new st;\n          if (ie)\n            var yt = ie(mt, At, it, P, U, Nt);\n          if (!(yt === void 0 ? xi(At, mt, ie, M | F, Nt) : yt))\n            return !1\n        }\n      }\n      return !0\n    }\n    function Xs(P) {\n      if (!Cn(P) || fa(P))\n        return !1;\n      var U = Li(P) || ae(P) ? y : en;\n      return U.test(dn(P))\n    }\n    function Qs(P) {\n      return ei(P) && Mi(P.length) && !!Ce[g.call(P)]\n    }\n    function ea(P) {\n      return typeof P == \"function\" ? P : P == null ? wa : typeof P == \"object\" ? Wt(P) ? ia(P[0], P[1]) : na(P) : ba(P)\n    }\n    function ta(P) {\n      if (!da(P))\n        return I(P);\n      var U = [];\n      for (var X in Object(P))\n        f.call(P, X) && X != \"constructor\" && U.push(X);\n      return U\n    }\n    function na(P) {\n      var U = la(P);\n      return U.length == 1 && U[0][2] ? pr(U[0][0], U[0][1]) : function(X) {\n        return X === P || Js(X, P, U)\n      }\n    }\n    function ia(P, U) {\n      return Xn(P) && dr(U) ? pr(Qn(P), U) : function(X) {\n        var ie = va(X, P);\n        return ie === void 0 && ie === U ? ma(X, P) : xi(U, ie, void 0, M | F)\n      }\n    }\n    function ra(P) {\n      return function(U) {\n        return lr(U, P)\n      }\n    }\n    function sa(P) {\n      if (typeof P == \"string\")\n        return P;\n      if (Ri(P))\n        return $ ? $.call(P) : \"\";\n      var U = P + \"\";\n      return U == \"0\" && 1 / P == -Z ? \"-0\" : U\n    }\n    function hr(P) {\n      return Wt(P) ? P : pa(P)\n    }\n    function aa(P) {\n      return function(U, X, ie) {\n        for (var Ne = -1, me = Object(U), Ze = ie(U), $e = Ze.length; $e--; ) {\n          var it = Ze[P ? $e : ++Ne];\n          if (X(me[it], it, me) === !1)\n            break\n        }\n        return U\n      }\n    }\n    function cr(P, U, X, ie, Ne, me) {\n      var Ze = Ne & F\n        , $e = P.length\n        , it = U.length;\n      if ($e != it && !(Ze && it > $e))\n        return !1;\n      var mt = me.get(P);\n      if (mt && me.get(U))\n        return mt == U;\n      var At = -1\n        , Nt = !0\n        , yt = Ne & M ? new nt : void 0;\n      for (me.set(P, U),\n             me.set(U, P); ++At < $e; ) {\n        var Bt = P[At]\n          , Ut = U[At];\n        if (ie)\n          var sn = Ze ? ie(Ut, Bt, At, U, P, me) : ie(Bt, Ut, At, P, U, me);\n        if (sn !== void 0) {\n          if (sn)\n            continue;\n          Nt = !1;\n          break\n        }\n        if (yt) {\n          if (!Bn(U, function(Jt, pn) {\n            if (!yt.has(pn) && (Bt === Jt || X(Bt, Jt, ie, Ne, me)))\n              return yt.add(pn)\n          })) {\n            Nt = !1;\n            break\n          }\n        } else if (!(Bt === Ut || X(Bt, Ut, ie, Ne, me))) {\n          Nt = !1;\n          break\n        }\n      }\n      return me.delete(P),\n        me.delete(U),\n        Nt\n    }\n    function oa(P, U, X, ie, Ne, me, Ze) {\n      switch (X) {\n        case ft:\n          if (P.byteLength != U.byteLength || P.byteOffset != U.byteOffset)\n            return !1;\n          P = P.buffer,\n            U = U.buffer;\n        case Pt:\n          return !(P.byteLength != U.byteLength || !ie(new v(P), new v(U)));\n        case B:\n        case C:\n        case Me:\n          return _r(+P, +U);\n        case Q:\n          return P.name == U.name && P.message == U.message;\n        case ye:\n        case We:\n          return P == U + \"\";\n        case Y:\n          var $e = e;\n        case oe:\n          var it = me & F;\n          if ($e || ($e = n),\n          P.size != U.size && !it)\n            return !1;\n          var mt = Ze.get(P);\n          if (mt)\n            return mt == U;\n          me |= M,\n            Ze.set(P, U);\n          var At = cr($e(P), $e(U), ie, Ne, me, Ze);\n          return Ze.delete(P),\n            At;\n        case ct:\n          if (K)\n            return K.call(P) == K.call(U)\n      }\n      return !1\n    }\n    function ua(P, U, X, ie, Ne, me) {\n      var Ze = Ne & F\n        , $e = ti(P)\n        , it = $e.length\n        , mt = ti(U)\n        , At = mt.length;\n      if (it != At && !Ze)\n        return !1;\n      for (var Nt = it; Nt--; ) {\n        var yt = $e[Nt];\n        if (!(Ze ? yt in U : f.call(U, yt)))\n          return !1\n      }\n      var Bt = me.get(P);\n      if (Bt && me.get(U))\n        return Bt == U;\n      var Ut = !0;\n      me.set(P, U),\n        me.set(U, P);\n      for (var sn = Ze; ++Nt < it; ) {\n        yt = $e[Nt];\n        var Jt = P[yt]\n          , pn = U[yt];\n        if (ie)\n          var yr = Ze ? ie(pn, Jt, yt, U, P, me) : ie(Jt, pn, yt, P, U, me);\n        if (!(yr === void 0 ? Jt === pn || X(Jt, pn, ie, Ne, me) : yr)) {\n          Ut = !1;\n          break\n        }\n        sn || (sn = yt == \"constructor\")\n      }\n      if (Ut && !sn) {\n        var ni = P.constructor\n          , ii = U.constructor;\n        ni != ii && \"constructor\"in P && \"constructor\"in U && !(typeof ni == \"function\" && ni instanceof ni && typeof ii == \"function\" && ii instanceof ii) && (Ut = !1)\n      }\n      return me.delete(P),\n        me.delete(U),\n        Ut\n    }\n    function Jn(P, U) {\n      var X = P.__data__;\n      return ca(U) ? X[typeof U == \"string\" ? \"string\" : \"hash\"] : X.map\n    }\n    function la(P) {\n      for (var U = ti(P), X = U.length; X--; ) {\n        var ie = U[X]\n          , Ne = P[ie];\n        U[X] = [ie, Ne, dr(Ne)]\n      }\n      return U\n    }\n    function In(P, U) {\n      var X = En(P, U);\n      return Xs(X) ? X : void 0\n    }\n    var rn = Ys;\n    (m && rn(new m(new ArrayBuffer(1))) != ft || w && rn(new w) != Y || E && rn(E.resolve()) != Se || A && rn(new A) != oe || N && rn(new N) != je) && (rn = function(P) {\n        var U = g.call(P)\n          , X = U == le ? P.constructor : void 0\n          , ie = X ? dn(X) : void 0;\n        if (ie)\n          switch (ie) {\n            case R:\n              return ft;\n            case D:\n              return Y;\n            case V:\n              return Se;\n            case z:\n              return oe;\n            case G:\n              return je\n          }\n        return U\n      }\n    );\n    function ha(P, U, X) {\n      U = Xn(U, P) ? [U] : hr(U);\n      for (var ie, Ne = -1, Ze = U.length; ++Ne < Ze; ) {\n        var me = Qn(U[Ne]);\n        if (!(ie = P != null && X(P, me)))\n          break;\n        P = P[me]\n      }\n      if (ie)\n        return ie;\n      var Ze = P ? P.length : 0;\n      return !!Ze && Mi(Ze) && fr(me, Ze) && (Wt(P) || gr(P))\n    }\n    function fr(P, U) {\n      return U = U ?? q,\n      !!U && (typeof P == \"number\" || Kt.test(P)) && P > -1 && P % 1 == 0 && P < U\n    }\n    function Xn(P, U) {\n      if (Wt(P))\n        return !1;\n      var X = typeof P;\n      return X == \"number\" || X == \"symbol\" || X == \"boolean\" || P == null || Ri(P) ? !0 : yn.test(P) || !kt.test(P) || U != null && P in Object(U)\n    }\n    function ca(P) {\n      var U = typeof P;\n      return U == \"string\" || U == \"number\" || U == \"symbol\" || U == \"boolean\" ? P !== \"__proto__\" : P === null\n    }\n    function fa(P) {\n      return !!o && o in P\n    }\n    function da(P) {\n      var U = P && P.constructor\n        , X = typeof U == \"function\" && U.prototype || s;\n      return P === X\n    }\n    function dr(P) {\n      return P === P && !Cn(P)\n    }\n    function pr(P, U) {\n      return function(X) {\n        return X == null ? !1 : X[P] === U && (U !== void 0 || P in Object(X))\n      }\n    }\n    var pa = Ni(function(P) {\n      P = ga(P);\n      var U = [];\n      return Gt.test(P) && U.push(\"\"),\n        P.replace(Mt, function(X, ie, Ne, me) {\n          U.push(Ne ? me.replace(xt, \"$1\") : ie || X)\n        }),\n        U\n    });\n    function Qn(P) {\n      if (typeof P == \"string\" || Ri(P))\n        return P;\n      var U = P + \"\";\n      return U == \"0\" && 1 / P == -Z ? \"-0\" : U\n    }\n    function dn(P) {\n      if (P != null) {\n        try {\n          return l.call(P)\n        } catch {}\n        try {\n          return P + \"\"\n        } catch {}\n      }\n      return \"\"\n    }\n    function Ni(P, U) {\n      if (typeof P != \"function\" || U && typeof U != \"function\")\n        throw new TypeError(p);\n      var X = function() {\n        var ie = arguments\n          , Ne = U ? U.apply(this, ie) : ie[0]\n          , me = X.cache;\n        if (me.has(Ne))\n          return me.get(Ne);\n        var Ze = P.apply(this, ie);\n        return X.cache = me.set(Ne, Ze),\n          Ze\n      };\n      return X.cache = new (Ni.Cache || xe),\n        X\n    }\n    Ni.Cache = xe;\n    function _r(P, U) {\n      return P === U || P !== P && U !== U\n    }\n    function gr(P) {\n      return _a(P) && f.call(P, \"callee\") && (!x.call(P, \"callee\") || g.call(P) == k)\n    }\n    var Wt = Array.isArray;\n    function vr(P) {\n      return P != null && Mi(P.length) && !Li(P)\n    }\n    function _a(P) {\n      return ei(P) && vr(P)\n    }\n    function Li(P) {\n      var U = Cn(P) ? g.call(P) : \"\";\n      return U == J || U == ne\n    }\n    function Mi(P) {\n      return typeof P == \"number\" && P > -1 && P % 1 == 0 && P <= q\n    }\n    function Cn(P) {\n      var U = typeof P;\n      return !!P && (U == \"object\" || U == \"function\")\n    }\n    function ei(P) {\n      return !!P && typeof P == \"object\"\n    }\n    function Ri(P) {\n      return typeof P == \"symbol\" || ei(P) && g.call(P) == ct\n    }\n    var mr = kn ? Qe(kn) : Qs;\n    function ga(P) {\n      return P == null ? \"\" : sa(P)\n    }\n    function va(P, U, X) {\n      var ie = P == null ? void 0 : lr(P, U);\n      return ie === void 0 ? X : ie\n    }\n    function ma(P, U) {\n      return P != null && ha(P, U, $s)\n    }\n    function ti(P) {\n      return vr(P) ? Dt(P) : ta(P)\n    }\n    function ya(P, U, X) {\n      var ie = Wt(P) || mr(P);\n      if (U = ea(U),\n      X == null)\n        if (ie || Cn(P)) {\n          var Ne = P.constructor;\n          ie ? X = Wt(P) ? new Ne : [] : X = Li(Ne) ? Tn(b(P)) : {}\n        } else\n          X = {};\n      return (ie ? Sn : Oi)(P, function(me, Ze, $e) {\n        return U(X, me, Ze, $e)\n      }),\n        X\n    }\n    function wa(P) {\n      return P\n    }\n    function ba(P) {\n      return Xn(P) ? Je(Qn(P)) : ra(P)\n    }\n    c.exports = ya\n  }\n)(Hi, Hi.exports);\nvar Ku = Hi.exports;\nvar {Commands: Yu} = vo;\nvar Gu = `\n  <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" class=\"spinner\" aria-label=\"loading\">\n    <path\n      d=\"M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z\"\n      opacity=\".25\"\n    />\n    <path d=\"M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z\" />\n  </svg>\n`\n  , Ti = c=>{\n    try {\n      if (c.dataset?.state === \"loading\")\n        return;\n      c.disabled = !0,\n        c.dataset.state = \"loading\",\n        c.innerHTML = `\n      <div class=\"spinner-container\">\n        ${Gu}\n      </div>\n      <div class=\"loading-container\">\n        ${c.innerHTML}\n      </div>\n    `\n    } catch {\n      console.error(\"failed to start loading\", c)\n    }\n  }\n  , Ii = c=>{\n    try {\n      if (c.dataset?.state !== \"loading\")\n        return;\n      delete c.dataset.state,\n        c.disabled = !1;\n      let a = null;\n      for (let h = 0; h < c.childElementCount; h++) {\n        let p = c.children[h];\n        if (p.classList?.contains(\"loading-container\")) {\n          a = p;\n          break\n        }\n      }\n      c.innerHTML = a.innerHTML\n    } catch (a) {\n      console.error(\"failed to stop loading\", c, a)\n    }\n  }\n;\nvar Yn = class extends EventTarget {\n    constructor(a) {\n      super(),\n        this.tool = new ce.Tool,\n        this.lastTolerance = 5,\n        this.selectedSegments = [],\n        this.editor = a,\n        this.tool.onKeyDown = h=>{\n          this.onKeyDown(h)\n        }\n        ,\n        this.tool.onMouseDown = h=>{\n          this.onMouseDown(h)\n        }\n        ,\n        this.tool.onMouseDrag = h=>{\n          this.onMouseDrag(h)\n        }\n        ,\n        this.tool.onMouseMove = h=>{\n          this.onMouseMove(h)\n        }\n        ,\n        this.tool.onMouseUp = h=>{\n          this.onMouseUp(h)\n        }\n    }\n    hitTestActiveLayer(a) {\n      return ce.project.hitTest(a, {\n        segments: !0,\n        stroke: !0,\n        fill: !0,\n        tolerance: this.lastTolerance,\n        match: h=>h.item.layer == ce.project.activeLayer && !h.item.name.includes(\"Background\") && !h.item.name.includes(\"Checkerboard\")\n      })\n    }\n    onMouseDown(a) {\n      a.event.pointerId && this.editor.canvas.setPointerCapture(a.event.pointerId || 1),\n        this.clampToBounds(a),\n        this.button = !a.event.button || a.event.button <= 0 ? this.editor.selectedTool : a.event.button,\n        this.minDistance = this.button == 2 ? this.lastTolerance * 2 : 0,\n        this.currentSegment = this.currentPath = null;\n      let h = this.hitTestActiveLayer(a.point);\n      if (!this.button || this.button <= 0)\n        this.currentPath = new ce.Path.Rectangle({\n          from: a.point,\n          to: a.point\n        }),\n          this.currentPath.strokeColor = new ce.Color(\"#eeeeee\"),\n          this.currentPath.strokeColor.alpha = 1,\n          this.currentPath.strokeCap = \"round\",\n          this.currentPath.isRectangle = !0,\n          this.currentPath.strokeWidth = 4,\n          this.currentPath.strokeColor = new ce.Color(\"rgba(255,255,255,1)\"),\n          this.currentPath.dashArray = [10, 10],\n          this.currentPath.add(a.point),\n          this.editor.drawingLayer.addChild(this.currentPath);\n      else if (this.button == .5)\n        this.currentPath = new ce.Path({\n          segments: [a.point]\n        }),\n          this.currentPath.strokeWidth = 4,\n          this.currentPath.strokeColor = new ce.Color(\"rgba(255,255,255,1)\"),\n          this.currentPath.dashArray = [10, 10],\n          this.currentPath.add(a.point),\n          this.currentPath.strokeCap = \"round\",\n          this.currentPath.isStroke = !0,\n          this.currentPath.closed = !0,\n          this.currentPath.fillColor = new ce.Color(1,1,1),\n          this.editor.drawingLayer.addChild(this.currentPath);\n      else if (this.button == 1) {\n        if (!h)\n          this.selectionRectPath = new ce.Path.Rectangle({\n            from: a.point,\n            to: a.point\n          });\n        else if (this.selectedSegments.length > 0)\n          this.markForSave = !0;\n        else if (this.currentPath = h.item,\n        this.currentPath && (this.saveItemStateForUndo(h.item),\n        h.type == \"stroke\" || h.type == \"fill\"))\n          if (this.editor.movePath)\n            this.currentSegment = null;\n          else {\n            let p = h.location;\n            this.currentSegment = this.currentPath.insert(p.index + 1, a.point),\n              this.currentPath.smooth()\n          }\n      } else if (h && this.button == 2) {\n        if (this.selectedSegments.length > 0)\n          for (let p = ce.project.selectedItems.length - 1; p >= 0; p--) {\n            let d = ce.project.selectedItems[p];\n            d.selected = !1,\n              this.saveItemStateForUndo(d),\n              d.remove()\n          }\n        else\n          h.type == \"stroke\" || h.type == \"fill\" || h.segment.path.segments.length <= 2 ? (this.saveItemStateForUndo(h.item),\n            h.item.remove()) : h.type == \"segment\" && (this.saveItemStateForUndo(h.item),\n            h.segment.remove());\n        return\n      }\n    }\n    onMouseMove(a) {\n      if (this.clampToBounds(a),\n      this.selectedSegments.length == 0) {\n        ce.project.activeLayer.selected = !1;\n        let h = this.hitTestActiveLayer(a.point);\n        h && (h.item.selected = !0,\n        h.item.strokeWidth && (this.lastTolerance = Math.max(h.item.strokeWidth / 4, 5)))\n      }\n    }\n    onMouseDrag(a) {\n      if (this.clampToBounds(a),\n      !this.button || this.button <= 0) {\n        if (ce.project.activeLayer.selected = !1,\n        this.currentPath && this.currentPath.isRectangle) {\n          let h = new ce.Path.Rectangle(a.downPoint,a.point);\n          h.fillColor = \"white\",\n            this.currentPath.replaceWith(h),\n            this.currentPath.remove(),\n            this.currentPath = h,\n            this.currentPath.bounds.selected = !0,\n            this.currentPath.isRectangle = !0\n        }\n      } else if (this.button == .5)\n        ce.project.activeLayer.selected = !1,\n          this.currentPath.add(a.point);\n      else if (this.button == 1)\n        if (this.selectionRectPath) {\n          let h = new ce.Path.Rectangle(a.downPoint,a.point);\n          this.selectionRectPath.replaceWith(h),\n            this.selectionRectPath.remove(),\n            this.selectionRectPath = h,\n            this.selectionRectPath.bounds.selected = !0,\n            this.selectedSegments = [];\n          for (let d = 0; d < ce.project.selectedItems.length; d++)\n            ce.project.selectedItems[d].selected = !1;\n          let p = this.editor.drawingLayer.getItems({\n            overlapping: h.bounds\n          });\n          for (let d = 0; d < p.length; d++)\n            if (p[d].segments)\n              for (let M = 0; M < p[d].segments.length; M++)\n                this.selectionRectPath.bounds.contains(p[d].segments[M].point) && (p[d].segments[M].selected = !0,\n                  this.selectedSegments.push(p[d].segments[M]))\n        } else if (this.selectedSegments.length > 0) {\n          if (this.markForSave) {\n            for (let h = ce.project.selectedItems.length - 1; h >= 0; h--)\n              this.saveItemStateForUndo(ce.project.selectedItems[h]);\n            this.markForSave = !1\n          }\n          for (let h = 0; h < this.selectedSegments.length; h++)\n            this.selectedSegments[h].point = this.selectedSegments[h].point.add(a.delta)\n        } else\n          this.currentSegment ? this.currentSegment.point = this.currentSegment.point.add(a.delta) : this.currentPath && (this.currentPath.position = this.currentPath.position.add(a.delta));\n      else if (this.button == 2) {\n        let h = this.hitTestActiveLayer(a.point);\n        if (!h)\n          return;\n        h.type == \"stroke\" || h.type == \"fill\" || h.segment.path.segments.length <= 2 ? (this.saveItemStateForUndo(h.item),\n          h.item.remove()) : h.type == \"segment\" && (this.saveItemStateForUndo(h.item),\n          h.segment.remove())\n      }\n    }\n    onMouseUp(a) {\n      a.event.pointerId && this.editor.canvas.releasePointerCapture(a.event.pointerId || 1),\n        this.clampToBounds(a),\n      this.selectionRectPath && (this.selectionRectPath.remove(),\n        this.selectionRectPath = null),\n      (!this.button || this.button <= .5) && (this.currentPath.isRectangle || (this.currentPath.segments.length > 1 ? this.currentPath.simplify(3) : this.currentPath.add(a.point),\n        this.currentPath.strokeColor = new ce.Color(\"#ffffff\")),\n        this.clearSelection(),\n        this.dispatchEvent(new Event(\"newStroke\",{\n          name: this.currentPath.name\n        })),\n        this.currentPath.bounds.selected = !1,\n        this.currentPath.name = \"Stroke-\" + this.stringHashCode(this.currentPath.toString()),\n        this.currentPath.strokeColor = null,\n        this.editor.undoLayer.addChild(new ce.Group({\n          name: this.editor.removeCmd + this.currentPath.name\n        })),\n        this.editor.redoLayer.removeChildren())\n    }\n    async onKeyDown(a) {\n      if (a.key == \"enter\") {\n        if (a.preventDefault(),\n          a.stopPropagation(),\n        this.editor.submitButton.disabled || this.editor.submitButton.dataset?.state === \"loading\")\n          return;\n        Ti(this.editor.submitButton);\n        try {\n          await this.editor.submit().catch(h=>this.editor.displayError(h?.toString()))\n        } finally {\n          Ii(this.editor.submitButton)\n        }\n      } else\n        (a.modifiers.control || a.modifiers.meta) && (a.key == \"z\" ? this.editor.undo() : a.key == \"y\" && this.editor.redo())\n    }\n    clearSelection() {\n      for (let a = 0; a < this.selectedSegments.length; a++)\n        this.selectedSegments[a].selected = !1;\n      this.selectedSegments = [];\n      for (let a = 0; a < ce.project.selectedItems.length; a++)\n        ce.project.selectedItems[a].selected = !1\n    }\n    saveItemStateForUndo(a) {\n      a.name || (a.name = \"ForeignObject-\" + this.stringHashCode(a.toString()));\n      let h = a.clone();\n      h.name = a.name,\n        this.editor.undoLayer.addChild(h),\n        this.editor.redoLayer.removeChildren()\n    }\n    stringHashCode(a) {\n      let h = 0;\n      if (a.length == 0)\n        return h;\n      for (let p = 0; p < a.length; p++) {\n        let d = a.charCodeAt(p);\n        h = (h << 5) - h + d,\n          h = h & h\n      }\n      return h\n    }\n    clampToBounds(a) {\n      let h = this.editor.backgroundImageElement.width\n        , p = this.editor.backgroundImageElement.height;\n      a.point = a.point.set(Math.min(h * .5, Math.max(-h * .5, a.point.x)), Math.min(p * .5, Math.max(-p * .5, a.point.y)))\n    }\n  }\n;\nvar Ci = class {\n    constructor(a) {\n      this.omniTool = a,\n        this.promptBarAvailable = !1\n    }\n    start() {\n      this.omniTool.addEventListener(\"newStroke\", ()=>{\n          this.promptBarAvailable ? (this.createPopover(\"When you're ready, edit the prompt to describe the new image\"),\n            document.getElementById(\"Prompt\").addEventListener(\"input\", ()=>{\n                this.createPopover(\"按右下角箭头提交\")\n              }\n              , {\n                once: !0\n              })) : this.createPopover(\"按右下角箭头提交\")\n        }\n        , {\n          once: !0\n        }),\n        this.createPopover(\"请拖动选择要更改的区域\")\n    }\n    setPromptBarAvailable(a) {\n      this.promptBarAvailable = a\n    }\n    createPopover(a) {\n      let h = document.getElementById(\"popover-container\");\n      h.innerHTML = \"\";\n      let p = document.createElement(\"div\");\n      p.className = \"popover\",\n        p.innerText = a,\n        h.appendChild(p)\n    }\n  }\n;\nvar ar = document.getElementById(\"modal-container\");\ndocument.addEventListener(\"click\", c=>{\n    c.target.classList.contains(\"modal-backdrop\") && Ai()\n  }\n);\nvar Ai = ()=>{\n    ar.innerHTML = \"\"\n  }\n  , hn = c=>{\n    let a = c.header !== void 0;\n    ar.innerHTML = \"\";\n    let h = document.createElement(\"div\");\n    h.classList.add(\"modal\");\n    let p = document.createElement(\"div\");\n    if (p.classList.add(\"modal-body\"),\n      p.innerHTML = `\n    ${a ? `<div class=\"modal-header\">\n      ${c.header}\n    </div>` : \"\"}\n    <div class=\"modal-content\">\n      ${c.content}\n    </div>\n  `,\n    c.footer !== void 0) {\n      let F = document.createElement(\"div\");\n      F.classList.add(\"modal-footer\"),\n      c.footer && (typeof c.footer == \"string\" ? F.innerHTML = c.footer : F.appendChild(c.footer)),\n        p.appendChild(F)\n    }\n    let M = document.createElement(\"div\");\n    M.classList.add(\"modal-backdrop\"),\n      h.appendChild(M),\n      h.appendChild(p),\n      ar.appendChild(h)\n  }\n;\nvar Zu = {\n  \"\": [\"<em>\", \"</em>\"],\n  _: [\"<strong>\", \"</strong>\"],\n  \"*\": [\"<strong>\", \"</strong>\"],\n  \"~\": [\"<s>\", \"</s>\"],\n  \"\\n\": [\"<br />\"],\n  \" \": [\"<br />\"],\n  \"-\": [\"<hr />\"]\n};\nfunction Ks(c) {\n  return c.replace(RegExp(\"^\" + (c.match(/^(\\t| )+/) || \"\")[0], \"gm\"), \"\")\n}\nfunction $n(c) {\n  return (c + \"\").replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\")\n}\nfunction Wn(c, a) {\n  let h = /((?:^|\\n+)(?:\\n---+|\\* \\*(?: \\*)+)\\n)|(?:^``` *(\\w*)\\n([\\s\\S]*?)\\n```$)|((?:(?:^|\\n+)(?:\\t|  {2,}).+)+\\n*)|((?:(?:^|\\n)([>*+-]|\\d+\\.)\\s+.*)+)|(?:!\\[([^\\]]*?)\\]\\(([^)]+?)\\))|(\\[)|(\\](?:\\(([^)]+?)\\))?)|(?:(?:^|\\n+)([^\\s].*)\\n(-{3,}|={3,})(?:\\n+|$))|(?:(?:^|\\n+)(#{1,6})\\s*(.+)(?:\\n+|$))|(?:`([^`].*?)`)|(  \\n\\n*|\\n{2,}|__|\\*\\*|[_*]|~~)/gm, p = [], d = \"\", M = a || {}, F = 0, Z, q, k, O, B;\n  function C(J) {\n    let ne = Zu[J[1] || \"\"]\n      , Y = p[p.length - 1] == J;\n    return ne ? ne[1] ? (Y ? p.pop() : p.push(J),\n      ne[Y | 0]) : ne[0] : J\n  }\n  function Q() {\n    let J = \"\";\n    for (; p.length; )\n      J += C(p[p.length - 1]);\n    return J\n  }\n  for (c = c.replace(/^\\[(.+?)\\]:\\s*(.+)$/gm, (J,ne,Y)=>(M[ne.toLowerCase()] = Y,\n    \"\")).replace(/^\\n+|\\n+$/g, \"\"); k = h.exec(c); )\n    q = c.substring(F, k.index),\n      F = h.lastIndex,\n      Z = k[0],\n    q.match(/[^\\\\](\\\\\\\\)*\\\\$/) || ((B = k[3] || k[4]) ? Z = '<pre class=\"code ' + (k[4] ? \"poetry\" : k[2].toLowerCase()) + '\"><code' + (k[2] ? ` class=\"language-${k[2].toLowerCase()}\"` : \"\") + \">\" + Ks($n(B).replace(/^\\n+|\\n+$/g, \"\")) + \"</code></pre>\" : (B = k[6]) ? (B.match(/\\./) && (k[5] = k[5].replace(/^\\d+/gm, \"\")),\n      O = Wn(Ks(k[5].replace(/^\\s*[>*+.-]/gm, \"\"))),\n      B == \">\" ? B = \"blockquote\" : (B = B.match(/\\./) ? \"ol\" : \"ul\",\n        O = O.replace(/^(.*)(\\n|$)/gm, \"<li>$1</li>\")),\n      Z = \"<\" + B + \">\" + O + \"</\" + B + \">\") : k[8] ? Z = `<img src=\"${$n(k[8])}\" alt=\"${$n(k[7])}\">` : k[10] ? (d = d.replace(\"<a>\", `<a href=\"${$n(k[11] || M[q.toLowerCase()])}\">`),\n      Z = Q() + \"</a>\") : k[9] ? Z = \"<a>\" : k[12] || k[14] ? (B = \"h\" + (k[14] ? k[14].length : k[13] > \"=\" ? 1 : 2),\n      Z = \"<\" + B + \">\" + Wn(k[12] || k[15], M) + \"</\" + B + \">\") : k[16] ? Z = \"<code>\" + $n(k[16]) + \"</code>\" : (k[17] || k[1]) && (Z = C(k[17] || \"--\"))),\n      d += q,\n      d += Z;\n  return (d + c.substring(F) + Q()).replace(/^\\n+|\\n+$/g, \"\")\n}\nvar or = class extends Error {\n    constructor(a, h) {\n      super(a + \": \" + h),\n        this.responseText = h\n    }\n  }\n  , Pi = class {\n    constructor() {}\n    async getImageInfo(a, h, p) {\n      return await fetch(`./api/get-image-info/${a}/${h}/${p}`).then(this._handleResponse)\n    }\n    async _handleResponse(a) {\n      if (a.ok || 400 <= a.status < 500)\n        return await a.json();\n      let h = await a.text();\n      throw new or(`request failed with ${a.status}`,h)\n    }\n  }\n;\nvar ur = class {\n    constructor() {\n      this.keymap = new Set,\n        this.width = 1024,\n        this.height = 1024,\n        this.movePath = !0,\n        this.removeCmd = \"Remove-\",\n        this.selectedTool = 0,\n        this.omniTool = new Yn(this),\n        this.onboarding = new Ci(this.omniTool),\n        this.api = new Pi,\n        window.addEventListener( 'message', (e)=>{\n         //console.log(\"message\",e.data);\n         const obj= JSON.parse(e.data)\n         this.imgInfo= obj.img_info;\n         this.setup()\n       });\n        //this.setup()\n    }\n    async setup() {\n      \n      if (this.imageURL = \"./assets/strawberryshake.webp\",\n        this.inIFrame = window.location.search != \"\",\n        this.currentPath = null,\n        document.addEventListener(\"keydown\", this.onKeyDown.bind(this)),\n        document.addEventListener(\"keyup\", this.onKeyUp.bind(this)),\n        this.inIFrame) {\n        if (this.searchParams = new URLSearchParams(window.location.search),\n          this.customId = this.searchParams.get(\"custom_id\").split(\"::\")[2],\n          this.applicationId = this.searchParams.get(\"instance_id\").split(\":\")[1],\n          this.guildId = this.searchParams.get(\"guild_id\"),\n          this.channelId = this.searchParams.get(\"channel_id\"),\n          this.platform = this.searchParams.get(\"platform\"),\n          //this.imgInfo = this.searchParams.get(\"img_info\") && JSON.parse(this.searchParams.get(\"img_info\")),\n          this.discord = null)\n          try {\n            let d = window.location.hostname.split(\".\")[0];\n            this.discord = new di(d),\n              console.log(\"Discord SDK was initialized!\", this.discord)\n          } catch (d) {\n            console.error(\"Discord SDK could not be initialized!\", d)\n          }\n        this.userId = \"0\",\n          this.userName = \"0\";\n        let p = this.imgInfo;\n        if (p.error === \"invalid_id\") {\n          console.error(\"Error fetching image info:\", p),\n          this.discord != null && (p.message = \"This session is invalid. Please relaunch the editor from the original message.\"),\n            hn({\n              header: \"Error\",\n              content: p.message,\n              footer: this.createDefaultCloseButton()\n            });\n          return\n        }\n        //console.log(\"Fetched Image info:\", p),\n          this.prompt = p.prompt,\n          this.input_job_id = p.child_job_id,\n          this.input_index = p.image_num,\n          this.has_prompt_enabled = p.has_prompt_enabled,\n          this.imageURL = p.image_url\n      } else\n        this.has_prompt_enabled = !0;\n      this.backgroundImageElement = await this.loadImageAsync(this.imageURL),\n        this.width = this.backgroundImageElement.width,\n        this.height = this.backgroundImageElement.height,\n        await this.forPageLoadAsync(),\n        this.canvas = document.getElementById(\"InpaintingEditorCanvas\"),\n        ce.setup(this.canvas),\n        ce.project.activeLayer.name = \"EditorWorkspace\",\n        this.checkerboardImage = new ce.Raster(\"./assets/checkerboard.png\"),\n        this.checkerboardImage.name = \"CheckerboardImage\",\n        this.checkerboardImage.position = new ce.Point(0,0),\n        this.checkerboardImage.strokeWidth = 0,\n        this.checkerboardImage.scale(Math.max(this.width, this.height) / 1024),\n        this.drawingLayer = new ce.Group({\n          name: \"Drawing\",\n          blendMode: \"destination-atop\"\n        }),\n        this.undoLayer = new ce.Group({\n          name: \"Undo\",\n          visible: !1\n        }),\n        this.redoLayer = new ce.Group({\n          name: \"Redo\",\n          visible: !1\n        }),\n        ce.project.activeLayer.addChildren(new ce.Group({\n          name: \"CheckerboardCompositingGroup\",\n          children: [this.checkerboardImage, this.drawingLayer],\n          blendMode: \"source-over\",\n          opacity: .4\n        }), this.undoLayer),\n        ce.project.activeLayer.addChild(this.redoLayer),\n        ce.view.onFrame = p=>{\n          this.checkerboardImage.visible = !1;\n          for (let d = 0; d < this.drawingLayer.children.length; d++)\n            if (this.drawingLayer.children[d].bounds.area > 0) {\n              this.checkerboardImage.visible = !0;\n              break\n            }\n        }\n        ,\n        ce.view.onResize = this.onResize.bind(this);\n      let a = !1;\n      this.toolbar = document.getElementById(\"appbody\"),\n        this.toolbar.addEventListener(\"mousedown\", p=>{\n            a = !0\n          }\n        ),\n        document.body.addEventListener(\"mouseup\", p=>{\n            a = !1,\n              this.toolbar.classList.remove(\"fadeout\")\n          }\n        );\n      let h = document.getElementById(\"popover-container\");\n      document.addEventListener(\"mousemove\", p=>{\n          p.buttons\n        }\n      ),\n        ce.view.onMouseMove = p=>{\n          !(p.event.buttons === 1) || a || h.classList.add(\"fadeout\")\n        }\n        ,\n        ce.view.onMouseDown = ce.view.onMouseMove,\n        ce.view.onMouseUp = p=>{\n          h.classList.remove(\"fadeout\")\n        }\n        ,\n        ce.view.onMouseLeave = p=>{\n          h.classList.remove(\"fadeout\")\n        }\n        ,\n        document.getElementById(\"Undo\").addEventListener(\"click\", ()=>{\n            this.undo()\n          }\n          , !1),\n        document.getElementById(\"Rect Tool\").addEventListener(\"click\", ()=>{\n            this.selectedTool = 0,\n              this.highlightSelected()\n          }\n          , !1),\n        document.getElementById(\"Lasso Tool\").addEventListener(\"click\", ()=>{\n            this.selectedTool = .5,\n              this.highlightSelected()\n          }\n          , !1),\n        this.bottomBar = document.getElementById(\"bottomBar\"),\n        this.promptBar = document.getElementById(\"Prompt\"),\n        this.promptBar.addEventListener(\"paste\", p=>{\n            p.preventDefault(),\n              p.stopPropagation();\n            let d = (p.originalEvent || p).clipboardData.getData(\"text/plain\");\n            document.execCommand(\"insertText\", !1, d)\n          }\n        ),\n        this.submitLabel = document.getElementById(\"submit-label\"),\n        this.submitButton = document.getElementById(\"Submit\"),\n        this.submitButton.addEventListener(\"click\", async p=>{\n            let d = p.target;\n            if (d instanceof HTMLButtonElement && !(d.disabled || d.dataset?.state === \"loading\")) {\n              Ti(d);\n              try {\n                await this.submit().catch(M=>this.displayError(M?.toString()))\n              } finally {\n                Ii(d)\n              }\n            }\n          }\n          , !1),\n      this.has_prompt_enabled && (this.bottomBar.classList.remove(\"noFill\"),\n        this.promptBar.classList.remove(\"hidden\"),\n        this.submitButton.classList.remove(\"withText\"),\n        this.submitLabel.innerText = \"\",\n        this.onboarding.setPromptBarAvailable(!0)),\n        setInterval(()=>{\n            this.submitButton instanceof HTMLButtonElement && (this.submitButton.disabled = this.drawingLayer.children.length === 0)\n          }\n          , 100),\n      this.prompt && (this.promptBar.textContent = this.prompt),\n        this.highlightSelected(),\n        this.onResize(),\n        this.backgroundImage = new ce.Raster(this.backgroundImageElement),\n        this.backgroundImage.name = \"BackgroundImage\",\n        this.backgroundImage.position = new ce.Point(0,0),\n        this.backgroundImage.strokeWidth = 0,\n        this.backgroundImage.insertBelow(this.drawingLayer.parent),\n        this.canvas.setAttribute(\"oncontextmenu\", \"return false;\"),\n        ce.settings.handleSize = 0;\n      try {\n        let p = window.localStorage.getItem(this.imageURL);\n        p && ce.project.importSVG(p, {\n          expandShapes: !0,\n          insert: !1,\n          onLoad: M=>{\n            M.translate(new ce.Point(-this.width / 2,-this.height / 2)),\n              M.getItems({\n                recursive: !0\n              }).forEach(F=>{\n                  F.name == this.drawingLayer.name ? this.drawingLayer.children = F.children : F.name == this.undoLayer.name ? this.undoLayer.children = F.children : F.name == this.redoLayer.name && (this.redoLayer.children = F.children)\n                }\n              ),\n            this.inIFrame && (document.getElementById(\"popover-container\").innerHTML = \"\")\n          }\n          ,\n          onError: M=>{\n            console.error(M)\n          }\n        });\n        let d = window.localStorage.getItem(this.imageURL + \"-Prompt\");\n        d && (this.prompt = d,\n          this.promptBar.textContent = d)\n      } catch (p) {\n        console.log(\"Couldn't load Local Storage\", p)\n      }\n      Ai(),\n        this.onboarding.start()\n    }\n    onKeyDown(a) {\n      this.keymap.add(a.key)\n    }\n    onKeyUp(a) {\n      if (this.keymap.delete(a.key),\n      a.key === \"Escape\") {\n        let h = document.getElementById(\"Prompt\");\n        h == document.activeElement ? h.blur() : this.close(\"User Exited\")\n      }\n    }\n    onResize(a) {\n      let h = 0;\n      if (a && a.canonicalSpace)\n        ce.view.viewSize.set(this.width / window.devicePixelRatio, this.height / window.devicePixelRatio),\n          ce.view.zoom = 1 / window.devicePixelRatio;\n      else {\n        let d = this.toolbar.getBoundingClientRect().height * 1.75;\n        h = d;\n        let M = this.canvas.width / window.devicePixelRatio\n          , F = this.canvas.height / window.devicePixelRatio;\n        ce.view.zoom = Math.max(.01, Math.min(M / this.width, (F - d) / this.height) * .95)\n      }\n      ce.view.translate(new ce.Point(ce.view.center.x,ce.view.center.y - h * .5 / ce.view.zoom)),\n        ce.view.update()\n    }\n    undo() {\n      this.processDoCommand(this.drawingLayer, this.undoLayer, this.redoLayer)\n    }\n    redo() {\n      this.processDoCommand(this.drawingLayer, this.redoLayer, this.undoLayer)\n    }\n    close(a=\"Job Submitted!\") {\n      this.discord != null && this.discord.close(ci.CLOSE_NORMAL, a)\n    }\n    processDoCommand(a, h, p) {\n      let d = h.lastChild;\n      if (d)\n        if (d.name && d.name.startsWith(this.removeCmd)) {\n          let M = d.name.substring(this.removeCmd.length)\n            , F = a.getItem({\n            match: Z=>Z.name == M\n          });\n          p.addChild(F),\n            d.remove()\n        } else {\n          let M = a.getItem({\n            match: F=>F.name == d.name\n          });\n          if (M) {\n            let F = M.clone();\n            F.name = M.name,\n              p.addChild(F),\n              M.replaceWith(d)\n          } else\n            a.addChild(d),\n              p.addChild(new ce.Group({\n                name: this.removeCmd + d.name\n              }))\n        }\n    }\n    async submit() {\n      document.getElementById(\"popover-container\").innerHTML = \"\",\n        document.getElementById(\"Prompt\").blur();\n      let a = this.drawingLayer.children.length\n        , h = this.drawingLayer.children;\n      if (console.log({\n        childLength: a\n      }),\n      a == 0) {\n        hn({\n          header: \"请进行选择\",\n          content: \"要使用修复功能，请开始拖动以选择您想要替换的图像区域。\",\n          footer: this.createDefaultCloseButton(\"好的\")\n        });\n        return\n      }\n      let p = 0;\n      for (let ye = 0; ye < a; ye++) {\n        let oe = h[ye];\n        oe.name.includes(\"Image\") || (p += oe.bounds.width * oe.bounds.height)\n      }\n      if (p < 1e4) {\n        hn({\n          header: \"选择的区域太小了\",\n          content: \"为了获得最佳效果，您需要选择更多的图像来替换。\",\n          footer: this.createDefaultCloseButton(\"好的\")\n        });\n        return\n      }\n      let d = document.getElementById(\"Prompt\").textContent\n        , M = ce.view.viewSize.width\n        , F = ce.view.viewSize.height;\n      this.omniTool.clearSelection(),\n        ce.project.activeLayer.selected = !1,\n      this.currentPath && (this.currentPath.bounds.selected = !1);\n      let Z = this.drawingLayer.parent.opacity;\n      this.drawingLayer.parent.opacity = 1,\n        this.drawingLayer.blendMode = \"normal\",\n        this.checkerboardImage.visible = !1,\n       // console.log(\"Submitting Job...\"),\n        this.onResize({\n          canonicalSpace: !0\n        });\n      let q = ce.project.exportSVG({\n        asString: !0\n      })\n        , k = q.indexOf(\"<image\")\n        , O = q.indexOf(\"/>\", k);\n      q = q.substring(0, k) + q.substring(O + 2),\n        k = q.indexOf(\"<image\"),\n        O = q.indexOf(\"/>\", k),\n        q = q.substring(0, k) + q.substring(O + 2),\n        q = q.replace(/width=\"\\d*\\.?\\d+\" height=\"\\d*\\.?\\d+\" viewBox=\"0,0,\\d*\\.?\\d+,\\d*\\.?\\d+\"/g, 'width=\"' + this.width + '\" height=\"' + this.height + '\" viewBox=\"0,0,' + this.width + \",\" + this.height + '\"'),\n        q = q.replace(/transform=\"translate\\(\\d*\\.?\\d+,\\d*\\.?\\d+\\) scale\\(\\d*\\.?\\d+,\\d*\\.?\\d+\\)\"/g, 'transform=\"translate(' + this.width / 2 + \",\" + this.height / 2 + ') scale(1.0,1.0)\"');\n      try {\n        window.localStorage.setItem(this.imageURL, q),\n          window.localStorage.setItem(this.imageURL + \"-Prompt\", d)\n      } catch (ye) {\n        console.log(\"Cannot access local storage!\", ye)\n      }\n      let B = new ce.Path.Rectangle(ce.view.bounds);\n      B.fillColor = \"white\",\n        B.sendToBack();\n      for (let ye = 0; ye < a; ye++) {\n        let oe = h[ye];\n        oe.name.includes(\"Image\") || (oe.visible = !0)\n      }\n      let C = []\n        , Q = this.backgroundImage;\n      if (Q.name && Q.visible && Q.name.includes(\"Image\")) {\n        let ye = new ce.Path.Rectangle(Q.bounds);\n        ye.fillColor = \"black\",\n          ye.insertAbove(Q),\n          ye.name = \"Occluder\",\n          C.push(ye)\n      }\n      this.omniTool.clearSelection(),\n        ce.project.activeLayer.selected = !1,\n      this.currentPath && (this.currentPath.bounds.selected = !1),\n        this.onResize({\n          canonicalSpace: !0\n        }),\n        ce.view.update(),\n        this.omniTool.clearSelection(),\n        ce.project.activeLayer.selected = !1,\n      this.currentPath && (this.currentPath.bounds.selected = !1),\n        this.onResize({\n          canonicalSpace: !0\n        });\n      let J = ce.view.getContext()\n        , ne = J.getImageData(0, 0, this.canvas.width / window.devicePixelRatio, this.canvas.height / window.devicePixelRatio)\n        , Y = ne.data;\n      for (let ye = 0; ye < Y.length; ye += 4)\n        Y[ye + 0] = Y[ye + 0] > 128 ? 255 : 0,\n          Y[ye + 1] = Y[ye + 1] > 128 ? 255 : 0,\n          Y[ye + 2] = Y[ye + 2] > 128 ? 255 : 0,\n          Y[ye + 3] = 255;\n      J.putImageData(ne, 0, 0);\n      let Me = this.canvas.toDataURL(\"image/\"+this.imgInfo.img_type, 1)\n        , le = document.createElement(\"a\");\n      this.inIFrame || (le.download = \"drawingExportMask.webp\",\n        le.href = Me,\n        le.click());\n      for (let ye = 0; ye < C.length; ye++)\n        C[ye].remove();\n      B.remove(),\n        ce.view.viewSize.set(M, F),\n        ce.view.update(),\n        this.onResize(),\n        this.drawingLayer.parent.opacity = Z,\n        this.drawingLayer.blendMode = \"destination-atop\",\n        this.checkerboardImage.visible = !0,\n      this.inIFrame || await new Promise(ye=>setTimeout(ye, 2e3));\n      let Se = Me.split(\",\")[1];\n      let ret = {\n        username: this.userName,\n        userId: this.userId,\n        customId: this.customId,\n        prompt: d,\n        full_prompt: null,\n        mask: Se\n      };\n      //localStorage.setItem(\"mj-iframe-btn-click\",\"1\");\n      //localStorage.setItem(\"mj-iframe-btn-click-ret\",JSON.stringify(ret));\n      window.parent.postMessage( JSON.stringify(ret) , '*' )\n    }\n    async submitToBackend(a, h, p, d, M, F=null,aid) {\n      let Z = await fetch(\"https://\"+aid+\".discordsays.com/inpaint/api/submit-job\", {\n        method: \"POST\",\n        mode: \"cors\",\n        cache: \"no-cache\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n          Accept: \"application/json\"\n        },\n        body: JSON.stringify({\n          username: a,\n          userId: h,\n          customId: p,\n          mask: d,\n          prompt: M,\n          full_prompt: F\n        })\n      });\n      return Z.status == 200 ? (Z = await Z.json(),\n      !this.keymap.has(\"Shift\") && !this.keymap.has(\"Alt\") && (this.close(),\n        hn({\n          header: \"Job Submitted!\",\n          content: \"Your job was submitted successfully! You can now close this window, or make additional edits.\",\n          footer: this.createDefaultCloseButton()\n        })),\n        Z) : 400 <= Z.status < 500 ? (Z = await Z.json(),\n        console.error(\"Received Error Response!\", Z),\n        hn({\n          header: \"Error\",\n          content: Z.message,\n          footer: this.createDefaultCloseButton()\n        }),\n        Z) : (hn({\n        header: \"Error\",\n        content: \"There was an error submitting your job. Please try again later.\",\n        footer: this.createDefaultCloseButton()\n      }),\n        null)\n    }\n    createDefaultCloseButton(a=\"Close\") {\n      let h = document.createElement(\"button\");\n      return h.className = \"modal-button\",\n        h.addEventListener(\"click\", Ai),\n        h.innerText = a,\n        h\n    }\n    displayError(a) {\n      hn({\n        header: \"\\u274C Submission Error!\",\n        content: `<p id=\"errorMessage\">${Wn(a)}</p>`,\n        footer: this.createDefaultCloseButton()\n      })\n    }\n    highlightSelected() {\n      let a = document.getElementById(\"Rect Tool\")\n        , h = document.getElementById(\"Lasso Tool\");\n      a.classList.remove(\"selected\"),\n        h.classList.remove(\"selected\"),\n        this.selectedTool == 0 ? a.classList.add(\"selected\") : this.selectedTool == .5 && h.classList.add(\"selected\")\n    }\n    loadImageAsync(a) {\n      return new Promise((h,p)=>{\n          let d = new Image;\n          d.src = a,\n            d.crossOrigin = \"anonymous\",\n            d.onload = ()=>h(d),\n            d.onerror = ()=>p(new Error(\"could not load image\"))\n        }\n      )\n    }\n    forPageLoadAsync() {\n      return new Promise(a=>{\n          document.readyState === \"complete\" ? a() : window.onload = a.bind(this)\n        }\n      )\n    }\n  }\n;\nwindow.inpaintingEditor = new ur;\nexport {ur as InpaintingEditor};\n/*!\n * Paper.js v0.12.17 - The Swiss Army Knife of Vector Graphics Scripting.\n * http://paperjs.org/\n *\n * Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey\n * http://juerglehni.com/ & https://puckey.studio/\n *\n * Distributed under the MIT license. See LICENSE file for details.\n *\n * All rights reserved.\n *\n * Date: Thu Nov 3 21:15:36 2022 +0100\n *\n ***\n *\n * Straps.js - Class inheritance library with support for bean-style accessors\n *\n * Copyright (c) 2006 - 2020 Jürg Lehni\n * http://juerglehni.com/\n *\n * Distributed under the MIT license.\n *\n ***\n *\n * Acorn.js\n * https://marijnhaverbeke.nl/acorn/\n *\n * Acorn is a tiny, fast JavaScript parser written in JavaScript,\n * created by Marijn Haverbeke and released under an MIT license.\n *\n */\n"
  },
  {
    "path": "src/static/mitf/assets/style.css",
    "content": "/* reset */\n* {\n  padding: 0;\n  margin: 0;\n  box-sizing: border-box;\n}\n\n/* variables */\n:root {\n  --sait: var(--discord-safe-area-inset-top, env(safe-area-inset-top));\n  --saib: var(--discord-safe-area-inset-bottom, env(safe-area-inset-bottom));\n  --sail: var(--discord-safe-area-inset-left, env(safe-area-inset-left));\n  --sair: var(--discord-safe-area-inset-right, env(safe-area-inset-right));\n\n  --mono-100: 227, 5%, 100%;\n  --mono-200: 227, 5%, 95%;\n  --mono-300: 227, 5%, 70%;\n  --mono-400: 227, 5%, 58%;\n  --mono-500: 227, 5%, 50%;\n  --mono-600: 227, 5%, 40%;\n  --mono-700: 227, 5%, 35%;\n\n  --discord-bg: rgb(49, 51, 56);\n  --discord-overlay: #232428c4;\n}\n\n/* set if html tag has data-color-mode set to dark theme */\nhtml[data-theme=\"light\"] {\n  --mono-100: 227, 5%, 10%;\n  --mono-200: 227, 5%, 25%;\n  --mono-300: 227, 5%, 35%;\n  --mono-400: 227, 5%, 40%;\n  --mono-500: 227, 5%, 60%;\n  --mono-600: 227, 5%, 75%;\n  --mono-700: 227, 5%, 87%;\n\n  --discord-bg: white;\n  --discord-overlay: #e0e1e2c4;\n}\n\n/**\n * Motion\n */\n\n@keyframes slideInTop {\n  from {\n    opacity: 0;\n    transform: translateY(-16px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes slideInBottom {\n  from {\n    opacity: 0;\n    transform: translateY(16px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\nhtml {\n  /* background-color: var(--discord-bg); */\n  color: hsl(var(--mono-100));\n  font-family: \"gg sans\", \"Noto Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\nbody {\n  padding-left: var(--sail);\n  padding-right: var(--sair);\n  padding-top: var(--sait);\n  padding-bottom: var(--saib);\n}\n\n/* Scale canvas with resize attribute to full size */\ncanvas[resize] {\n  width: 100%;\n  height: 100%;\n}\n\n/* Styles for the parent container */\n\n.hidden {\n  display: none !important;\n}\n\n.hstack {\n  display: flex;\n  gap: 4px;\n}\n\n.center {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  width: 100%;\n}\n\n#container {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100vw;\n  height: 100vh;\n}\n\n#appbody {\n  height: fit-content;\n  position: fixed;\n  display: flex;\n  bottom: 16px;\n  left: 0;\n  right: 0;\n  width: 100%;\n\n  justify-content: space-between;\n  transition: opacity 0.17s ease;\n  padding-inline: 4px;\n  z-index: 1;\n}\n\n@media (min-width: 640px) {\n  #appbody {\n    max-width: 70vw;\n    margin: 0 auto;\n  }\n  #bottomBarWrapper {\n    border-radius: 19px;\n  }\n\n}\n\n.toolButton {\n  flex-shrink: 0;\n  align-self: flex-end;\n  position: relative;\n  width: 38px; /* match discord's style */\n  height: 38px;\n  margin-right: 8px;\n  margin-left: 0px\n}\n\n.fadeout {\n  opacity: 0;\n}\n\n#buttonContainer {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\nbutton {\n  display: flex;\n  position: relative;\n  width: 38px; /* match discord's style */\n  height: 38px;\n  box-sizing: border-box;\n  -webkit-box-direction: normal;\n  -webkit-box-pack: center;\n  -webkit-box-align: center;\n  cursor: pointer;\n  justify-content: center;\n  align-items: center;\n  user-select: none;\n  color: hsla(var(--mono-100), 0.8);\n  background-color: hsla(var(--mono-700), 0.6);\n  backdrop-filter: blur(5px);\n  -webkit-backdrop-filter: blur(5px);\n  border: none;\n  outline-offset: -1px;\n  border-radius: 48px;\n}\nbutton:hover {\n  background-color: hsla(var(--mono-700), 0.8);\n  transition: background-color .17s ease, border .17s ease;\n}\nbutton:active {\n  background-color: hsla(var(--mono-300), 0.8);\n  transition: background-color .01s ease, border .01s ease;\n}\nbutton:disabled {\n  opacity: 0.2;\n  cursor: not-allowed;\n}\nbutton.selected {\n  background-color: hsla(var(--mono-500), 0.8);\n  transition: background-color .17s ease, border 0.17s ease;\n}\n\n@keyframes spinner {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n.spinner-container {\n  padding: 4px;\n  z-index: 1;\n  position: absolute;\n  inset: 0;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.spinner {\n  animation: spinner 1s linear infinite;\n  fill: hsla(var(--mono-200), 0.85);\n}\n\n.loading-container {\n  opacity: 0;\n  transition: opacity 0.17s ease;\n}\n\n.Submit {\n  border: none;\n  outline: none;\n  border-radius: 32px;\n  background: none;\n  position: relative;\n  display: flex;\n  backdrop-filter: none;\n  -webkit-backdrop-filter: none;\n  height: 28px;\n  width: 28px;\n  background-color: hsla(var(--mono-200), 1.0);\n}\n.Submit svg {\n  color: hsl(var(--mono-700));\n  width: 14px;\n  height: 14px;\n  pointer-events: none;\n}\n.Submit svg:hover{\n  transition: fill .17s ease;\n}\n.Submit svg:active{\n  transition: fill .17s ease;\n}\n.Submit[data-state=\"loading\"] {\n  background-color: hsla(var(--mono-200), 0.2);\n  cursor: not-allowed;\n}\n\n.withText {\n  background-color: transparent;\n  padding-inline: 8px;\n  gap: 12px;\n  width: unset !important;\n}\n\n.withText svg {\n  color: hsla(var(--mono-200), 0.85);\n}\n\n#Undo {\n  margin-left: 8px;\n}\n\n.no-animation {\n  animation: none !important;\n}\n\n.textarea {\n  /* 2.5x line-height */\n  max-height: 56px;\n  background-color: transparent;\n  border: none;\n  color: hsla(var(--mono-100), 1.0);\n  font-size: 16px;\n  line-height: 1.4;\n  resize: none;\n  outline: none;\n  outline-offset: 0px;\n\n  padding-inline-start: 8px;\n  flex: 1;\n  display: block;\n  overflow: auto;\n  resize: none;\n  white-space: break-spaces;\n  word-break: normal;\n  font-family: \"gg sans\", \"Noto Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  -webkit-appearance: none;\n  appearance: none;\n  transition: max-height 0.17s ease;\n}\n.textarea[placeholder]:empty:before {\n  content: attr(placeholder);\n  color: hsla(var(--mono-100), 0.6);\n}\n.textarea[placeholder]:empty:focus:before {\n  content: \"\";\n}\n.textarea:focus, .textarea:active {\n  box-shadow: none;\n  max-height: unset;\n}\n\n/* hide the scrollbar to avoid overlap with the submit button */\n.textarea::-webkit-scrollbar {\n  display: none;\n}\n\n@media (max-width: 640px) {\n  .textarea {\n    min-width: auto;\n  }\n\n  .Submit {\n    width: 38px;\n    height: 38px;\n  }\n\n  .toolButton {\n    width: 48px; /* match discord's style */\n    height: 48px;\n  }\n}\n\n#submit-label {\n  pointer-events: none;\n}\n\n#loadingModal {\n  display: flex;\n}\n\n#splashPageModal {\n  display: none;\n}\n\n#jobSubmittedModal {\n  display: none;\n}\n\n#jobErroredModal {\n  display: none;\n}\n\n.undoButtons {\n  position: fixed;\n  top: 16px;\n  left: 8px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  flex-direction: row;\n}\n\n.bottomBarWrapper {\n  display: flex;\n  flex-direction: row;\n  overflow: hidden;\n  align-items: center;\n  border: none;\n  /* border: 1px solid hsl(var(--mono-400)); */\n  padding-inline: 4px;\n  padding-block: 4px;\n  box-sizing: border-box;\n  border-radius: 24px;\n  background-color: hsla(var(--mono-700), 0.6);\n  backdrop-filter: blur(5px);\n  -webkit-backdrop-filter: blur(5px);\n  width: 100%;\n  gap: 4px;\n}\n.noFill {\n  width: unset;\n}\n\n/**\n * Tutorial overlay\n */\n\n#popover-container {\n  position: absolute;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  pointer-events: none;\n  z-index: 10;\n}\n\n.popover {\n  border: 1px solid hsla(var(--mono-100), 0.1);\n  position: absolute;\n  top: 16px;\n  z-index: 10;\n  padding-inline: 16px;\n  padding-block: 9px;\n  border-radius: 100px;\n  font-size: 16px;\n  max-width: 90vw;\n  background-color: var(--discord-overlay);\n  animation: slideInTop 0.3s ease;\n  transition: opacity 0.3s ease;\n  box-shadow: 0 2px 10px 0 rgba(0,0,0,0.09);\n}\n\n@media (max-width: 640px) {\n  .popover {\n    top: 64px;\n  }\n\n  @media (max-height: 500px) {\n    .popover {\n      opacity: 0;\n    }\n  }\n}\n\n/**\n * Modals\n */\n\n.modal {\n  display: flex;\n  position: fixed;\n  justify-content: center;\n  align-items: center;\n  left: 0;\n  top: 0;\n  padding-inline: 8px;\n  width: 100%; /* Full width */\n  height: 100%; /* Full height */\n  overflow: auto; /* Enable scroll if needed */\n}\n\n.modal-backdrop {\n  position: fixed;\n  z-index: 2;\n  inset: 0;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0,0,0,0.4);\n  animation: fadeIn 0.3s ease;\n}\n\n.modal-body {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n  z-index: 3;\n  max-width: 420px;\n  background-color: var(--discord-bg);\n  border-radius: 8px;\n  padding: 16px;\n  box-sizing: border-box;\n  animation: slideInBottom 0.2s ease;\n}\n\n.modal-header {\n  font-size: 18px;\n  font-weight: 600;\n}\n\n.modal-content {\n  color: hsla(var(--mono-100), 0.6);\n}\n\n.modal-footer {\n  width: 100%;\n  display: flex;\n  justify-content: flex-end;\n}\n\n.modal-button {\n  border-radius: 4px;\n  background-color: hsl(var(--mono-500));\n  color: hsl(var(--mono-100));\n  padding: 8px 16px;\n  flex-shrink: 0;\n  width: unset;\n  height: unset;\n}\n"
  },
  {
    "path": "src/static/mitf/index.html",
    "content": "\n<!DOCTYPE html>\n<html lang=\"en\"><head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n  <title>局部绘画组件</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=0, shrink-to-fit=0\">\n  <meta name=\"theme-color\" content=\"#ffffff\">\n  <link rel=\"stylesheet\" href=\"assets/style.css\">\n</head>\n<body style=\"overflow:hidden;\">\n\n<script type=\"text/javascript\" nonce=\"\">\n  RTCPeerConnection = null;\n  WebTransport = null;\n</script>\n<script type=\"text/javascript\" nonce=\"\">\n  // Set the theme based on the parent iframe's colorScheme. This is how\n  // Discord communicates the user's theme to us.\n  if (window.parent) {\n    let iframes = window.parent.document.getElementsByTagName('iframe');\n    for (var i = 0; i < iframes.length; i++) {\n      if (iframes[i].contentWindow === window) {\n        var myMetadata = iframes[i];\n\n        document.documentElement.setAttribute(\n          \"data-theme\",\n          myMetadata.style.colorScheme || \"dark\"\n        );\n      }\n    }\n  }\n</script>\n<h1 hidden=\"\"></h1> <!-- Necessary for lighthouse score -->\n<div id=\"popover-container\"><div class=\"popover\">Drag to select the area to be changed</div></div>\n\n<div id=\"container\" class=\"center\">\n  <canvas id=\"InpaintingEditorCanvas\" hidpi=\"on\" width=\"1920\" height=\"1616\" resize=\"\" style=\"padding: 0px; margin: 0px; width: 100%; max-width: 960px; -webkit-user-drag: none; user-select: none; touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\" oncontextmenu=\"return false;\"></canvas>\n</div>\n\n<div class=\"undoButtons\">\n  <button title=\"Undo\" id=\"Undo\">\n    <svg width=\"20px\" height=\"20px\" version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 20.298 20.298\" xml:space=\"preserve\">\n                    <path fill=\"currentColor\" d=\"M0.952,11.102c0-0.264,0.213-0.474,0.475-0.474h2.421c0.262,0,0.475,0.21,0.475,0.474 c0,3.211,2.615,5.826,5.827,5.826s5.827-2.615,5.827-5.826c0-3.214-2.614-5.826-5.827-5.826c-0.34,0-0.68,0.028-1.016,0.089 v1.647c0,0.193-0.116,0.367-0.291,0.439C8.662,7.524,8.46,7.482,8.322,7.347L3.49,4.074c-0.184-0.185-0.184-0.482,0-0.667 l4.833-3.268c0.136-0.136,0.338-0.176,0.519-0.104c0.175,0.074,0.291,0.246,0.291,0.438V1.96c0.34-0.038,0.68-0.057,1.016-0.057 c5.071,0,9.198,4.127,9.198,9.198c0,5.07-4.127,9.197-9.198,9.197C5.079,20.299,0.952,16.172,0.952,11.102z\"></path>\n                </svg>\n  </button>\n  <button title=\"Redo\" id=\"Redo\" style=\"display: none;\">\n    <svg width=\"20px\" height=\"20px\" version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 20.298 20.298\" xml:space=\"preserve\">\n                    <g transform=\"scale(-1, 1) translate(-20, 0)\">\n                        <path d=\"M0.952,11.102c0-0.264,0.213-0.474,0.475-0.474h2.421c0.262,0,0.475,0.21,0.475,0.474 c0,3.211,2.615,5.826,5.827,5.826s5.827-2.615,5.827-5.826c0-3.214-2.614-5.826-5.827-5.826c-0.34,0-0.68,0.028-1.016,0.089 v1.647c0,0.193-0.116,0.367-0.291,0.439C8.662,7.524,8.46,7.482,8.322,7.347L3.49,4.074c-0.184-0.185-0.184-0.482,0-0.667 l4.833-3.268c0.136-0.136,0.338-0.176,0.519-0.104c0.175,0.074,0.291,0.246,0.291,0.438V1.96c0.34-0.038,0.68-0.057,1.016-0.057 c5.071,0,9.198,4.127,9.198,9.198c0,5.07-4.127,9.197-9.198,9.197C5.079,20.299,0.952,16.172,0.952,11.102z\" fill=\"currentColor\"></path>\n                    </g>\n                </svg>\n  </button>\n</div>\n\n<div id=\"appbody\" class=\"center\">\n  <div class=\"hstack\">\n    <button title=\"Rectangle Tool\" id=\"Rect Tool\" class=\"toolButton selected\">\n      <svg class=\"svg-icon\" width=\"20px\" height=\"20px\" style=\"vertical-align: middle;overflow: hidden;\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n        <path d=\"M768 42.65984l85.34016 0q53.00224 0 90.50112 37.49888t37.49888 90.50112l0 85.34016q0 17.67424-12.4928 30.16704t-30.16704 12.4928-30.16704-12.4928-12.4928-30.16704l0-85.34016q0-17.67424-12.4928-30.16704t-30.16704-12.4928l-85.34016 0q-17.67424 0-30.16704-12.4928t-12.4928-30.16704 12.4928-30.16704 30.16704-12.4928zM85.34016 725.34016q17.67424 0 30.16704 12.4928t12.4928 30.16704l0 85.34016q0 17.67424 12.4928 30.16704t30.16704 12.4928l85.34016 0q17.67424 0 30.16704 12.4928t12.4928 30.16704-12.4928 30.16704-30.16704 12.4928l-85.34016 0q-53.00224 0-90.50112-37.49888t-37.49888-90.50112l0-85.34016q0-17.67424 12.4928-30.16704t30.16704-12.4928zM85.34016 384q17.67424 0 30.16704 12.4928t12.4928 30.16704l0 170.65984q0 17.67424-12.4928 30.16704t-30.16704 12.4928-30.16704-12.4928-12.4928-30.16704l0-170.65984q0-17.67424 12.4928-30.16704t30.16704-12.4928zM426.65984 896l170.65984 0q17.67424 0 30.16704 12.4928t12.4928 30.16704-12.4928 30.16704-30.16704 12.4928l-170.65984 0q-17.67424 0-30.16704-12.4928t-12.4928-30.16704 12.4928-30.16704 30.16704-12.4928zM170.65984 42.65984l85.34016 0q17.67424 0 30.16704 12.4928t12.4928 30.16704-12.4928 30.16704-30.16704 12.4928l-85.34016 0q-17.67424 0-30.16704 12.4928t-12.4928 30.16704l0 85.34016q0 17.67424-12.4928 30.16704t-30.16704 12.4928-30.16704-12.4928-12.4928-30.16704l0-85.34016q0-53.00224 37.49888-90.50112t90.50112-37.49888zM938.65984 725.34016q17.67424 0 30.16704 12.4928t12.4928 30.16704l0 85.34016q0 53.00224-37.49888 90.50112t-90.50112 37.49888l-85.34016 0q-17.67424 0-30.16704-12.4928t-12.4928-30.16704 12.4928-30.16704 30.16704-12.4928l85.34016 0q17.67424 0 30.16704-12.4928t12.4928-30.16704l0-85.34016q0-17.67424 12.4928-30.16704t30.16704-12.4928zM938.65984 384q17.67424 0 30.16704 12.4928t12.4928 30.16704l0 170.65984q0 17.67424-12.4928 30.16704t-30.16704 12.4928-30.16704-12.4928-12.4928-30.16704l0-170.65984q0-17.67424 12.4928-30.16704t30.16704-12.4928zM426.65984 42.65984l170.65984 0q17.67424 0 30.16704 12.4928t12.4928 30.16704-12.4928 30.16704-30.16704 12.4928l-170.65984 0q-17.67424 0-30.16704-12.4928t-12.4928-30.16704 12.4928-30.16704 30.16704-12.4928z\" fill=\"currentColor\"></path>\n      </svg>\n    </button>\n    <button title=\"Lasso Tool\" id=\"Lasso Tool\" class=\"toolButton\">\n      <svg width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n        <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M5.00001 10C5.00001 8.75523 5.7133 7.52938 7.06628 6.57433C8.41665 5.62113 10.3346 5 12.5 5C14.6654 5 16.5834 5.62113 17.9337 6.57433C19.2867 7.52938 20 8.75523 20 10C20 11.2448 19.2867 12.4706 17.9337 13.4257C16.5834 14.3789 14.6654 15 12.5 15C11.9849 15 11.4828 14.9648 10.9982 14.898C10.934 13.1045 9.18159 12 7.50001 12C6.92753 12 6.37589 12.1176 5.88506 12.3351C5.30127 11.6111 5.00001 10.8126 5.00001 10ZM12.5 17C11.7421 17 11.0036 16.9352 10.2949 16.8124C10.2111 16.9074 10.1215 16.9971 10.027 17.0814C10.0324 17.1351 10.0364 17.1937 10.0381 17.2566C10.0459 17.5458 10.0053 17.9424 9.80913 18.3641C9.38923 19.2667 8.42683 19.9562 6.7537 20.2187C4.68005 20.544 4.14608 21.1521 4.01748 21.3745C3.95033 21.4906 3.94254 21.5823 3.94406 21.6357C3.94468 21.6576 3.94702 21.6739 3.94861 21.6827C3.96296 21.7256 3.97448 21.7699 3.98295 21.8152C4.03316 22.0804 3.97228 22.3491 3.826 22.5638C3.74444 22.6836 3.63632 22.7865 3.50609 22.8627C3.40769 22.9205 3.29851 22.962 3.1823 22.9834C3.06521 23.0053 2.94748 23.0055 2.83406 22.9863C2.687 22.9617 2.55081 22.9051 2.43293 22.8238C2.31589 22.7434 2.21506 22.6375 2.13982 22.5103C2.1012 22.4453 2.06973 22.3756 2.0465 22.3023C2.04333 22.2927 2.04 22.2823 2.03655 22.2711C2.02484 22.2331 2.01167 22.1856 1.99902 22.1296C1.97383 22.0181 1.94991 21.8695 1.94487 21.6927C1.93466 21.3347 2.00276 20.8633 2.28609 20.3733C2.85846 19.3834 4.12384 18.6068 6.4437 18.2429C6.8529 18.1787 7.15489 18.0908 7.37778 17.9981C5.70287 17.9451 4.00001 16.8095 4.00001 15C4.00001 14.4998 4.14018 14.0417 4.37329 13.6452C3.52173 12.6101 3.00001 11.3665 3.00001 10C3.00001 7.93106 4.18951 6.15691 5.91292 4.94039C7.63895 3.72202 9.97098 3 12.5 3C15.029 3 17.3611 3.72202 19.0871 4.94039C20.8105 6.15691 22 7.93106 22 10C22 12.0689 20.8105 13.8431 19.0871 15.0596C17.3611 16.278 15.029 17 12.5 17ZM6.34227 14.3786C6.60474 14.1624 7.01132 14 7.50001 14C8.5482 14 9.00001 14.6444 9.00001 15C9.00001 15.0929 8.97952 15.185 8.9364 15.2772C8.85616 15.4487 8.687 15.6381 8.41217 15.7841C8.16534 15.9153 7.85219 16 7.50001 16C6.45182 16 6.00001 15.3556 6.00001 15C6.00001 14.8092 6.09212 14.5846 6.34227 14.3786Z\" fill=\"currentColor\"></path>\n      </svg>\n    </button>\n  </div>\n  <div id=\"bottomBar\" class=\"bottomBarWrapper\">\n    <div title=\"Write a prompt here\" class=\"textarea\" role=\"textbox\" contenteditable=\"true\" id=\"Prompt\" placeholder=\"用英文描述要修改的要求 如: sunglasses \"></div>\n    <button id=\"Submit\" class=\"Submit\" title=\"点我提交\" disabled=\"\">\n      <div id=\"submit-label\"></div>\n      <svg width=\"502\" height=\"496\" viewBox=\"0 0 502 496\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n        <path d=\"M176.518 454.8V361.136H29.9841C13.5252 361.136 0 347.598 0 331.102V164.89C0 148.437 13.4821 134.878 29.9841 134.878H176.496V41.1489C176.496 5.0694 219.423 -13.0675 245.438 10.8127L487.144 218.113C506.817 234.393 506.817 264.125 487.942 280.815L244.618 485.849C217.805 509.232 176.561 489.433 176.518 454.8Z\" fill=\"currentColor\"></path>\n      </svg>\n    </button>\n  </div>\n</div>\n\n<div id=\"modal-container\"></div>\n\n<div id=\"splashPageModal\" class=\"modal\">\n  <!-- Modal content -->\n  <div class=\"modal-content\">\n    <div style=\"align-items: center; padding-bottom: 16px; \">\n      <h1>Midjourney Inpainting Editor</h1>\n    </div>\n    <div>\n      <!--<p>Drag to highlight regions of the image to be replaced with new content from the prompt.</p>-->\n      <p>Use the controls below to select parts of the image to edit, and describe the entire image (including edits).</p>\n      <!--<p>For example, if you want to add a mouse to a cat image, select the part of the image you want to add the mouse and enter 'cat chasing a mouse'.</p>\n      <video width=\"444\" height=\"308\" autoplay loop muted playsinline>\n          <source src=\"./assets/Tutorial.webm\" type=\"video/webm\" />\n          <source src=\"./assets/Tutorial.mp4\" type=\"video/mp4\" />-->\n      Your browser does not support the video tag.\n\n      <hr>\n      <p>Click anywhere to begin!</p>\n    </div>\n  </div>\n</div>\n\n<div id=\"jobSubmittedModal\" class=\"modal\">\n  <!-- Modal content -->\n  <div class=\"modal-content\">\n    <div style=\"align-items: center; padding-bottom: 16px\">\n      <svg style=\"display:inline-block;\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-check-circle\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><polyline points=\"22 4 12 14.01 9 11.01\"></polyline></svg>\n      <h1 style=\"display:inline-block;\">Image submitted</h1>\n    </div>\n  </div>\n</div>\n\n<div id=\"jobErroredModal\" class=\"modal\">\n  <!-- Modal content -->\n  <div class=\"modal-content\">\n    <div style=\"align-items: center; padding-bottom: 16px\">\n      <h1>❌ Submission Error!</h1>\n    </div>\n    <div>\n      <p>Something went wrong when submitting this inpainting job!</p>\n      <hr>\n      <p id=\"errorMessage\"></p>\n    </div>\n  </div>\n</div>\n<script type=\"module\" src=\"assets/mj.js\"></script>\n\n\n</body></html>\n"
  },
  {
    "path": "src/store/helper.ts",
    "content": "import { createPinia } from 'pinia'\n\nexport const store = createPinia()\n"
  },
  {
    "path": "src/store/homeStore.ts",
    "content": "import { gptsType, mlog } from '@/api';\nimport { reactive } from 'vue'\nimport { ss } from '@/utils/storage'\n\nexport const homeStore = reactive({\n    myData:{\n        act:'',//动作\n        act2:'',//动作\n        actData:{} //动作类别 \n        ,local:'' //当前所处的版本\n        ,session:{} as any\n        ,isLoader:false\n        ,vtoken:'' //turnstile token\n        ,ctoken:'' //cookie\n        ,isClient: typeof window !== 'undefined' && window.__TAURI__\n        ,ms:{} as any\n        ,is_luma_pro:false\n        ,is_viggle_pro:false\n       \n    }\n    \n    ,setMyData( v:object){\n        this.myData={...this.myData,...v}; \n        if( Object.keys(v).indexOf('act')>-1){ \n            setTimeout(()=> {\n                this.myData.act=''\n                this.myData.actData=''\n            }, 2000 );\n        }\n        if( Object.keys(v).indexOf('act2')>-1){ \n            setTimeout(()=> {\n                this.myData.act2=''\n                this.myData.actData=''\n            }, 500 );\n        }\n    }\n \n})\n\nexport interface gptConfigType{\n    model:string\n    max_tokens:number\n    userModel?:string //自定义\n    talkCount:number //联系对话\n    systemMessage:string //自定义系统提示语\n    gpts?:gptsType\n    uuid?:number\n    temperature?:number // 随机性 : 值越大，回复越随机\n    top_p?:number // 核采样 : 与随机性类似，但不要和随机性一起更改\n    frequency_penalty?:number\n    presence_penalty?:number\n    tts_voice?:string //TTS 人物\n}\nconst getGptInt= ():gptConfigType =>{\n    let v:gptConfigType=getDefault();\n    let str = localStorage.getItem('gptConfigStore');\n    if(str){\n        let old = JSON.parse(str);\n        if(old) v={...v,...old};\n    }\n    return v;\n}\n\nconst  getDefault=()=>{\nconst amodel = homeStore.myData.session.amodel??'gpt-3.5-turbo'\nlet v:gptConfigType={\n        model: amodel,\n        max_tokens:1024,\n        userModel:'',\n        talkCount:10,\n        systemMessage:'',\n        temperature:0.5,\n        top_p:1,\n        presence_penalty:0,\n        frequency_penalty:0,\n        tts_voice:\"alloy\"\n    }\n    return v ;\n}\nexport const gptConfigStore= reactive({\n    myData:getGptInt(),\n    setMyData(v: Partial<gptConfigType>){\n\n         this.myData={...this.myData,...v}; \n         //mlog('gptConfigStore', v )\n         if(v.model && !v.gpts) this.myData.gpts=undefined;\n\n         localStorage.setItem('gptConfigStore', JSON.stringify( this.myData));\n    }\n    ,setInit(){\n        this.setMyData(getDefault());\n    }\n})\n\n\nexport interface gptServerType{\n    OPENAI_API_KEY:string\n    OPENAI_API_BASE_URL:string\n    MJ_SERVER:string\n    MJ_API_SECRET:string\n    UPLOADER_URL:string\n    MJ_CDN_WSRV?:boolean //wsrv.nl\n    SUNO_SERVER:string\n    SUNO_KEY:string\n    LUMA_SERVER:string\n    LUMA_KEY:string\n    VIGGLE_SERVER:string\n    VIGGLE_KEY:string\n    RUNWAY_SERVER:string\n    RUNWAY_KEY:string\n    IDEO_SERVER:string\n    IDEO_KEY:string\n    KLING_SERVER:string\n    KLING_KEY:string\n    PIKA_SERVER:string\n    PIKA_KEY:string\n    UDIO_SERVER:string\n    UDIO_KEY:string\n    PIXVERSE_SERVER:string\n    PIXVERSE_KEY:string\n    RIFF_SERVER:string\n    RIFF_KEY:string\n    IS_SET_SYNC?:boolean\n    GPTS_GX?:boolean\n    IS_LUMA_PRO?:boolean\n    RRUNWAY_VERSION?:string\n    DRAW_TYPE?:string\n    IS_VIGGLE_PRO?:boolean\n    TAB_VIDEO?:string\n    TTS_VOICE?:string\n    REALTIME_SYSMSG?:string\n    REALTIME_MODEL?:string\n    REALTIME_IS_WHISPER?:boolean \n    TAB_MUSIC?:string\n\n}\n\nconst  getServerDefault=()=>{\nlet v:gptServerType={\n        OPENAI_API_KEY:'',\n        OPENAI_API_BASE_URL:'',\n        MJ_SERVER:'',\n        UPLOADER_URL:'',\n        MJ_API_SECRET:'',\n        SUNO_KEY:'',\n        SUNO_SERVER:'',\n        MJ_CDN_WSRV:false\n        ,IS_SET_SYNC:true,\n        LUMA_SERVER:'',\n        LUMA_KEY:'',\n        VIGGLE_SERVER:'',\n        VIGGLE_KEY:'',\n        TAB_VIDEO:'all',\n        RUNWAY_SERVER:'',\n        RUNWAY_KEY:'',\n        IDEO_SERVER:'',\n        IDEO_KEY:'',\n        KLING_SERVER:'',\n        KLING_KEY:'',\n        PIKA_SERVER:'',\n        PIKA_KEY:'',\n        TTS_VOICE:'alloy',\n        UDIO_SERVER:'',\n        UDIO_KEY:'',\n        PIXVERSE_SERVER:'',\n        PIXVERSE_KEY:''\n    }\n    return v ;\n}\nconst getServerInit= ():gptServerType =>{\n    let v:gptServerType=getServerDefault();\n    let str = localStorage.getItem('gptServerStore');\n    if(str){\n        let old = JSON.parse(str);\n        if(old) v={...v,...old};\n    }\n    return v;\n}\n\nexport const gptServerStore= reactive({\n    myData:getServerInit(),\n    setMyData(v: Partial<gptServerType>){\n         this.myData={...this.myData,...v}; \n         localStorage.setItem('gptServerStore', JSON.stringify( this.myData));\n    }\n    ,setInit(){\n        this.setMyData(getServerDefault());\n    }\n})\n\n\nconst gptsUlistInit= ():gptsType[]=>{\n    const lk= ss.get('gpts-use-list');\n    if( !lk) return [];\n    return lk as gptsType[]; \n}\n\n//使用gtps列表\nexport const gptsUlistStore= reactive({\n    myData:gptsUlistInit(),\n    setMyData( v: gptsType){\n        this.myData= this.myData.filter( v2=> v2.gid!=v.gid );\n        this.myData.unshift(v);\n        ss.set('gpts-use-list', this.myData );\n        return this;\n    }\n});"
  },
  {
    "path": "src/store/index.ts",
    "content": "import type { App } from 'vue'\nimport { store } from './helper'\n\nexport function setupStore(app: App) {\n  app.use(store)\n}\n\nexport * from './modules'\nexport * from \"./homeStore\"\n"
  },
  {
    "path": "src/store/modules/app/helper.ts",
    "content": "import { homeStore } from '@/store/homeStore'\nimport { ss } from '@/utils/storage'\n\nconst LOCAL_NAME = 'appSetting'\n\nexport type Theme = 'light' | 'dark' | 'auto'\n\nexport type Language = 'zh-CN' | 'zh-TW' | 'en-US' | 'ko-KR' | 'ru-RU' | 'vi-VN' | 'fr-FR' | 'tr-TR'\n\nexport interface AppState {\n  siderCollapsed: boolean\n  theme: Theme\n  language: Language\n}\n\nexport function defaultSetting(): AppState {\n   const userLang = navigator.language || navigator.userLanguage;\n    let content:Language= 'en-US';\n    if (userLang.startsWith('zh-HK') || userLang.startsWith('zh-TW')) {\n        content =  'zh-TW'; // 繁体中文\n    } else if (userLang.startsWith('zh')) {\n        content = 'zh-CN'; // 简体中文\n    } else if (userLang.startsWith('fr')) {\n        content = 'fr-FR'; // 法语\n    } else if (userLang.startsWith('ko')) {\n        content = 'ko-KR'; // 韩语\n    } else if (userLang.startsWith('ru')) {\n        content = 'ru-RU'; // 俄文\n    } else if (userLang.startsWith('vi')) {\n        content = 'vi-VN'; // 越南语\n    } else if (userLang.startsWith('tr')) {\n        content = 'tr-TR'; // 土耳其语\n    } else {\n        content = 'en-US'; // 英语\n    }\n  return { siderCollapsed: false, theme: homeStore.myData.session.theme=='light'?'light': 'auto', language:  content }\n}\n\nexport function getLocalSetting(): AppState {\n  const localSetting: AppState | undefined = ss.get(LOCAL_NAME)\n  return { ...defaultSetting(), ...localSetting }\n}\n\nexport function setLocalSetting(setting: AppState): void {\n  ss.set(LOCAL_NAME, setting)\n}\n"
  },
  {
    "path": "src/store/modules/app/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport type { AppState, Language, Theme } from './helper'\nimport { getLocalSetting, setLocalSetting } from './helper'\nimport { store } from '@/store/helper'\n\nexport const useAppStore = defineStore('app-store', {\n  state: (): AppState => getLocalSetting(),\n  actions: {\n    setSiderCollapsed(collapsed: boolean) {\n      this.siderCollapsed = collapsed\n      this.recordState()\n    },\n\n    setTheme(theme: Theme) {\n      this.theme = theme\n      this.recordState()\n    },\n\n    setLanguage(language: Language) {\n      if (this.language !== language) {\n        this.language = language\n        this.recordState()\n      }\n    },\n\n    recordState() {\n      setLocalSetting(this.$state)\n    },\n  },\n})\n\nexport function useAppStoreWithOut() {\n  return useAppStore(store)\n}\n"
  },
  {
    "path": "src/store/modules/auth/helper.ts",
    "content": "import { ss } from '@/utils/storage'\n\nconst LOCAL_NAME = 'SECRET_TOKEN'\n\nexport function getToken() {\n  return ss.get(LOCAL_NAME)\n}\n\nexport function setToken(token: string) {\n  return ss.set(LOCAL_NAME, token)\n}\n\nexport function removeToken() {\n  return ss.remove(LOCAL_NAME)\n}\n"
  },
  {
    "path": "src/store/modules/auth/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport { getToken, removeToken, setToken } from './helper'\nimport { store } from '@/store/helper'\nimport { fetchSession } from '@/api'\nimport { gptConfigStore, homeStore } from '@/store/homeStore'\nimport { useAppStore } from '@/store'\nconst appStore = useAppStore()\ninterface SessionResponse {\n  theme?: string\n  auth: boolean\n  model: 'ChatGPTAPI' | 'ChatGPTUnofficialProxyAPI'\n}\n\nexport interface AuthState {\n  token: string | undefined\n  session: SessionResponse | null\n}\n\nexport const useAuthStore = defineStore('auth-store', {\n  state: (): AuthState => ({\n    token: getToken(),\n    session: null,\n  }),\n\n  getters: {\n    isChatGPTAPI(state): boolean {\n      return state.session?.model === 'ChatGPTAPI'\n    },\n  },\n\n  actions: {\n    async getSession() {\n      try {\n        const { data } = await fetchSession<SessionResponse>()\n        this.session = { ...data }\n        \n        homeStore.setMyData({session: data });\n        if(appStore.$state.theme=='auto' ){\n            appStore.setTheme(  data.theme && data.theme=='light' ?'light':'dark')\n        }\n\n        let str = localStorage.getItem('gptConfigStore');\n        if( ! str ) setTimeout( ()=>  gptConfigStore.setInit() , 500); \n        return Promise.resolve(data)\n      }\n      catch (error) {\n        return Promise.reject(error)\n      }\n    },\n\n    setToken(token: string) {\n      this.token = token\n      setToken(token)\n    },\n\n    removeToken() {\n      this.token = undefined\n      removeToken()\n    },\n  },\n})\n\nexport function useAuthStoreWithout() {\n  return useAuthStore(store)\n}\n"
  },
  {
    "path": "src/store/modules/chat/helper.ts",
    "content": "import { ss } from '@/utils/storage'\n\nconst LOCAL_NAME = 'chatStorage'\n\nexport function defaultState(): Chat.ChatState {\n  const uuid = 1002\n  return {\n    active: uuid,\n    usingContext: true,\n    history: [{ uuid, title: 'New Chat', isEdit: false }],\n    chat: [{ uuid, data: [] }],\n  }\n}\n\nexport function getLocalState(): Chat.ChatState {\n  const localState = ss.get(LOCAL_NAME)\n  return { ...defaultState(), ...localState }\n}\n\nexport function setLocalState(state: Chat.ChatState) {\n  ss.set(LOCAL_NAME, state)\n}\n"
  },
  {
    "path": "src/store/modules/chat/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport { defaultState, getLocalState, setLocalState } from './helper'\nimport { router } from '@/router'\nimport { homeStore } from '@/store/homeStore'\nimport { sleep } from '@/api/suno'\nimport { mlog } from '@/api'\n\nexport const useChatStore = defineStore('chat-store', {\n  state: (): Chat.ChatState => getLocalState(),\n\n  getters: {\n    getChatHistoryByCurrentActive(state: Chat.ChatState) {\n      const index = state.history.findIndex(item => item.uuid === state.active)\n      if (index !== -1)\n        return state.history[index]\n      return null\n    },\n\n    getChatByUuid(state: Chat.ChatState) {\n      return (uuid?: number) => {\n        if (uuid)\n          return state.chat.find(item => item.uuid === uuid)?.data ?? []\n        return state.chat.find(item => item.uuid === state.active)?.data ?? []\n      }\n    },\n  },\n\n  actions: {\n    setUsingContext(context: boolean) {\n      this.usingContext = context\n      this.recordState()\n    },\n\n    addHistory(history: Chat.History, chatData: Chat.Chat[] = []) {\n      this.history.unshift(history)\n      this.chat.unshift({ uuid: history.uuid, data: chatData })\n      this.active = history.uuid\n      this.reloadRoute(history.uuid)\n    },\n\n    updateHistory(uuid: number, edit: Partial<Chat.History>) {\n      const index = this.history.findIndex(item => item.uuid === uuid)\n      if (index !== -1) {\n        this.history[index] = { ...this.history[index], ...edit }\n        this.recordState()\n      }\n    },\n\n    async deleteHistory(index: number) {\n      this.history.splice(index, 1)\n      this.chat.splice(index, 1)\n\n      if (this.history.length === 0) {\n        this.active = null\n        this.reloadRoute()\n        return\n      }\n\n      if (index > 0 && index <= this.history.length) {\n        const uuid = this.history[index - 1].uuid\n        this.active = uuid\n        this.reloadRoute(uuid)\n        return\n      }\n\n      if (index === 0) {\n        if (this.history.length > 0) {\n          const uuid = this.history[0].uuid\n          this.active = uuid\n          this.reloadRoute(uuid)\n        }\n      }\n\n      if (index > this.history.length) {\n        const uuid = this.history[this.history.length - 1].uuid\n        this.active = uuid\n        this.reloadRoute(uuid)\n      }\n    },\n\n    async setActive(uuid: number) {\n      this.active = uuid\n      return await this.reloadRoute(uuid)\n    },\n\n    getChatByUuidAndIndex(uuid: number, index: number) {\n      if (!uuid || uuid === 0) {\n        if (this.chat.length)\n          return this.chat[0].data[index]\n        return null\n      }\n      const chatIndex = this.chat.findIndex(item => item.uuid === uuid)\n      if (chatIndex !== -1)\n        return this.chat[chatIndex].data[index]\n      return null\n    },\n\n    addChatByUuid(uuid: number, chat: Chat.Chat) {\n      if (!uuid || uuid === 0) {\n        if (this.history.length === 0) {\n          const uuid = Date.now()\n          this.history.push({ uuid, title: chat.text, isEdit: false })\n          this.chat.push({ uuid, data: [chat] })\n          this.active = uuid\n          this.recordState()\n        }\n        else {\n          this.chat[0].data.push(chat)\n          if (this.history[0].title === 'New Chat')\n            this.history[0].title = chat.text\n          this.recordState()\n        }\n      }\n\n      const index = this.chat.findIndex(item => item.uuid === uuid)\n      if (index !== -1) {\n        this.chat[index].data.push(chat)\n        if (this.history[index].title === 'New Chat')\n          this.history[index].title = chat.text\n        this.recordState()\n      }\n    },\n\n    updateChatByUuid(uuid: number, index: number, chat: Chat.Chat) {\n      if (!uuid || uuid === 0) {\n        if (this.chat.length) {\n          this.chat[0].data[index] = chat\n          this.recordState()\n        }\n        return\n      }\n\n      const chatIndex = this.chat.findIndex(item => item.uuid === uuid)\n      if (chatIndex !== -1) {\n        this.chat[chatIndex].data[index] = chat\n        this.recordState()\n      }\n    },\n\n    updateChatSomeByUuid(uuid: number, index: number, chat: Partial<Chat.Chat>) {\n      if (!uuid || uuid === 0) {\n        if (this.chat.length) {\n          this.chat[0].data[index] = { ...this.chat[0].data[index], ...chat }\n          this.recordState()\n        }\n        return\n      }\n\n      const chatIndex = this.chat.findIndex(item => item.uuid === uuid)\n      if (chatIndex !== -1) {\n        this.chat[chatIndex].data[index] = { ...this.chat[chatIndex].data[index], ...chat }\n        this.recordState()\n      }\n    },\n\n    deleteChatByUuid(uuid: number, index: number) {\n      if (!uuid || uuid === 0) {\n        if (this.chat.length) {\n          this.chat[0].data.splice(index, 1)\n          this.recordState()\n        }\n        return\n      }\n\n      const chatIndex = this.chat.findIndex(item => item.uuid === uuid)\n      if (chatIndex !== -1) {\n        this.chat[chatIndex].data.splice(index, 1)\n        this.recordState()\n      }\n    },\n\n    clearChatByUuid(uuid: number) {\n      if (!uuid || uuid === 0) {\n        if (this.chat.length) {\n          this.chat[0].data = []\n          this.recordState()\n        }\n        return\n      }\n\n      const index = this.chat.findIndex(item => item.uuid === uuid)\n      if (index !== -1) {\n        this.chat[index].data = []\n        this.recordState()\n      }\n\n      //清空标题\n      const i2= this.history.findIndex( v=>v.uuid===uuid )\n      if (i2 !== -1) {\n        this.history[i2].title= \"New Chat\"\n         this.recordState()\n      }\n      //end 清空标题\n    },\n\n    clearHistory() {\n      this.$state = { ...defaultState() }\n      this.recordState()\n    },\n\n    async reloadRoute(uuid?: number) {\n      this.recordState();\n      mlog('toMyuid19','reloadRoute')\n      //await sleep(1000)\n      await router.push({ name: homeStore.myData.local=='draw'?'draw': 'Chat', params: { uuid } })\n    },\n\n    recordState() {\n      setLocalState(this.$state)\n    },\n  },\n})\n"
  },
  {
    "path": "src/store/modules/index.ts",
    "content": "export * from './app'\nexport * from './chat'\nexport * from './user'\nexport * from './prompt'\nexport * from './settings'\nexport * from './auth'\n"
  },
  {
    "path": "src/store/modules/prompt/helper.ts",
    "content": "import { ss } from '@/utils/storage'\n\nconst LOCAL_NAME = 'promptStore'\n\nexport type PromptList = []\n\nexport interface PromptStore {\n  promptList: PromptList\n}\n\nexport function getLocalPromptList(): PromptStore {\n  const promptStore: PromptStore | undefined = ss.get(LOCAL_NAME)\n  return promptStore ?? { promptList: [] }\n}\n\nexport function setLocalPromptList(promptStore: PromptStore): void {\n  ss.set(LOCAL_NAME, promptStore)\n}\n"
  },
  {
    "path": "src/store/modules/prompt/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport type { PromptStore } from './helper'\nimport { getLocalPromptList, setLocalPromptList } from './helper'\n\nexport const usePromptStore = defineStore('prompt-store', {\n  state: (): PromptStore => getLocalPromptList(),\n\n  actions: {\n    updatePromptList(promptList: []) {\n      this.$patch({ promptList })\n      setLocalPromptList({ promptList })\n    },\n    getPromptList() {\n      return this.$state\n    },\n  },\n})\n"
  },
  {
    "path": "src/store/modules/settings/helper.ts",
    "content": "import { ss } from '@/utils/storage'\n\nconst LOCAL_NAME = 'settingsStorage'\n\nexport interface SettingsState {\n  systemMessage: string\n  temperature: number\n  top_p: number\n}\n\nexport function defaultSetting(): SettingsState {\n  return {\n    systemMessage: 'You are ChatGPT, a large language model trained by OpenAI. Follow the user\\'s instructions carefully. Respond using markdown.',\n    temperature: 0.8,\n    top_p: 1,\n  }\n}\n\nexport function getLocalState(): SettingsState {\n  const localSetting: SettingsState | undefined = ss.get(LOCAL_NAME)\n  return { ...defaultSetting(), ...localSetting }\n}\n\nexport function setLocalState(setting: SettingsState): void {\n  ss.set(LOCAL_NAME, setting)\n}\n\nexport function removeLocalState() {\n  ss.remove(LOCAL_NAME)\n}\n"
  },
  {
    "path": "src/store/modules/settings/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport type { SettingsState } from './helper'\nimport { defaultSetting, getLocalState, removeLocalState, setLocalState } from './helper'\n\nexport const useSettingStore = defineStore('setting-store', {\n  state: (): SettingsState => getLocalState(),\n  actions: {\n    updateSetting(settings: Partial<SettingsState>) {\n      this.$state = { ...this.$state, ...settings }\n      this.recordState()\n    },\n\n    resetSetting() {\n      this.$state = defaultSetting()\n      removeLocalState()\n    },\n\n    recordState() {\n      setLocalState(this.$state)\n    },\n  },\n})\n"
  },
  {
    "path": "src/store/modules/user/helper.ts",
    "content": "import { ss } from '@/utils/storage'\nimport { t } from '@/locales'\nimport { homeStore } from \"@/store\";\nconst LOCAL_NAME = 'userStorage'\nconst backgroundImage = homeStore.myData.session.backgroundImage ?? \"https://t.alcy.cc/fj/\"\n\nexport interface UserInfo {\n  avatar: string\n  name: string\n  backgroundImage: string\n  description: string\n}\n\nexport interface UserState {\n  userInfo: UserInfo\n}\n\nexport function defaultSetting(): UserState {\n  return {\n    userInfo: {\n      avatar: 'https://raw.githubusercontent.com/Dooy/chatgpt-web-midjourney-proxy/main/src/assets/avatar.jpg',\n      name:  t('mjset.sysname'),//'AI绘图',\n      description: 'Star on <a href=\"https://github.com/Dooy/chatgpt-web-midjourney-proxy\" class=\"text-blue-500\" target=\"_blank\" >GitHub</a>',\n    },\n  }\n}\n\nexport function getLocalState(): UserState {\n  const localSetting: UserState | undefined = ss.get(LOCAL_NAME)\n  return { ...defaultSetting(), ...localSetting }\n}\n\nexport function setLocalState(setting: UserState): void {\n  ss.set(LOCAL_NAME, setting)\n}\n"
  },
  {
    "path": "src/store/modules/user/index.ts",
    "content": "import { defineStore } from 'pinia'\nimport type { UserInfo, UserState } from './helper'\nimport { defaultSetting, getLocalState, setLocalState } from './helper'\n\nexport const useUserStore = defineStore('user-store', {\n  state: (): UserState => getLocalState(),\n  actions: {\n    updateUserInfo(userInfo: Partial<UserInfo>) {\n      this.userInfo = { ...this.userInfo, ...userInfo }\n      this.recordState()\n    },\n\n    resetUserInfo() {\n      this.userInfo = { ...defaultSetting().userInfo }\n      this.recordState()\n    },\n\n    recordState() {\n      setLocalState(this.$state)\n    },\n  },\n})\n"
  },
  {
    "path": "src/styles/global.less",
    "content": "html,\nbody,\n#app {\n\theight: 100%;\n}\n\nbody {\n\tpadding-bottom: constant(safe-area-inset-bottom);\n\tpadding-bottom: env(safe-area-inset-bottom);\n}\n\n.active{\n    color: #4b9e5f!important;\n}\n"
  },
  {
    "path": "src/styles/lib/github-markdown.less",
    "content": "html.dark {\n  .markdown-body {\n    color-scheme: dark;\n    --color-prettylights-syntax-comment: #8b949e;\n    --color-prettylights-syntax-constant: #79c0ff;\n    --color-prettylights-syntax-entity: #d2a8ff;\n    --color-prettylights-syntax-storage-modifier-import: #c9d1d9;\n    --color-prettylights-syntax-entity-tag: #7ee787;\n    --color-prettylights-syntax-keyword: #ff7b72;\n    --color-prettylights-syntax-string: #a5d6ff;\n    --color-prettylights-syntax-variable: #ffa657;\n    --color-prettylights-syntax-brackethighlighter-unmatched: #f85149;\n    --color-prettylights-syntax-invalid-illegal-text: #f0f6fc;\n    --color-prettylights-syntax-invalid-illegal-bg: #8e1519;\n    --color-prettylights-syntax-carriage-return-text: #f0f6fc;\n    --color-prettylights-syntax-carriage-return-bg: #b62324;\n    --color-prettylights-syntax-string-regexp: #7ee787;\n    --color-prettylights-syntax-markup-list: #f2cc60;\n    --color-prettylights-syntax-markup-heading: #1f6feb;\n    --color-prettylights-syntax-markup-italic: #c9d1d9;\n    --color-prettylights-syntax-markup-bold: #c9d1d9;\n    --color-prettylights-syntax-markup-deleted-text: #ffdcd7;\n    --color-prettylights-syntax-markup-deleted-bg: #67060c;\n    --color-prettylights-syntax-markup-inserted-text: #aff5b4;\n    --color-prettylights-syntax-markup-inserted-bg: #033a16;\n    --color-prettylights-syntax-markup-changed-text: #ffdfb6;\n    --color-prettylights-syntax-markup-changed-bg: #5a1e02;\n    --color-prettylights-syntax-markup-ignored-text: #c9d1d9;\n    --color-prettylights-syntax-markup-ignored-bg: #1158c7;\n    --color-prettylights-syntax-meta-diff-range: #d2a8ff;\n    --color-prettylights-syntax-brackethighlighter-angle: #8b949e;\n    --color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;\n    --color-prettylights-syntax-constant-other-reference-link: #a5d6ff;\n    --color-fg-default: #c9d1d9;\n    --color-fg-muted: #8b949e;\n    --color-fg-subtle: #6e7681;\n    --color-canvas-default: #0d1117;\n    --color-canvas-subtle: #161b22;\n    --color-border-default: #30363d;\n    --color-border-muted: #21262d;\n    --color-neutral-muted: rgba(110,118,129,0.4);\n    --color-accent-fg: #58a6ff;\n    --color-accent-emphasis: #1f6feb;\n    --color-attention-subtle: rgba(187,128,9,0.15);\n    --color-danger-fg: #f85149;\n  }\n}\n\nhtml {\n  .markdown-body {\n    color-scheme: light;\n    --color-prettylights-syntax-comment: #6e7781;\n    --color-prettylights-syntax-constant: #0550ae;\n    --color-prettylights-syntax-entity: #8250df;\n    --color-prettylights-syntax-storage-modifier-import: #24292f;\n    --color-prettylights-syntax-entity-tag: #116329;\n    --color-prettylights-syntax-keyword: #cf222e;\n    --color-prettylights-syntax-string: #0a3069;\n    --color-prettylights-syntax-variable: #953800;\n    --color-prettylights-syntax-brackethighlighter-unmatched: #82071e;\n    --color-prettylights-syntax-invalid-illegal-text: #f6f8fa;\n    --color-prettylights-syntax-invalid-illegal-bg: #82071e;\n    --color-prettylights-syntax-carriage-return-text: #f6f8fa;\n    --color-prettylights-syntax-carriage-return-bg: #cf222e;\n    --color-prettylights-syntax-string-regexp: #116329;\n    --color-prettylights-syntax-markup-list: #3b2300;\n    --color-prettylights-syntax-markup-heading: #0550ae;\n    --color-prettylights-syntax-markup-italic: #24292f;\n    --color-prettylights-syntax-markup-bold: #24292f;\n    --color-prettylights-syntax-markup-deleted-text: #82071e;\n    --color-prettylights-syntax-markup-deleted-bg: #ffebe9;\n    --color-prettylights-syntax-markup-inserted-text: #116329;\n    --color-prettylights-syntax-markup-inserted-bg: #dafbe1;\n    --color-prettylights-syntax-markup-changed-text: #953800;\n    --color-prettylights-syntax-markup-changed-bg: #ffd8b5;\n    --color-prettylights-syntax-markup-ignored-text: #eaeef2;\n    --color-prettylights-syntax-markup-ignored-bg: #0550ae;\n    --color-prettylights-syntax-meta-diff-range: #8250df;\n    --color-prettylights-syntax-brackethighlighter-angle: #57606a;\n    --color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;\n    --color-prettylights-syntax-constant-other-reference-link: #0a3069;\n    --color-fg-default: #24292f;\n    --color-fg-muted: #57606a;\n    --color-fg-subtle: #6e7781;\n    --color-canvas-default: #ffffff;\n    --color-canvas-subtle: #f6f8fa;\n    --color-border-default: #d0d7de;\n    --color-border-muted: hsla(210,18%,87%,1);\n    --color-neutral-muted: rgba(175,184,193,0.2);\n    --color-accent-fg: #0969da;\n    --color-accent-emphasis: #0969da;\n    --color-attention-subtle: #fff8c5;\n    --color-danger-fg: #cf222e;\n  }\n}\n\n.markdown-body {\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n  margin: 0;\n  color: var(--color-fg-default);\n  background-color: var(--color-canvas-default);\n  font-family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",\"Noto Sans\",Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\";\n  font-size: 16px;\n  line-height: 1.5;\n  word-wrap: break-word;\n}\n\n.markdown-body .octicon {\n  display: inline-block;\n  fill: currentColor;\n  vertical-align: text-bottom;\n}\n\n.markdown-body h1:hover .anchor .octicon-link:before,\n.markdown-body h2:hover .anchor .octicon-link:before,\n.markdown-body h3:hover .anchor .octicon-link:before,\n.markdown-body h4:hover .anchor .octicon-link:before,\n.markdown-body h5:hover .anchor .octicon-link:before,\n.markdown-body h6:hover .anchor .octicon-link:before {\n  width: 16px;\n  height: 16px;\n  content: ' ';\n  display: inline-block;\n  background-color: currentColor;\n  -webkit-mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n  mask-image: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>\");\n}\n\n.markdown-body details,\n.markdown-body figcaption,\n.markdown-body figure {\n  display: block;\n}\n\n.markdown-body summary {\n  display: list-item;\n}\n\n.markdown-body [hidden] {\n  display: none !important;\n}\n\n.markdown-body a {\n  background-color: transparent;\n  color: var(--color-accent-fg);\n  text-decoration: none;\n}\n\n.markdown-body abbr[title] {\n  border-bottom: none;\n  text-decoration: underline dotted;\n}\n\n.markdown-body b,\n.markdown-body strong {\n  font-weight: var(--base-text-weight-semibold, 600);\n}\n\n.markdown-body dfn {\n  font-style: italic;\n}\n\n.markdown-body h1 {\n  margin: .67em 0;\n  font-weight: var(--base-text-weight-semibold, 600);\n  padding-bottom: .3em;\n  font-size: 2em;\n  border-bottom: 1px solid var(--color-border-muted);\n}\n\n.markdown-body mark {\n  background-color: var(--color-attention-subtle);\n  color: var(--color-fg-default);\n}\n\n.markdown-body small {\n  font-size: 90%;\n}\n\n.markdown-body sub,\n.markdown-body sup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\n.markdown-body sub {\n  bottom: -0.25em;\n}\n\n.markdown-body sup {\n  top: -0.5em;\n}\n\n.markdown-body img {\n  border-style: none;\n  max-width: 100%;\n  box-sizing: content-box;\n  background-color: var(--color-canvas-default);\n}\n\n.markdown-body code,\n.markdown-body kbd,\n.markdown-body pre,\n.markdown-body samp {\n  font-family: monospace;\n  font-size: 1em;\n}\n\n.markdown-body figure {\n  margin: 1em 40px;\n}\n\n.markdown-body hr {\n  box-sizing: content-box;\n  overflow: hidden;\n  background: transparent;\n  border-bottom: 1px solid var(--color-border-muted);\n  height: .25em;\n  padding: 0;\n  margin: 24px 0;\n  background-color: var(--color-border-default);\n  border: 0;\n}\n\n.markdown-body input {\n  font: inherit;\n  margin: 0;\n  overflow: visible;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n.markdown-body [type=button],\n.markdown-body [type=reset],\n.markdown-body [type=submit] {\n  -webkit-appearance: button;\n}\n\n.markdown-body [type=checkbox],\n.markdown-body [type=radio] {\n  box-sizing: border-box;\n  padding: 0;\n}\n\n.markdown-body [type=number]::-webkit-inner-spin-button,\n.markdown-body [type=number]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n.markdown-body [type=search]::-webkit-search-cancel-button,\n.markdown-body [type=search]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n.markdown-body ::-webkit-input-placeholder {\n  color: inherit;\n  opacity: .54;\n}\n\n.markdown-body ::-webkit-file-upload-button {\n  -webkit-appearance: button;\n  font: inherit;\n}\n\n.markdown-body a:hover {\n  text-decoration: underline;\n}\n\n.markdown-body ::placeholder {\n  color: var(--color-fg-subtle);\n  opacity: 1;\n}\n\n.markdown-body hr::before {\n  display: table;\n  content: \"\";\n}\n\n.markdown-body hr::after {\n  display: table;\n  clear: both;\n  content: \"\";\n}\n\n.markdown-body table {\n  border-spacing: 0;\n  border-collapse: collapse;\n  display: block;\n  width: max-content;\n  max-width: 100%;\n  overflow: auto;\n}\n\n.markdown-body td,\n.markdown-body th {\n  padding: 0;\n}\n\n.markdown-body details summary {\n  cursor: pointer;\n}\n\n.markdown-body details:not([open])>*:not(summary) {\n  display: none !important;\n}\n\n.markdown-body a:focus,\n.markdown-body [role=button]:focus,\n.markdown-body input[type=radio]:focus,\n.markdown-body input[type=checkbox]:focus {\n  outline: 2px solid var(--color-accent-fg);\n  outline-offset: -2px;\n  box-shadow: none;\n}\n\n.markdown-body a:focus:not(:focus-visible),\n.markdown-body [role=button]:focus:not(:focus-visible),\n.markdown-body input[type=radio]:focus:not(:focus-visible),\n.markdown-body input[type=checkbox]:focus:not(:focus-visible) {\n  outline: solid 1px transparent;\n}\n\n.markdown-body a:focus-visible,\n.markdown-body [role=button]:focus-visible,\n.markdown-body input[type=radio]:focus-visible,\n.markdown-body input[type=checkbox]:focus-visible {\n  outline: 2px solid var(--color-accent-fg);\n  outline-offset: -2px;\n  box-shadow: none;\n}\n\n.markdown-body a:not([class]):focus,\n.markdown-body a:not([class]):focus-visible,\n.markdown-body input[type=radio]:focus,\n.markdown-body input[type=radio]:focus-visible,\n.markdown-body input[type=checkbox]:focus,\n.markdown-body input[type=checkbox]:focus-visible {\n  outline-offset: 0;\n}\n\n.markdown-body kbd {\n  display: inline-block;\n  padding: 3px 5px;\n  font: 11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;\n  line-height: 10px;\n  color: var(--color-fg-default);\n  vertical-align: middle;\n  background-color: var(--color-canvas-subtle);\n  border: solid 1px var(--color-neutral-muted);\n  border-bottom-color: var(--color-neutral-muted);\n  border-radius: 6px;\n  box-shadow: inset 0 -1px 0 var(--color-neutral-muted);\n}\n\n.markdown-body h1,\n.markdown-body h2,\n.markdown-body h3,\n.markdown-body h4,\n.markdown-body h5,\n.markdown-body h6 {\n  margin-top: 24px;\n  margin-bottom: 16px;\n  font-weight: var(--base-text-weight-semibold, 600);\n  line-height: 1.25;\n}\n\n.markdown-body h2 {\n  font-weight: var(--base-text-weight-semibold, 600);\n  padding-bottom: .3em;\n  font-size: 1.5em;\n  border-bottom: 1px solid var(--color-border-muted);\n}\n\n.markdown-body h3 {\n  font-weight: var(--base-text-weight-semibold, 600);\n  font-size: 1.25em;\n}\n\n.markdown-body h4 {\n  font-weight: var(--base-text-weight-semibold, 600);\n  font-size: 1em;\n}\n\n.markdown-body h5 {\n  font-weight: var(--base-text-weight-semibold, 600);\n  font-size: .875em;\n}\n\n.markdown-body h6 {\n  font-weight: var(--base-text-weight-semibold, 600);\n  font-size: .85em;\n  color: var(--color-fg-muted);\n}\n\n.markdown-body p {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\n\n.markdown-body blockquote {\n  margin: 0;\n  padding: 0 1em;\n  color: var(--color-fg-muted);\n  border-left: .25em solid var(--color-border-default);\n}\n\n.markdown-body ul,\n.markdown-body ol {\n  margin-top: 0;\n  margin-bottom: 0;\n  padding-left: 2em;\n}\n\n.markdown-body ol ol,\n.markdown-body ul ol {\n  list-style-type: lower-roman;\n}\n\n.markdown-body ul ul ol,\n.markdown-body ul ol ol,\n.markdown-body ol ul ol,\n.markdown-body ol ol ol {\n  list-style-type: lower-alpha;\n}\n\n.markdown-body dd {\n  margin-left: 0;\n}\n\n.markdown-body tt,\n.markdown-body code,\n.markdown-body samp {\n  font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;\n  font-size: 12px;\n}\n\n.markdown-body pre {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;\n  font-size: 12px;\n  word-wrap: normal;\n}\n\n.markdown-body .octicon {\n  display: inline-block;\n  overflow: visible !important;\n  vertical-align: text-bottom;\n  fill: currentColor;\n}\n\n.markdown-body input::-webkit-outer-spin-button,\n.markdown-body input::-webkit-inner-spin-button {\n  margin: 0;\n  -webkit-appearance: none;\n  appearance: none;\n}\n\n.markdown-body::before {\n  display: table;\n  content: \"\";\n}\n\n.markdown-body::after {\n  display: table;\n  clear: both;\n  content: \"\";\n}\n\n.markdown-body>*:first-child {\n  margin-top: 0 !important;\n}\n\n.markdown-body>*:last-child {\n  margin-bottom: 0 !important;\n}\n\n.markdown-body a:not([href]) {\n  color: inherit;\n  text-decoration: none;\n}\n\n.markdown-body .absent {\n  color: var(--color-danger-fg);\n}\n\n.markdown-body .anchor {\n  float: left;\n  padding-right: 4px;\n  margin-left: -20px;\n  line-height: 1;\n}\n\n.markdown-body .anchor:focus {\n  outline: none;\n}\n\n.markdown-body p,\n.markdown-body blockquote,\n.markdown-body ul,\n.markdown-body ol,\n.markdown-body dl,\n.markdown-body table,\n.markdown-body pre,\n.markdown-body details {\n  margin-top: 0;\n  margin-bottom: 16px;\n}\n\n.markdown-body blockquote>:first-child {\n  margin-top: 0;\n}\n\n.markdown-body blockquote>:last-child {\n  margin-bottom: 0;\n}\n\n.markdown-body h1 .octicon-link,\n.markdown-body h2 .octicon-link,\n.markdown-body h3 .octicon-link,\n.markdown-body h4 .octicon-link,\n.markdown-body h5 .octicon-link,\n.markdown-body h6 .octicon-link {\n  color: var(--color-fg-default);\n  vertical-align: middle;\n  visibility: hidden;\n}\n\n.markdown-body h1:hover .anchor,\n.markdown-body h2:hover .anchor,\n.markdown-body h3:hover .anchor,\n.markdown-body h4:hover .anchor,\n.markdown-body h5:hover .anchor,\n.markdown-body h6:hover .anchor {\n  text-decoration: none;\n}\n\n.markdown-body h1:hover .anchor .octicon-link,\n.markdown-body h2:hover .anchor .octicon-link,\n.markdown-body h3:hover .anchor .octicon-link,\n.markdown-body h4:hover .anchor .octicon-link,\n.markdown-body h5:hover .anchor .octicon-link,\n.markdown-body h6:hover .anchor .octicon-link {\n  visibility: visible;\n}\n\n.markdown-body h1 tt,\n.markdown-body h1 code,\n.markdown-body h2 tt,\n.markdown-body h2 code,\n.markdown-body h3 tt,\n.markdown-body h3 code,\n.markdown-body h4 tt,\n.markdown-body h4 code,\n.markdown-body h5 tt,\n.markdown-body h5 code,\n.markdown-body h6 tt,\n.markdown-body h6 code {\n  padding: 0 .2em;\n  font-size: inherit;\n}\n\n.markdown-body summary h1,\n.markdown-body summary h2,\n.markdown-body summary h3,\n.markdown-body summary h4,\n.markdown-body summary h5,\n.markdown-body summary h6 {\n  display: inline-block;\n}\n\n.markdown-body summary h1 .anchor,\n.markdown-body summary h2 .anchor,\n.markdown-body summary h3 .anchor,\n.markdown-body summary h4 .anchor,\n.markdown-body summary h5 .anchor,\n.markdown-body summary h6 .anchor {\n  margin-left: -40px;\n}\n\n.markdown-body summary h1,\n.markdown-body summary h2 {\n  padding-bottom: 0;\n  border-bottom: 0;\n}\n\n.markdown-body ul.no-list,\n.markdown-body ol.no-list {\n  padding: 0;\n  list-style-type: none;\n}\n\n.markdown-body ol[type=a] {\n  list-style-type: lower-alpha;\n}\n\n.markdown-body ol[type=A] {\n  list-style-type: upper-alpha;\n}\n\n.markdown-body ol[type=i] {\n  list-style-type: lower-roman;\n}\n\n.markdown-body ol[type=I] {\n  list-style-type: upper-roman;\n}\n\n.markdown-body ol[type=\"1\"] {\n  list-style-type: decimal;\n}\n\n.markdown-body div>ol:not([type]) {\n  list-style-type: decimal;\n}\n\n.markdown-body ul ul,\n.markdown-body ul ol,\n.markdown-body ol ol,\n.markdown-body ol ul {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n.markdown-body li>p {\n  margin-top: 16px;\n}\n\n.markdown-body li+li {\n  margin-top: .25em;\n}\n\n.markdown-body dl {\n  padding: 0;\n}\n\n.markdown-body dl dt {\n  padding: 0;\n  margin-top: 16px;\n  font-size: 1em;\n  font-style: italic;\n  font-weight: var(--base-text-weight-semibold, 600);\n}\n\n.markdown-body dl dd {\n  padding: 0 16px;\n  margin-bottom: 16px;\n}\n\n.markdown-body table th {\n  font-weight: var(--base-text-weight-semibold, 600);\n}\n\n.markdown-body table th,\n.markdown-body table td {\n  padding: 6px 13px;\n  border: 1px solid var(--color-border-default);\n}\n\n.markdown-body table tr {\n  background-color: var(--color-canvas-default);\n  border-top: 1px solid var(--color-border-muted);\n}\n\n.markdown-body table tr:nth-child(2n) {\n  background-color: var(--color-canvas-subtle);\n}\n\n.markdown-body table img {\n  background-color: transparent;\n}\n\n.markdown-body img[align=right] {\n  padding-left: 20px;\n}\n\n.markdown-body img[align=left] {\n  padding-right: 20px;\n}\n\n.markdown-body .emoji {\n  max-width: none;\n  vertical-align: text-top;\n  background-color: transparent;\n}\n\n.markdown-body span.frame {\n  display: block;\n  overflow: hidden;\n}\n\n.markdown-body span.frame>span {\n  display: block;\n  float: left;\n  width: auto;\n  padding: 7px;\n  margin: 13px 0 0;\n  overflow: hidden;\n  border: 1px solid var(--color-border-default);\n}\n\n.markdown-body span.frame span img {\n  display: block;\n  float: left;\n}\n\n.markdown-body span.frame span span {\n  display: block;\n  padding: 5px 0 0;\n  clear: both;\n  color: var(--color-fg-default);\n}\n\n.markdown-body span.align-center {\n  display: block;\n  overflow: hidden;\n  clear: both;\n}\n\n.markdown-body span.align-center>span {\n  display: block;\n  margin: 13px auto 0;\n  overflow: hidden;\n  text-align: center;\n}\n\n.markdown-body span.align-center span img {\n  margin: 0 auto;\n  text-align: center;\n}\n\n.markdown-body span.align-right {\n  display: block;\n  overflow: hidden;\n  clear: both;\n}\n\n.markdown-body span.align-right>span {\n  display: block;\n  margin: 13px 0 0;\n  overflow: hidden;\n  text-align: right;\n}\n\n.markdown-body span.align-right span img {\n  margin: 0;\n  text-align: right;\n}\n\n.markdown-body span.float-left {\n  display: block;\n  float: left;\n  margin-right: 13px;\n  overflow: hidden;\n}\n\n.markdown-body span.float-left span {\n  margin: 13px 0 0;\n}\n\n.markdown-body span.float-right {\n  display: block;\n  float: right;\n  margin-left: 13px;\n  overflow: hidden;\n}\n\n.markdown-body span.float-right>span {\n  display: block;\n  margin: 13px auto 0;\n  overflow: hidden;\n  text-align: right;\n}\n\n.markdown-body code,\n.markdown-body tt {\n  padding: .2em .4em;\n  margin: 0;\n  font-size: 85%;\n  white-space: break-spaces;\n  background-color: var(--color-neutral-muted);\n  border-radius: 6px;\n}\n\n.markdown-body code br,\n.markdown-body tt br {\n  display: none;\n}\n\n.markdown-body del code {\n  text-decoration: inherit;\n}\n\n.markdown-body samp {\n  font-size: 85%;\n}\n\n.markdown-body pre code {\n  font-size: 100%;\n}\n\n.markdown-body pre>code {\n  padding: 0;\n  margin: 0;\n  word-break: normal;\n  white-space: pre;\n  background: transparent;\n  border: 0;\n}\n\n.markdown-body .highlight {\n  margin-bottom: 16px;\n}\n\n.markdown-body .highlight pre {\n  margin-bottom: 0;\n  word-break: normal;\n}\n\n.markdown-body .highlight pre,\n.markdown-body pre {\n  padding: 16px;\n  overflow: auto;\n  font-size: 85%;\n  line-height: 1.45;\n  background-color: var(--color-canvas-subtle);\n  border-radius: 6px;\n}\n\n.markdown-body pre code,\n.markdown-body pre tt {\n  display: inline;\n  max-width: auto;\n  padding: 0;\n  margin: 0;\n  overflow: visible;\n  line-height: inherit;\n  word-wrap: normal;\n  background-color: transparent;\n  border: 0;\n}\n\n.markdown-body .csv-data td,\n.markdown-body .csv-data th {\n  padding: 5px;\n  overflow: hidden;\n  font-size: 12px;\n  line-height: 1;\n  text-align: left;\n  white-space: nowrap;\n}\n\n.markdown-body .csv-data .blob-num {\n  padding: 10px 8px 9px;\n  text-align: right;\n  background: var(--color-canvas-default);\n  border: 0;\n}\n\n.markdown-body .csv-data tr {\n  border-top: 0;\n}\n\n.markdown-body .csv-data th {\n  font-weight: var(--base-text-weight-semibold, 600);\n  background: var(--color-canvas-subtle);\n  border-top: 0;\n}\n\n.markdown-body [data-footnote-ref]::before {\n  content: \"[\";\n}\n\n.markdown-body [data-footnote-ref]::after {\n  content: \"]\";\n}\n\n.markdown-body .footnotes {\n  font-size: 12px;\n  color: var(--color-fg-muted);\n  border-top: 1px solid var(--color-border-default);\n}\n\n.markdown-body .footnotes ol {\n  padding-left: 16px;\n}\n\n.markdown-body .footnotes ol ul {\n  display: inline-block;\n  padding-left: 16px;\n  margin-top: 16px;\n}\n\n.markdown-body .footnotes li {\n  position: relative;\n}\n\n.markdown-body .footnotes li:target::before {\n  position: absolute;\n  top: -8px;\n  right: -8px;\n  bottom: -8px;\n  left: -24px;\n  pointer-events: none;\n  content: \"\";\n  border: 2px solid var(--color-accent-emphasis);\n  border-radius: 6px;\n}\n\n.markdown-body .footnotes li:target {\n  color: var(--color-fg-default);\n}\n\n.markdown-body .footnotes .data-footnote-backref g-emoji {\n  font-family: monospace;\n}\n\n.markdown-body .pl-c {\n  color: var(--color-prettylights-syntax-comment);\n}\n\n.markdown-body .pl-c1,\n.markdown-body .pl-s .pl-v {\n  color: var(--color-prettylights-syntax-constant);\n}\n\n.markdown-body .pl-e,\n.markdown-body .pl-en {\n  color: var(--color-prettylights-syntax-entity);\n}\n\n.markdown-body .pl-smi,\n.markdown-body .pl-s .pl-s1 {\n  color: var(--color-prettylights-syntax-storage-modifier-import);\n}\n\n.markdown-body .pl-ent {\n  color: var(--color-prettylights-syntax-entity-tag);\n}\n\n.markdown-body .pl-k {\n  color: var(--color-prettylights-syntax-keyword);\n}\n\n.markdown-body .pl-s,\n.markdown-body .pl-pds,\n.markdown-body .pl-s .pl-pse .pl-s1,\n.markdown-body .pl-sr,\n.markdown-body .pl-sr .pl-cce,\n.markdown-body .pl-sr .pl-sre,\n.markdown-body .pl-sr .pl-sra {\n  color: var(--color-prettylights-syntax-string);\n}\n\n.markdown-body .pl-v,\n.markdown-body .pl-smw {\n  color: var(--color-prettylights-syntax-variable);\n}\n\n.markdown-body .pl-bu {\n  color: var(--color-prettylights-syntax-brackethighlighter-unmatched);\n}\n\n.markdown-body .pl-ii {\n  color: var(--color-prettylights-syntax-invalid-illegal-text);\n  background-color: var(--color-prettylights-syntax-invalid-illegal-bg);\n}\n\n.markdown-body .pl-c2 {\n  color: var(--color-prettylights-syntax-carriage-return-text);\n  background-color: var(--color-prettylights-syntax-carriage-return-bg);\n}\n\n.markdown-body .pl-sr .pl-cce {\n  font-weight: bold;\n  color: var(--color-prettylights-syntax-string-regexp);\n}\n\n.markdown-body .pl-ml {\n  color: var(--color-prettylights-syntax-markup-list);\n}\n\n.markdown-body .pl-mh,\n.markdown-body .pl-mh .pl-en,\n.markdown-body .pl-ms {\n  font-weight: bold;\n  color: var(--color-prettylights-syntax-markup-heading);\n}\n\n.markdown-body .pl-mi {\n  font-style: italic;\n  color: var(--color-prettylights-syntax-markup-italic);\n}\n\n.markdown-body .pl-mb {\n  font-weight: bold;\n  color: var(--color-prettylights-syntax-markup-bold);\n}\n\n.markdown-body .pl-md {\n  color: var(--color-prettylights-syntax-markup-deleted-text);\n  background-color: var(--color-prettylights-syntax-markup-deleted-bg);\n}\n\n.markdown-body .pl-mi1 {\n  color: var(--color-prettylights-syntax-markup-inserted-text);\n  background-color: var(--color-prettylights-syntax-markup-inserted-bg);\n}\n\n.markdown-body .pl-mc {\n  color: var(--color-prettylights-syntax-markup-changed-text);\n  background-color: var(--color-prettylights-syntax-markup-changed-bg);\n}\n\n.markdown-body .pl-mi2 {\n  color: var(--color-prettylights-syntax-markup-ignored-text);\n  background-color: var(--color-prettylights-syntax-markup-ignored-bg);\n}\n\n.markdown-body .pl-mdr {\n  font-weight: bold;\n  color: var(--color-prettylights-syntax-meta-diff-range);\n}\n\n.markdown-body .pl-ba {\n  color: var(--color-prettylights-syntax-brackethighlighter-angle);\n}\n\n.markdown-body .pl-sg {\n  color: var(--color-prettylights-syntax-sublimelinter-gutter-mark);\n}\n\n.markdown-body .pl-corl {\n  text-decoration: underline;\n  color: var(--color-prettylights-syntax-constant-other-reference-link);\n}\n\n.markdown-body g-emoji {\n  display: inline-block;\n  min-width: 1ch;\n  font-family: \"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";\n  font-size: 1em;\n  font-style: normal !important;\n  font-weight: var(--base-text-weight-normal, 400);\n  line-height: 1;\n  vertical-align: -0.075em;\n}\n\n.markdown-body g-emoji img {\n  width: 1em;\n  height: 1em;\n}\n\n.markdown-body .task-list-item {\n  list-style-type: none;\n}\n\n.markdown-body .task-list-item label {\n  font-weight: var(--base-text-weight-normal, 400);\n}\n\n.markdown-body .task-list-item.enabled label {\n  cursor: pointer;\n}\n\n.markdown-body .task-list-item+.task-list-item {\n  margin-top: 4px;\n}\n\n.markdown-body .task-list-item .handle {\n  display: none;\n}\n\n.markdown-body .task-list-item-checkbox {\n  margin: 0 .2em .25em -1.4em;\n  vertical-align: middle;\n}\n\n.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox {\n  margin: 0 -1.6em .25em .2em;\n}\n\n.markdown-body .contains-task-list {\n  position: relative;\n}\n\n.markdown-body .contains-task-list:hover .task-list-item-convert-container,\n.markdown-body .contains-task-list:focus-within .task-list-item-convert-container {\n  display: block;\n  width: auto;\n  height: 24px;\n  overflow: visible;\n  clip: auto;\n}\n\n.markdown-body ::-webkit-calendar-picker-indicator {\n  filter: invert(50%);\n}\n"
  },
  {
    "path": "src/styles/lib/highlight.less",
    "content": "html.dark {\n\tpre code.hljs {\n\t\tdisplay: block;\n\t\toverflow-x: auto;\n\t\tpadding: 1em\n\t}\n\n\tcode.hljs {\n\t\tpadding: 3px 5px\n\t}\n\n\t.hljs {\n\t\tcolor: #abb2bf;\n\t\tbackground: #282c34\n\t}\n\n\t.hljs-keyword,\n\t.hljs-operator,\n\t.hljs-pattern-match {\n\t\tcolor: #f92672\n\t}\n\n\t.hljs-function,\n\t.hljs-pattern-match .hljs-constructor {\n\t\tcolor: #61aeee\n\t}\n\n\t.hljs-function .hljs-params {\n\t\tcolor: #a6e22e\n\t}\n\n\t.hljs-function .hljs-params .hljs-typing {\n\t\tcolor: #fd971f\n\t}\n\n\t.hljs-module-access .hljs-module {\n\t\tcolor: #7e57c2\n\t}\n\n\t.hljs-constructor {\n\t\tcolor: #e2b93d\n\t}\n\n\t.hljs-constructor .hljs-string {\n\t\tcolor: #9ccc65\n\t}\n\n\t.hljs-comment,\n\t.hljs-quote {\n\t\tcolor: #b18eb1;\n\t\tfont-style: italic\n\t}\n\n\t.hljs-doctag,\n\t.hljs-formula {\n\t\tcolor: #c678dd\n\t}\n\n\t.hljs-deletion,\n\t.hljs-name,\n\t.hljs-section,\n\t.hljs-selector-tag,\n\t.hljs-subst {\n\t\tcolor: #e06c75\n\t}\n\n\t.hljs-literal {\n\t\tcolor: #56b6c2\n\t}\n\n\t.hljs-addition,\n\t.hljs-attribute,\n\t.hljs-meta .hljs-string,\n\t.hljs-regexp,\n\t.hljs-string {\n\t\tcolor: #98c379\n\t}\n\n\t.hljs-built_in,\n\t.hljs-class .hljs-title,\n\t.hljs-title.class_ {\n\t\tcolor: #e6c07b\n\t}\n\n\t.hljs-attr,\n\t.hljs-number,\n\t.hljs-selector-attr,\n\t.hljs-selector-class,\n\t.hljs-selector-pseudo,\n\t.hljs-template-variable,\n\t.hljs-type,\n\t.hljs-variable {\n\t\tcolor: #d19a66\n\t}\n\n\t.hljs-bullet,\n\t.hljs-link,\n\t.hljs-meta,\n\t.hljs-selector-id,\n\t.hljs-symbol,\n\t.hljs-title {\n\t\tcolor: #61aeee\n\t}\n\n\t.hljs-emphasis {\n\t\tfont-style: italic\n\t}\n\n\t.hljs-strong {\n\t\tfont-weight: 700\n\t}\n\n\t.hljs-link {\n\t\ttext-decoration: underline\n\t}\n}\n\nhtml {\n\tpre code.hljs {\n\t\tdisplay: block;\n\t\toverflow-x: auto;\n\t\tpadding: 1em\n\t}\n\n\tcode.hljs {\n\t\tpadding: 3px 5px;\n\t\t&::-webkit-scrollbar {\n\t\t\theight: 4px;\n\t\t}\n\t}\n\n\t.hljs {\n\t\tcolor: #383a42;\n\t\tbackground: #fafafa\n\t}\n\n\t.hljs-comment,\n\t.hljs-quote {\n\t\tcolor: #a0a1a7;\n\t\tfont-style: italic\n\t}\n\n\t.hljs-doctag,\n\t.hljs-formula,\n\t.hljs-keyword {\n\t\tcolor: #a626a4\n\t}\n\n\t.hljs-deletion,\n\t.hljs-name,\n\t.hljs-section,\n\t.hljs-selector-tag,\n\t.hljs-subst {\n\t\tcolor: #e45649\n\t}\n\n\t.hljs-literal {\n\t\tcolor: #0184bb\n\t}\n\n\t.hljs-addition,\n\t.hljs-attribute,\n\t.hljs-meta .hljs-string,\n\t.hljs-regexp,\n\t.hljs-string {\n\t\tcolor: #50a14f\n\t}\n\n\t.hljs-attr,\n\t.hljs-number,\n\t.hljs-selector-attr,\n\t.hljs-selector-class,\n\t.hljs-selector-pseudo,\n\t.hljs-template-variable,\n\t.hljs-type,\n\t.hljs-variable {\n\t\tcolor: #986801\n\t}\n\n\t.hljs-bullet,\n\t.hljs-link,\n\t.hljs-meta,\n\t.hljs-selector-id,\n\t.hljs-symbol,\n\t.hljs-title {\n\t\tcolor: #4078f2\n\t}\n\n\t.hljs-built_in,\n\t.hljs-class .hljs-title,\n\t.hljs-title.class_ {\n\t\tcolor: #c18401\n\t}\n\n\t.hljs-emphasis {\n\t\tfont-style: italic\n\t}\n\n\t.hljs-strong {\n\t\tfont-weight: 700\n\t}\n\n\t.hljs-link {\n\t\ttext-decoration: underline\n\t}\n}\n"
  },
  {
    "path": "src/styles/lib/tailwind.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
  },
  {
    "path": "src/typings/chat.d.ts",
    "content": "declare namespace Chat {\n\tinterface VideoUrl{\n\t\turl:string\n\t}\n\tinterface Chat {\n\t\tdateTime: string\n\t\ttext: string\n\t\tinversion?: boolean\n\t\terror?: boolean\n\t\tloading?: boolean\n\t\tconversationOptions?: ConversationRequest | null\n\t\trequestOptions: { prompt: string; options?: ConversationRequest | null }\n\t\tmodel?:string //模型\n\t\tmjID?:string //MJ的ID\n\t\topt?:{\n\t\t\tprogress?:string,seed?:number, imageUrl?:string\n\t\t\t, status?:string, images?:string[]\n\t\t\t,promptEn?:string,buttons?:any[]\n\t\t\t,action?:string\n\t\t\t,duration?:number\n\t\t\t,lkey?:string\n\t\t\t,videoUrls?:VideoUrl[]\n\t\t\t,imageUrls?:VideoUrl[]\n\t\t} //\n\t\tuuid?:number\n\t\tindex?:number\n\t\tmyid?:string //唯一随机\n\t\tlogo?:string\n\t\t\n\t\t//progress?:string\n\t}\n\n\tinterface History {\n\t\ttitle: string\n\t\tisEdit: boolean\n\t\tuuid: number\n\t}\n\n\tinterface ChatState {\n\t\tactive: number | null\n\t\tusingContext: boolean;\n\t\thistory: History[]\n\t\tchat: { uuid: number; data: Chat[] }[]\n\t}\n\n\tinterface ConversationRequest {\n\t\tconversationId?: string\n\t\tparentMessageId?: string\n\t}\n\n\tinterface ConversationResponse {\n\t\tconversationId: string\n\t\tdetail: {\n\t\t\tchoices: { finish_reason: string; index: number; logprobs: any; text: string }[]\n\t\t\tcreated: number\n\t\t\tid: string\n\t\t\tmodel: string\n\t\t\tobject: string\n\t\t\tusage: { completion_tokens: number; prompt_tokens: number; total_tokens: number }\n\t\t}\n\t\tid: string\n\t\tparentMessageId: string\n\t\trole: string\n\t\ttext: string\n\t}\n}\n"
  },
  {
    "path": "src/typings/env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ninterface ImportMetaEnv {\n\treadonly VITE_GLOB_API_URL: string;\n\treadonly VITE_APP_API_BASE_URL: string;\n\treadonly VITE_GLOB_OPEN_LONG_REPLY: string;\n\treadonly VITE_GLOB_APP_PWA: string;\n}\n"
  },
  {
    "path": "src/typings/global.d.ts",
    "content": "interface Window {\n  $loadingBar?: import('naive-ui').LoadingBarProviderInst;\n  $dialog?: import('naive-ui').DialogProviderInst;\n  $message?: import('naive-ui').MessageProviderInst;\n  $notification?: import('naive-ui').NotificationProviderInst;\n}\n"
  },
  {
    "path": "src/utils/copy.ts",
    "content": "export function copyToClip(text: string) {\n  return new Promise((resolve, reject) => {\n    try {\n      const input: HTMLTextAreaElement = document.createElement('textarea')\n      input.setAttribute('readonly', 'readonly')\n      input.value = text\n      document.body.appendChild(input)\n      input.select()\n      if (document.execCommand('copy'))\n        document.execCommand('copy')\n      document.body.removeChild(input)\n      resolve(text)\n    }\n    catch (error) {\n      reject(error)\n    }\n  })\n}\n"
  },
  {
    "path": "src/utils/functions/debounce.ts",
    "content": "type CallbackFunc<T extends unknown[]> = (...args: T) => void\n\nexport function debounce<T extends unknown[]>(\n  func: CallbackFunc<T>,\n  wait: number,\n): (...args: T) => void {\n  let timeoutId: ReturnType<typeof setTimeout> | undefined\n\n  return (...args: T) => {\n    const later = () => {\n      clearTimeout(timeoutId)\n      func(...args)\n    }\n\n    clearTimeout(timeoutId)\n    timeoutId = setTimeout(later, wait)\n  }\n}\n"
  },
  {
    "path": "src/utils/functions/index.ts",
    "content": "export function getCurrentDate() {\n  const date = new Date()\n  const day = date.getDate()\n  const month = date.getMonth() + 1\n  const year = date.getFullYear()\n  return `${year}-${month}-${day}`\n}\n"
  },
  {
    "path": "src/utils/is/index.ts",
    "content": "export function isNumber<T extends number>(value: T | unknown): value is number {\n  return Object.prototype.toString.call(value) === '[object Number]'\n}\n\nexport function isString<T extends string>(value: T | unknown): value is string {\n  return Object.prototype.toString.call(value) === '[object String]'\n}\n\nexport function isBoolean<T extends boolean>(value: T | unknown): value is boolean {\n  return Object.prototype.toString.call(value) === '[object Boolean]'\n}\n\nexport function isNull<T extends null>(value: T | unknown): value is null {\n  return Object.prototype.toString.call(value) === '[object Null]'\n}\n\nexport function isUndefined<T extends undefined>(value: T | unknown): value is undefined {\n  return Object.prototype.toString.call(value) === '[object Undefined]'\n}\n\nexport function isObject<T extends object>(value: T | unknown): value is object {\n  return Object.prototype.toString.call(value) === '[object Object]'\n}\n\nexport function isArray<T extends any[]>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Array]'\n}\n\nexport function isFunction<T extends (...args: any[]) => any | void | never>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Function]'\n}\n\nexport function isDate<T extends Date>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Date]'\n}\n\nexport function isRegExp<T extends RegExp>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object RegExp]'\n}\n\nexport function isPromise<T extends Promise<any>>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Promise]'\n}\n\nexport function isSet<T extends Set<any>>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Set]'\n}\n\nexport function isMap<T extends Map<any, any>>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object Map]'\n}\n\nexport function isFile<T extends File>(value: T | unknown): value is T {\n  return Object.prototype.toString.call(value) === '[object File]'\n}\n"
  },
  {
    "path": "src/utils/request/axios.ts",
    "content": "import axios, { type AxiosResponse } from 'axios'\nimport { useAuthStore } from '@/store'\n\nconst service = axios.create({\n  baseURL: import.meta.env.VITE_GLOB_API_URL,\n})\n\nservice.interceptors.request.use(\n  (config) => {\n    const token = useAuthStore().token\n    if (token)\n      config.headers.Authorization = `Bearer ${token}`\n    return config\n  },\n  (error) => {\n    return Promise.reject(error.response)\n  },\n)\n\nservice.interceptors.response.use(\n  (response: AxiosResponse): AxiosResponse => {\n    if (response.status === 200)\n      return response\n\n    throw new Error(response.status.toString())\n  },\n  (error) => {\n    return Promise.reject(error)\n  },\n)\n\nexport default service\n"
  },
  {
    "path": "src/utils/request/index.ts",
    "content": "import type { AxiosProgressEvent, AxiosResponse, GenericAbortSignal } from 'axios'\nimport request from './axios'\nimport { useAuthStore } from '@/store'\n\nexport interface HttpOption {\n  url: string\n  data?: any\n  method?: string\n  headers?: any\n  onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void\n  signal?: GenericAbortSignal\n  beforeRequest?: () => void\n  afterRequest?: () => void\n}\n\nexport interface Response<T = any> {\n  data: T\n  message: string | null\n  status: string\n}\n\nfunction http<T = any>(\n  { url, data, method, headers, onDownloadProgress, signal, beforeRequest, afterRequest }: HttpOption,\n) {\n  const successHandler = (res: AxiosResponse<Response<T>>) => {\n    const authStore = useAuthStore()\n\n    if (res.data.status === 'Success' || typeof res.data === 'string')\n      return res.data\n\n    if (res.data.status === 'Unauthorized') {\n      authStore.removeToken()\n      window.location.reload()\n    }\n\n    return Promise.reject(res.data)\n  }\n\n  const failHandler = (error: Response<Error>) => {\n    afterRequest?.()\n    throw new Error(error?.message || 'Error')\n  }\n\n  beforeRequest?.()\n\n  method = method || 'GET'\n\n  const params = Object.assign(typeof data === 'function' ? data() : data ?? {}, {})\n\n  return method === 'GET'\n    ? request.get(url, { params, signal, onDownloadProgress }).then(successHandler, failHandler)\n    : request.post(url, params, { headers, signal, onDownloadProgress }).then(successHandler, failHandler)\n}\n\nexport function get<T = any>(\n  { url, data, method = 'GET', onDownloadProgress, signal, beforeRequest, afterRequest }: HttpOption,\n): Promise<Response<T>> {\n  return http<T>({\n    url,\n    method,\n    data,\n    onDownloadProgress,\n    signal,\n    beforeRequest,\n    afterRequest,\n  })\n}\n\nexport function post<T = any>(\n  { url, data, method = 'POST', headers, onDownloadProgress, signal, beforeRequest, afterRequest }: HttpOption,\n): Promise<Response<T>> {\n  return http<T>({\n    url,\n    method,\n    data,\n    headers,\n    onDownloadProgress,\n    signal,\n    beforeRequest,\n    afterRequest,\n  })\n}\n\nexport default post\n"
  },
  {
    "path": "src/utils/storage/index.ts",
    "content": "interface StorageData<T = any> {\n  data: T\n  expire: number | null\n}\n\nexport function createLocalStorage(options?: { expire?: number | null }) {\n  const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7\n\n  const { expire } = Object.assign({ expire: DEFAULT_CACHE_TIME }, options)\n\n  function set<T = any>(key: string, data: T) {\n    const storageData: StorageData<T> = {\n      data,\n      expire: expire !== null ? new Date().getTime() + expire * 1000 : null,\n    }\n\n    const json = JSON.stringify(storageData)\n    window.localStorage.setItem(key, json)\n  }\n\n  function get(key: string) {\n    const json = window.localStorage.getItem(key)\n    if (json) {\n      let storageData: StorageData | null = null\n\n      try {\n        storageData = JSON.parse(json)\n      }\n      catch {\n        // Prevent failure\n      }\n\n      if (storageData) {\n        const { data, expire } = storageData\n        if (expire === null || expire >= Date.now())\n          return data\n      }\n\n      remove(key)\n      return null\n    }\n  }\n\n  function remove(key: string) {\n    window.localStorage.removeItem(key)\n  }\n\n  function clear() {\n    window.localStorage.clear()\n  }\n\n  return { set, get, remove, clear }\n}\n\nexport const ls = createLocalStorage()\n\nexport const ss = createLocalStorage({ expire: null })\n"
  },
  {
    "path": "src/utils/wav_renderer.ts",
    "content": "const dataMap = new WeakMap();\n\n/**\n * Normalizes a Float32Array to Array(m): We use this to draw amplitudes on a graph\n * If we're rendering the same audio data, then we'll often be using\n * the same (data, m, downsamplePeaks) triplets so we give option to memoize\n */\nconst normalizeArray = (\n  data: Float32Array,\n  m: number,\n  downsamplePeaks: boolean = false,\n  memoize: boolean = false\n) => {\n  let cache, mKey, dKey;\n  if (memoize) {\n    mKey = m.toString();\n    dKey = downsamplePeaks.toString();\n    cache = dataMap.has(data) ? dataMap.get(data) : {};\n    dataMap.set(data, cache);\n    cache[mKey] = cache[mKey] || {};\n    if (cache[mKey][dKey]) {\n      return cache[mKey][dKey];\n    }\n  }\n  const n = data.length;\n  const result = new Array(m);\n  if (m <= n) {\n    // Downsampling\n    result.fill(0);\n    const count = new Array(m).fill(0);\n    for (let i = 0; i < n; i++) {\n      const index = Math.floor(i * (m / n));\n      if (downsamplePeaks) {\n        // take highest result in the set\n        result[index] = Math.max(result[index], Math.abs(data[i]));\n      } else {\n        result[index] += Math.abs(data[i]);\n      }\n      count[index]++;\n    }\n    if (!downsamplePeaks) {\n      for (let i = 0; i < result.length; i++) {\n        result[i] = result[i] / count[i];\n      }\n    }\n  } else {\n    for (let i = 0; i < m; i++) {\n      const index = (i * (n - 1)) / (m - 1);\n      const low = Math.floor(index);\n      const high = Math.ceil(index);\n      const t = index - low;\n      if (high >= n) {\n        result[i] = data[n - 1];\n      } else {\n        result[i] = data[low] * (1 - t) + data[high] * t;\n      }\n    }\n  }\n  if (memoize) {\n    cache[mKey as string][dKey as string] = result;\n  }\n  return result;\n};\n\nexport const WavRenderer = {\n  /**\n   * Renders a point-in-time snapshot of an audio sample, usually frequency values\n   * @param canvas\n   * @param ctx\n   * @param data\n   * @param color\n   * @param pointCount number of bars to render\n   * @param barWidth width of bars in px\n   * @param barSpacing spacing between bars in px\n   * @param center vertically center the bars\n   */\n  drawBars: (\n    canvas: HTMLCanvasElement,\n    ctx: CanvasRenderingContext2D,\n    data: Float32Array,\n    color: string,\n    pointCount: number = 0,\n    barWidth: number = 0,\n    barSpacing: number = 0,\n    center: boolean = false\n  ) => {\n    pointCount = Math.floor(\n      Math.min(\n        pointCount,\n        (canvas.width - barSpacing) / (Math.max(barWidth, 1) + barSpacing)\n      )\n    );\n    if (!pointCount) {\n      pointCount = Math.floor(\n        (canvas.width - barSpacing) / (Math.max(barWidth, 1) + barSpacing)\n      );\n    }\n    if (!barWidth) {\n      barWidth = (canvas.width - barSpacing) / pointCount - barSpacing;\n    }\n    const points = normalizeArray(data, pointCount, true);\n    for (let i = 0; i < pointCount; i++) {\n      const amplitude = Math.abs(points[i]);\n      const height = Math.max(1, amplitude * canvas.height);\n      const x = barSpacing + i * (barWidth + barSpacing);\n      const y = center ? (canvas.height - height) / 2 : canvas.height - height;\n      ctx.fillStyle = color;\n      ctx.fillRect(x, y, barWidth, height);\n    }\n  },\n};\n"
  },
  {
    "path": "src/utils/webdav.ts",
    "content": "﻿// WebDAV 同步工具\ninterface WebDAVConfig {\n  url: string\n  username: string\n  password: string\n}\n\nconst WEBDAV_CONFIG_KEY = 'webdav_config'\nconst WEBDAV_FILE_NAME = 'chatgpt-backup.json'\n\nexport function getWebDAVConfig(): WebDAVConfig | null {\n  const config = localStorage.getItem(WEBDAV_CONFIG_KEY)\n  return config ? JSON.parse(config) : null\n}\n\nexport function saveWebDAVConfig(config: WebDAVConfig): void {\n  localStorage.setItem(WEBDAV_CONFIG_KEY, JSON.stringify(config))\n}\n\nasync function webdavRequest(config: WebDAVConfig, method: string, data?: string) {\n  const url = `${config.url.replace(/\\/$/, '')}/${WEBDAV_FILE_NAME}`\n  const res = await fetch('/api/webdav-proxy', {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ url, method, username: config.username, password: config.password, data }),\n  })\n  const result = await res.json()\n  if (!result.success)\n    throw new Error(result.error || '请求失败')\n  return result\n}\n\nexport async function syncToWebDAV(): Promise<void> {\n  const config = getWebDAVConfig()\n  if (!config)\n    throw new Error('WebDAV 未配置')\n  \n  const data = localStorage.getItem('chatStorage') || '{}'\n  \n  // 尝试上传，如果失败尝试创建目录再上传\n  try {\n    await webdavRequest(config, 'PUT', data)\n  }\n  catch (error: any) {\n    if (error.message.includes('409')) {\n      await fetch('/api/webdav-proxy', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          url: config.url.replace(/\\/$/, ''),\n          method: 'MKCOL',\n          username: config.username,\n          password: config.password,\n        }),\n      })\n      await webdavRequest(config, 'PUT', data)\n    }\n    else {\n      throw error\n    }\n  }\n}\n\nexport async function syncFromWebDAV(): Promise<void> {\n  const config = getWebDAVConfig()\n  if (!config)\n    throw new Error('WebDAV 未配置')\n  \n  const result = await webdavRequest(config, 'GET')\n  try {\n    localStorage.setItem('chatStorage', result.data || '{}')\n  }\n  catch {\n    throw new Error('浏览器存储限制，请使用Chrome/Edge或手动导入文件')\n  }}\n\n"
  },
  {
    "path": "src/views/chat/components/Header/index.vue",
    "content": "<script lang=\"ts\" setup>\nimport { computed, nextTick,ref,watch  } from 'vue'\nimport { HoverButton, SvgIcon } from '@/components/common'\nimport {  gptConfigStore, homeStore, useAppStore, useChatStore } from '@/store'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport {NModal} from \"naive-ui\"\nimport aiModel from \"@/views/mj/aiModel.vue\"\nimport { chatSetting, mlog } from '@/api'\nimport { debounce } from '@/utils/functions/debounce'\n\nconst { isMobile } = useBasicLayout()\n\ninterface Props {\n  usingContext: boolean\n}\n\ninterface Emit {\n  (ev: 'export'): void\n  (ev: 'handleClear'): void\n}\n\ndefineProps<Props>()\n\nconst emit = defineEmits<Emit>()\n\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\n\nconst collapsed = computed(() => appStore.siderCollapsed)\nconst currentChatHistory = computed(() => chatStore.getChatHistoryByCurrentActive)\n\nfunction handleUpdateCollapsed() {\n  appStore.setSiderCollapsed(!collapsed.value)\n}\n\nfunction onScrollToTop() {\n  const scrollRef = document.querySelector('#scrollRef')\n  if (scrollRef)\n    nextTick(() => scrollRef.scrollTop = 0)\n}\n\nfunction handleExport() {\n  emit('export')\n}\n\nfunction handleClear() {\n  emit('handleClear')\n}\nconst uuid = chatStore.active;\nconst chatSet = new chatSetting( uuid==null?1002:uuid);\nconst nGptStore = ref()  ;\nnGptStore.value=  chatSet.getGptConfig() ;\nconst st = ref({isShow:false});\n//导致卡死的原因 当删除时触发 切换 uuid 这个地方会删除的uuid 跟新uuid 一直却换\nwatch(()=>gptConfigStore.myData,debounce( ()=>{\n  mlog(\"toMyuid19\",\"watch gptConfigStore.myData \",  chatStore.active  )\n  nGptStore.value=  chatSet.getGptConfig() \n},600 ), {deep:true})\nwatch(()=>homeStore.myData.act,debounce( (n)=> n=='saveChat' && (nGptStore.value=  chatSet.getGptConfig() ),600), {deep:true})\n</script>\n\n<template>\n  <header\n    class=\"sticky top-0 left-0 right-0 z-30 border-b dark:border-neutral-800 bg-white/80 dark:bg-black/20 backdrop-blur\"\n  >\n    <div class=\"relative flex items-center justify-between min-w-0 overflow-hidden h-14\" data-tauri-drag-region>\n      <div class=\"flex items-center\">\n        <button\n          class=\"flex items-center justify-center w-11 h-11\"\n          @click=\"handleUpdateCollapsed\" v-if=\"isMobile\"\n        >\n          <SvgIcon v-if=\"collapsed\" class=\"text-2xl\" icon=\"ri:align-justify\" />\n          <SvgIcon v-else class=\"text-2xl\" icon=\"ri:align-right\" />\n        </button>\n      </div>\n      <h1  class=\"flex-1 px-4 pr-6 overflow-hidden cursor-pointer select-none text-ellipsis whitespace-nowrap\"\n        @dblclick=\"onScrollToTop\" data-tauri-drag-region>\n        {{ currentChatHistory?.title ?? '' }}\n      </h1>\n      <div class=\"flex items-center space-x-2\">\n        <HoverButton @click=\"handleExport\">\n          <span class=\"text-xl text-[#4f555e] dark:text-white\">\n            <SvgIcon icon=\"ri:download-2-line\" />\n          </span>\n        </HoverButton>\n        <HoverButton @click=\"handleClear\">\n          <span class=\"text-xl text-[#4f555e] dark:text-white\">\n            <SvgIcon icon=\"ri:delete-bin-line\" />\n          </span>\n        </HoverButton>\n      </div>\n    </div>\n    \n    <div @click=\"st.isShow=true\" class=\"absolute left-1/2   top-full -translate-x-1/2 cursor-pointer select-none rounded-b-md border  bg-white px-2 dark:border-neutral-800 dark:bg-[#111114]\">\n    <!-- <div @click=\"st.isShow=true\" class=\"absolute left-1/2   top-full -translate-x-1/2 cursor-pointer select-none rounded-b-md px-2\"> -->\n        <div class=\"flex items-center   justify-center space-x-1 cursor-pointer hover:text-[#4b9e5f]\" v-if=\"homeStore.myData.local!='draw'\">\n            <template   v-if=\"nGptStore.gpts\">\n             <SvgIcon icon=\"ri:apps-fill\" /> \n             <span class=\"line-clamp-1 overflow-hidden\">{{ nGptStore.gpts.name }}</span> \n            </template>\n            <template v-else >\n            <SvgIcon icon=\"heroicons:sparkles\" /> \n            <span >{{ nGptStore.model }}</span> \n            </template>\n            <SvgIcon icon=\"icon-park-outline:right\" />\n        </div>\n    </div>\n  </header>\n\n  <NModal v-model:show=\"st.isShow\"   preset=\"card\"  :title=\"$t('mjchat.modelChange')\" class=\"!max-w-[620px]\" @close=\"st.isShow=false\" >  \n        <aiModel @close=\"st.isShow=false\"/>\n  </NModal>\n</template>\n"
  },
  {
    "path": "src/views/chat/components/Message/Avatar.vue",
    "content": "<script lang=\"ts\" setup>\nimport { computed } from 'vue'\nimport { NAvatar } from 'naive-ui'\nimport { useUserStore } from '@/store'\nimport { isString } from '@/utils/is'\nimport defaultAvatar from '@/assets/avatar.jpg'\n\ninterface Props {\n  image?: boolean\n  logo?:string\n}\ndefineProps<Props>()\n\nconst userStore = useUserStore()\n\nconst avatar = computed(() => userStore.userInfo.avatar)\n</script>\n\n<template>\n  \n   <NAvatar v-if=\"logo\"     :src=\"logo\" />\n  <template v-else-if=\"image\">\n    <NAvatar v-if=\"isString(avatar) && avatar.length > 0\" :src=\"avatar\" :fallback-src=\"defaultAvatar\" />\n    <NAvatar v-else round :src=\"defaultAvatar\" />\n  </template>\n  <span v-else class=\"text-[28px] dark:text-white\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" aria-hidden=\"true\" width=\"1em\" height=\"1em\">\n      <path d=\"M29.71,13.09A8.09,8.09,0,0,0,20.34,2.68a8.08,8.08,0,0,0-13.7,2.9A8.08,8.08,0,0,0,2.3,18.9,8,8,0,0,0,3,25.45a8.08,8.08,0,0,0,8.69,3.87,8,8,0,0,0,6,2.68,8.09,8.09,0,0,0,7.7-5.61,8,8,0,0,0,5.33-3.86A8.09,8.09,0,0,0,29.71,13.09Zm-12,16.82a6,6,0,0,1-3.84-1.39l.19-.11,6.37-3.68a1,1,0,0,0,.53-.91v-9l2.69,1.56a.08.08,0,0,1,.05.07v7.44A6,6,0,0,1,17.68,29.91ZM4.8,24.41a6,6,0,0,1-.71-4l.19.11,6.37,3.68a1,1,0,0,0,1,0l7.79-4.49V22.8a.09.09,0,0,1,0,.08L13,26.6A6,6,0,0,1,4.8,24.41ZM3.12,10.53A6,6,0,0,1,6.28,7.9v7.57a1,1,0,0,0,.51.9l7.75,4.47L11.85,22.4a.14.14,0,0,1-.09,0L5.32,18.68a6,6,0,0,1-2.2-8.18Zm22.13,5.14-7.78-4.52L20.16,9.6a.08.08,0,0,1,.09,0l6.44,3.72a6,6,0,0,1-.9,10.81V16.56A1.06,1.06,0,0,0,25.25,15.67Zm2.68-4-.19-.12-6.36-3.7a1,1,0,0,0-1.05,0l-7.78,4.49V9.2a.09.09,0,0,1,0-.09L19,5.4a6,6,0,0,1,8.91,6.21ZM11.08,17.15,8.38,15.6a.14.14,0,0,1-.05-.08V8.1a6,6,0,0,1,9.84-4.61L18,3.6,11.61,7.28a1,1,0,0,0-.53.91ZM12.54,14,16,12l3.47,2v4L16,20l-3.47-2Z\" fill=\"currentColor\" />\n    </svg>\n  </span>\n</template>\n"
  },
  {
    "path": "src/views/chat/components/Message/Text.vue",
    "content": "<script lang=\"ts\" setup>\nimport { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue'\nimport MarkdownIt from 'markdown-it'\nimport mdKatex from '@traptitech/markdown-it-katex'\nimport mila from 'markdown-it-link-attributes'\nimport hljs from 'highlight.js'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { t } from '@/locales'\nimport { copyToClip } from '@/utils/copy'\n\nimport mjText from '@/views/mj/mjText.vue'\nimport dallText from '@/views/mj/dallText.vue'\nimport ttsText from '@/views/mj/ttsText.vue'\nimport whisperText from '@/views/mj/whisperText.vue'\nimport MjTextAttr from '@/views/mj/mjTextAttr.vue'\nimport aiTextSetting from '@/views/mj/aiTextSetting.vue'\nimport aiSetAuth from '@/views/mj/aiSetAuth.vue'\nimport { isApikeyError, isAuthSessionError, isDallImageModel, isTTS, mlog } from '@/api'\n\ninterface Props {\n  inversion?: boolean\n  error?: boolean\n  text?: string\n  loading?: boolean\n  asRawText?: boolean\n  chat:Chat.Chat\n}\n\nconst props = defineProps<Props>()\n\nconst { isMobile } = useBasicLayout()\n\nconst textRef = ref<HTMLElement>()\n\nconst mdi = new MarkdownIt({\n  html: false,\n  linkify: true,\n  highlight(code, language) {\n    const validLang = !!(language && hljs.getLanguage(language))\n    if (validLang) {\n      const lang = language ?? ''\n      return highlightBlock(hljs.highlight(code, { language: lang }).value, lang)\n    }\n    return highlightBlock(hljs.highlightAuto(code).value, '')\n  },\n})\n\nmdi.use(mila, { attrs: { target: '_blank', rel: 'noopener' } })\nmdi.use(mdKatex, { blockClass: 'katexmath-block rounded-md p-[10px]', errorColor: ' #cc0000' })\n\nconst wrapClass = computed(() => {\n  return [\n    'text-wrap',\n    'min-w-[20px]','max-w-[810px]',\n    'rounded-md',\n    isMobile.value ? 'p-2' : 'px-3 py-2',\n    props.inversion ? 'bg-[#d2f9d1]' : 'bg-[#f4f6f8]',\n    props.inversion ? 'dark:bg-[#a1dc95]' : 'dark:bg-[#1e1e20]',\n    props.inversion ? 'message-request' : 'message-reply',\n    { 'text-red-500': props.error },\n  ]\n})\n\nconst text = computed(() => {\n  let value = props.text ?? ''\n  if (!props.asRawText){\n    value = value.replace(/\\\\\\( *(.*?) *\\\\\\)/g, '$$$1$$');\n    //value = value.replace(/\\\\\\((.*?)\\\\\\)/g, '$$$1$$');\n    value = value.replace(/\\\\\\[ *(.*?) *\\\\\\]/g, '$$$$$1$$$$');\n    //\n    value= value.replaceAll('\\\\[',\"$$$$\")\n    value= value.replaceAll('\\\\]',\"$$$$\")   \n\n    //思考过程处理\n    //value= value.replace(/<think>([\\s\\S]*?)<\\/think>/g, (match: string, content: string) => { \n    value= value.replace(/<think>([\\s\\S]*?)(?=<\\/think>|$)/g, (match: string, content: string) => { \n      const processedContent: string = content\n        .split('\\n')\n        .map(line => line.trim() ? '>' + line : line)  \n        .join('\\n').replace(/(\\r?\\n)+/g, '\\n>\\n');\n       \n      return \">Thinking...\"+(processedContent) ;\n    });\n    value= value.replaceAll('</think>','')\n    //mlog('replace', value)\n    return mdi.render(value) \n  }\n  return value\n})\n\nfunction highlightBlock(str: string, lang?: string) {\n  return `<pre class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-header__lang\">${lang}</span><span class=\"code-block-header__copy\">${t('chat.copyCode')}</span></div><code class=\"hljs code-block-body ${lang}\">${str}</code></pre>`\n}\n\nfunction addCopyEvents() {\n  if (textRef.value) {\n    const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')\n    copyBtn.forEach((btn) => {\n      btn.addEventListener('click', () => {\n        const code = btn.parentElement?.nextElementSibling?.textContent\n        if (code) {\n          copyToClip(code).then(() => {\n            btn.textContent = '复制成功'\n            setTimeout(() => {\n              btn.textContent = '复制代码'\n            }, 1000)\n          })\n        }\n      })\n    })\n  }\n}\n\nfunction removeCopyEvents() {\n  if (textRef.value) {\n    const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')\n    copyBtn.forEach((btn) => {\n      btn.removeEventListener('click', () => {})\n    })\n  }\n}\n\nonMounted(() => {\n  addCopyEvents()\n})\n\nonUpdated(() => {\n  addCopyEvents()\n})\n\nonUnmounted(() => {\n  removeCopyEvents()\n})\n\nconst isDall=(chat: Chat.Chat)=>{\n if(   chat.model=='midjourney'){\n        return false\n  }\n  if( isDallImageModel( chat.model ) ){\n    return true\n  }\n  if(chat.opt?.imageUrl){\n    return true\n  }\n  return false\n}\n</script>\n\n<template>\n  <div class=\"text-black\" :class=\"wrapClass\">\n    <div ref=\"textRef\" class=\"leading-relaxed break-words\">\n      <div v-if=\"!inversion\">\n        <aiTextSetting v-if=\"!inversion && isApikeyError(text)\"/>\n        <aiSetAuth v-if=\"!inversion && isAuthSessionError(text)\" />\n          \n        <dallText :chat=\"chat\" v-if=\" chat.model && chat.model?.indexOf('chat') == -1 && isDall( chat ) \" class=\"whitespace-pre-wrap\" />\n        <mjText v-if=\"chat.mjID\" class=\"whitespace-pre-wrap\" :chat=\"chat\" :mdi=\"mdi\"></mjText>\n        <ttsText v-else-if=\"chat.model && isTTS(chat.model) && chat.text=='ok'\" :chat=\"chat\"/>\n        <template v-else>\n          <div v-if=\"!asRawText\" class=\"markdown-body\" :class=\"{ 'markdown-body-generate': loading }\" v-html=\"text\" />\n          <div v-else class=\"whitespace-pre-wrap\" v-text=\"text\" />\n        </template>\n      </div>\n      <whisperText v-else-if=\"text=='whisper' && chat.opt?.lkey \"  :chat=\"chat\" />\n      <div v-else-if=\"asRawText\" class=\"whitespace-pre-wrap\" v-text=\"text\" />\n      <div v-else class=\"markdown-body \"  style=\"--color-fg-default:#24292f\"  v-html=\"text\" />\n      <!-- <div v-else class=\"whitespace-pre-wrap\" v-text=\"text\" /> -->\n      <MjTextAttr :image=\"chat.opt?.images[0]\" v-if=\"chat.opt?.images\"></MjTextAttr>\n      <whisperText v-if=\"chat.model && chat.model.indexOf('whisper')>-1 && chat.opt?.lkey \" :isW=\"true\"  :chat=\"chat\" class=\"w-full\" />\n      <ttsText v-if=\"!inversion && chat.opt?.duration && chat.opt?.duration>0 && chat.opt?.lkey \" :isW=\"true\"  :chat=\"chat\" class=\"w-full\" />\n\n      \n\n    </div>\n  </div>\n</template>\n\n<style lang=\"less\">\n@import url(./style.less);\n</style>\n"
  },
  {
    "path": "src/views/chat/components/Message/index.vue",
    "content": "<script setup lang='ts'>\nimport { computed, ref, watch } from 'vue'\nimport { NDropdown, useMessage } from 'naive-ui'\nimport AvatarComponent from './Avatar.vue'\nimport TextComponent from './Text.vue'\nimport { SvgIcon } from '@/components/common'\nimport { useIconRender } from '@/hooks/useIconRender'\nimport { t } from '@/locales'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { copyToClip } from '@/utils/copy'\nimport { homeStore } from '@/store'\nimport { getSeed, mlog ,mjImgUrl, isDallImageModel} from '@/api' \n\ninterface Props {\n  dateTime?: string\n  text?: string\n  inversion?: boolean\n  error?: boolean\n  loading?: boolean\n  chat:Chat.Chat\n  index:number\n}\n\ninterface Emit {\n  (ev: 'regenerate'): void\n  (ev: 'delete'): void\n  (ev: 'edit'): void\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits<Emit>()\n\nconst { isMobile } = useBasicLayout()\n\nconst { iconRender } = useIconRender()\n\nconst message = useMessage()\n\nconst textRef = ref<HTMLElement>()\n\nconst asRawText = ref(props.inversion && homeStore.myData.session.isCloseMdPreview)\n\nconst messageRef = ref<HTMLElement>()\n\nconst options = computed(() => {\n  const common = [\n    {\n      label: t('chat.copy'),\n      key: 'copyText',\n      icon: iconRender({ icon: 'ri:file-copy-2-line' }),\n    },\n    {\n      label: t('common.delete'),\n      key: 'delete',\n      icon: iconRender({ icon: 'ri:delete-bin-line' }),\n    },\n    {\n      label: t('common.edit'),\n      key: 'edit',\n      icon: iconRender({ icon: 'ri:edit-2-line' }),\n    },\n  ]\n\n  if (!props.inversion) {\n    common.unshift({\n      label: asRawText.value ? t('chat.preview') : t('chat.showRawText'),\n      key: 'toggleRenderType',\n      icon: iconRender({ icon: asRawText.value ? 'ic:outline-code-off' : 'ic:outline-code' }),\n    });\n    common.unshift({\n      label: t('mj.tts'),\n      key: 'tts',\n      icon: iconRender({ icon:'mdi:tts' }),\n    })\n  }\n\n  return common\n})\n\nfunction handleSelect(key: 'copyText' | 'delete' | 'edit' | 'toggleRenderType' | 'tts') {\n  switch (key) {\n    case 'tts': \n      homeStore.setMyData({act:'gpt.ttsv2', actData:{ index:props.index , uuid:props.chat.uuid, text:props.text } });\n      return;\n    case 'copyText':\n      handleCopy()\n      return\n    case 'toggleRenderType':\n      asRawText.value = !asRawText.value\n      return\n    case 'delete':\n      emit('delete')\n      return\n    case 'edit':\n      emit('edit')\n  }\n}\n\nfunction handleRegenerate() {\n  messageRef.value?.scrollIntoView()\n  emit('regenerate')\n}\n\n\nasync function handleCopy(txt?:string) {\n  try {\n    await copyToClip( txt|| props.text || '')\n    message.success( t('chat.copied'))\n  }\n  catch {\n    message.error( t('mj.copyFail') )\n  }\n}\n\nconst sendReload = () => {\n  homeStore.setMyData({act:'mjReload', actData:{mjID:props.chat.mjID} })\n}\n\nfunction handleRegenerate2() {\n  messageRef.value?.scrollIntoView()\n  //emit('regenerate')\n  mlog('重新发送！');\n  homeStore.setMyData({act:'gpt.resubmit', actData:{ index:props.index , uuid:props.chat.uuid } });\n}\n \n</script>\n\n<template>\n  <div\n    ref=\"messageRef\"\n    class=\"flex w-full mb-6 overflow-hidden\"\n    :class=\"[{ 'flex-row-reverse': inversion }]\"\n  >\n    <div\n      class=\"flex items-center justify-center flex-shrink-0 h-8 overflow-hidden rounded-full basis-8\"\n      :class=\"[inversion ? 'ml-2' : 'mr-2']\"\n    >\n      <AvatarComponent :image=\"inversion\" :logo=\"chat.logo\"/>\n    </div>\n    <div class=\"overflow-hidden text-sm \" :class=\"[inversion ? 'items-end' : 'items-start']\">\n      <p class=\"text-xs group  text-[#b4bbc4] flex  items-center space-x-2 \" :class=\"[inversion ? 'justify-end' : 'justify-start']\">\n        <span>{{ dateTime }}</span>\n        <span v-if=\"chat.model\"  class=\"text-[#b4bbc4]/50\">{{ chat.model }}</span>\n        <!-- <span>{{ chat.opt?.progress }}</span> -->\n        <template  v-if=\"chat.opt?.status=='SUCCESS'\">\n          <SvgIcon icon=\"ri:restart-line\" @click=\"sendReload\"  class=\"cursor-pointer text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-300 \" ></SvgIcon>\n          \n          <div @click=\"getSeed(chat, message )\" class=\"cursor-pointer\">\n            <span v-if=\"chat.opt?.seed\">Seed:{{ chat.opt?.seed }}</span>\n            <span v-else>Seed</span>\n          </div>\n          <a :href=\" mjImgUrl(chat.opt?.imageUrl)\" class=\"hidden group-hover:block active  cursor-pointer underline \" target=\"_blank\">{{ $t('mj.ulink') }}</a>\n        </template>\n      </p>\n      \n      <div  class=\"flex items-end gap-1 mt-2\"\n        :class=\"[inversion ? 'flex-row-reverse' : 'flex-row']\" > \n        <TextComponent \n          ref=\"textRef\"\n          :inversion=\"inversion\"\n          :error=\"error\"\n          :text=\"text\"\n          :loading=\"loading\"\n          :as-raw-text=\"asRawText\"\n          :chat=\"chat\"\n        />\n        <!-- <div class=\"flex flex-col\" v-if=\"!chat.mjID && chat.model!='dall-e-3' && chat.model!='dall-e-2' \"> -->\n        <div class=\"flex flex-col\" v-if=\"!chat.mjID &&   !isDallImageModel(chat.model) \">\n          <!-- <button\n            v-if=\"!inversion \"\n            class=\"mb-2 transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-300\"\n            @click=\"handleRegenerate\"\n          >\n            <SvgIcon icon=\"ri:restart-line\" />\n          </button> -->\n          <button\n            v-if=\"!inversion \"\n            class=\"mb-2 transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-300\"\n            @click=\"handleRegenerate2\"\n          >\n            <SvgIcon icon=\"ri:restart-line\" />\n          </button>\n          <NDropdown\n            :trigger=\"isMobile ? 'click' : 'hover'\"\n            :placement=\"!inversion ? 'right' : 'left'\"\n            :options=\"options\"\n            @select=\"handleSelect\" \n          >\n            <button class=\"transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-200\">\n              <SvgIcon icon=\"ri:more-2-fill\" />\n            </button>\n          </NDropdown>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/views/chat/components/Message/style.less",
    "content": ".markdown-body {\n\tbackground-color: transparent;\n\tfont-size: 14px;\n\n\tp {\n\t\twhite-space: pre-wrap;\n\t}\n\n\tol {\n\t\tlist-style-type: decimal;\n\t}\n\n\tul {\n\t\tlist-style-type: disc;\n\t}\n\timg{\n\t\tmax-width: 400px;\n\t}\n\n\tpre code,\n\tpre tt {\n\t\tline-height: 1.65;\n\t}\n\n\t.highlight pre,\n\tpre {\n\t\tbackground-color: #fff;\n\t}\n\n\tcode.hljs {\n\t\tpadding: 0;\n\t}\n\n\t.code-block {\n\t\t&-wrapper {\n\t\t\tposition: relative;\n\t\t\tpadding-top: 24px;\n\t\t}\n\n\t\t&-header {\n\t\t\tposition: absolute;\n\t\t\ttop: 5px;\n\t\t\tright: 0;\n\t\t\twidth: 100%;\n\t\t\tpadding: 0 1rem;\n\t\t\tdisplay: flex;\n\t\t\tjustify-content: flex-end;\n\t\t\talign-items: center;\n\t\t\tcolor: #b3b3b3;\n\n\t\t\t&__copy {\n\t\t\t\tcursor: pointer;\n\t\t\t\tmargin-left: 0.5rem;\n\t\t\t\tuser-select: none;\n\n\t\t\t\t&:hover {\n\t\t\t\t\tcolor: #65a665;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t&.markdown-body-generate>dd:last-child:after,\n\t&.markdown-body-generate>dl:last-child:after,\n\t&.markdown-body-generate>dt:last-child:after,\n\t&.markdown-body-generate>h1:last-child:after,\n\t&.markdown-body-generate>h2:last-child:after,\n\t&.markdown-body-generate>h3:last-child:after,\n\t&.markdown-body-generate>h4:last-child:after,\n\t&.markdown-body-generate>h5:last-child:after,\n\t&.markdown-body-generate>h6:last-child:after,\n\t&.markdown-body-generate>li:last-child:after,\n\t&.markdown-body-generate>ol:last-child li:last-child:after,\n\t&.markdown-body-generate>p:last-child:after,\n\t&.markdown-body-generate>pre:last-child code:after,\n\t&.markdown-body-generate>td:last-child:after,\n\t&.markdown-body-generate>ul:last-child li:last-child:after {\n\t\tanimation: blink 1s steps(5, start) infinite;\n\t\tcolor: #000;\n\t\tcontent: '_';\n\t\tfont-weight: 700;\n\t\tmargin-left: 3px;\n\t\tvertical-align: baseline;\n\t}\n\n\t@keyframes blink {\n\t\tto {\n\t\t\tvisibility: hidden;\n\t\t}\n\t}\n}\n\nhtml.dark {\n\n\t.markdown-body {\n\n\t\t&.markdown-body-generate>dd:last-child:after,\n\t\t&.markdown-body-generate>dl:last-child:after,\n\t\t&.markdown-body-generate>dt:last-child:after,\n\t\t&.markdown-body-generate>h1:last-child:after,\n\t\t&.markdown-body-generate>h2:last-child:after,\n\t\t&.markdown-body-generate>h3:last-child:after,\n\t\t&.markdown-body-generate>h4:last-child:after,\n\t\t&.markdown-body-generate>h5:last-child:after,\n\t\t&.markdown-body-generate>h6:last-child:after,\n\t\t&.markdown-body-generate>li:last-child:after,\n\t\t&.markdown-body-generate>ol:last-child li:last-child:after,\n\t\t&.markdown-body-generate>p:last-child:after,\n\t\t&.markdown-body-generate>pre:last-child code:after,\n\t\t&.markdown-body-generate>td:last-child:after,\n\t\t&.markdown-body-generate>ul:last-child li:last-child:after {\n\t\t\tcolor: #65a665;\n\t\t}\n\t}\n\n\t.message-reply {\n\t\t.whitespace-pre-wrap {\n\t\t\twhite-space: pre-wrap;\n\t\t\tcolor: var(--n-text-color);\n\t\t}\n\t}\n\n\t.highlight pre,\n\tpre {\n\t\tbackground-color: #282c34;\n\t}\n}\n\n@media screen and (max-width: 533px) {\n\t.markdown-body .code-block-wrapper {\n\t\tpadding: unset;\n\n\t\tcode {\n\t\t\tpadding: 24px 16px 16px 16px;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/views/chat/components/index.ts",
    "content": "import Message from './Message/index.vue'\n\nexport { Message }\n"
  },
  {
    "path": "src/views/chat/hooks/useChat.ts",
    "content": "import { useChatStore } from '@/store'\n\nexport function useChat() {\n  const chatStore = useChatStore()\n\n  const getChatByUuidAndIndex = (uuid: number, index: number) => {\n    return chatStore.getChatByUuidAndIndex(uuid, index)\n  }\n\n  const addChat = (uuid: number, chat: Chat.Chat) => {\n    chatStore.addChatByUuid(uuid, chat)\n  }\n\n  const updateChat = (uuid: number, index: number, chat: Chat.Chat) => {\n    chatStore.updateChatByUuid(uuid, index, chat)\n  }\n\n  const updateChatSome = (uuid: number, index: number, chat: Partial<Chat.Chat>) => {\n    chatStore.updateChatSomeByUuid(uuid, index, chat)\n  }\n\n  return {\n    addChat,\n    updateChat,\n    updateChatSome,\n    getChatByUuidAndIndex,\n  }\n}\n"
  },
  {
    "path": "src/views/chat/hooks/useScroll.ts",
    "content": "import type { Ref } from 'vue'\nimport { nextTick, ref } from 'vue'\n\ntype ScrollElement = HTMLDivElement | null\n\ninterface ScrollReturn {\n  scrollRef: Ref<ScrollElement>\n  scrollToBottom: () => Promise<void>\n  scrollToTop: () => Promise<void>\n  scrollToBottomIfAtBottom: () => Promise<void>\n}\n\nexport function useScroll(): ScrollReturn {\n  const scrollRef = ref<ScrollElement>(null)\n\n  const scrollToBottom = async () => {\n    await nextTick()\n    if (scrollRef.value)\n      scrollRef.value.scrollTop = scrollRef.value.scrollHeight\n  }\n\n  const scrollToTop = async () => {\n    await nextTick()\n    if (scrollRef.value)\n      scrollRef.value.scrollTop = 0\n  }\n\n  const scrollToBottomIfAtBottom = async () => {\n    await nextTick()\n    if (scrollRef.value) {\n      const threshold = 100 // 阈值，表示滚动条到底部的距离阈值\n      const distanceToBottom = scrollRef.value.scrollHeight - scrollRef.value.scrollTop - scrollRef.value.clientHeight\n      if (distanceToBottom <= threshold)\n        scrollRef.value.scrollTop = scrollRef.value.scrollHeight\n    }\n  }\n\n  return {\n    scrollRef,\n    scrollToBottom,\n    scrollToTop,\n    scrollToBottomIfAtBottom,\n  }\n}\n"
  },
  {
    "path": "src/views/chat/hooks/useUsingContext.ts",
    "content": "import { computed } from 'vue'\nimport { useMessage } from 'naive-ui'\nimport { t } from '@/locales'\nimport { useChatStore } from '@/store'\n\nexport function useUsingContext() {\n  const ms = useMessage()\n  const chatStore = useChatStore()\n  const usingContext = computed<boolean>(() => chatStore.usingContext)\n\n  function toggleUsingContext() {\n    chatStore.setUsingContext(!usingContext.value)\n    if (usingContext.value)\n      ms.success(t('chat.turnOnContext'))\n    else\n      ms.warning(t('chat.turnOffContext'))\n  }\n\n  return {\n    usingContext,\n    toggleUsingContext,\n  }\n}\n"
  },
  {
    "path": "src/views/chat/index.vue",
    "content": "<script setup lang='ts'>\nimport type { Ref } from \"vue\";\nimport { computed, h, onMounted, onUnmounted, ref, watch } from \"vue\";\nimport { useRoute, useRouter } from \"vue-router\";\nimport { storeToRefs } from \"pinia\";\nimport {\n  NAutoComplete,\n  NButton,\n  NInput,\n  useDialog,\n  useMessage,\n  NAvatar,\n} from \"naive-ui\";\nimport html2canvas from \"html2canvas\";\nimport { Message } from \"./components\";\nimport { useScroll } from \"./hooks/useScroll\";\nimport { useChat } from \"./hooks/useChat\";\nimport { useUsingContext } from \"./hooks/useUsingContext\";\nimport HeaderComponent from \"./components/Header/index.vue\";\nimport { SvgIcon } from \"@/components/common\";\nimport { useBasicLayout } from \"@/hooks/useBasicLayout\";\nimport {\n  gptConfigStore,\n  gptServerStore,\n  gptsUlistStore,\n  homeStore,\n  useChatStore,\n  usePromptStore,\n} from \"@/store\";\nimport {\n  chatSetting,\n  fetchChatAPIProcess,\n  gptsType,\n  mlog,\n  myFetch,\n} from \"@/api\";\nimport { t } from \"@/locales\";\nimport drawListVue from \"../mj/drawList.vue\";\nimport aiGPT from \"../mj/aiGpt.vue\";\nimport AiSiderInput from \"../mj/aiSiderInput.vue\";\nimport aiGptInput from \"../mj/aiGptInput.vue\";\nimport AiTextSetting from \"../mj/aiTextSetting.vue\";\nimport { useUserStore } from \"@/store\";\n\nlet controller = new AbortController();\n\nconst openLongReply = import.meta.env.VITE_GLOB_OPEN_LONG_REPLY === \"true\";\n\nconst route = useRoute();\nconst dialog = useDialog();\nconst ms = useMessage();\nconst router = useRouter();\nconst chatStore = useChatStore();\n\nconst { isMobile } = useBasicLayout();\nconst { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } =\n  useChat();\nconst { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll();\nconst { usingContext, toggleUsingContext } = useUsingContext();\n\nconst { uuid } = route.params as { uuid: string };\n\nconst dataSources = computed(() => chatStore.getChatByUuid(+uuid));\nconst conversationList = computed(() =>\n  dataSources.value.filter(\n    (item) => !item.inversion && !!item.conversationOptions\n  )\n);\n\nconst prompt = ref<string>(\"\");\nconst loading = ref<boolean>(false);\nconst inputRef = ref<Ref | null>(null);\n\n// 添加PromptStore\nconst promptStore = usePromptStore();\n\n// 使用storeToRefs，保证store修改后，联想部分能够重新渲染\nconst { promptList: promptTemplate } = storeToRefs<any>(promptStore);\n\n// 未知原因刷新页面，loading 状态不会重置，手动重置\ndataSources.value.forEach((item, index) => {\n  if (item.loading) updateChatSome(+uuid, index, { loading: false });\n});\n\nconst userStore = useUserStore();\n\nconst userInfo = computed(() => userStore.userInfo);\n\nconst backgroundImage = computed(()=>userInfo.value.backgroundImage ?? \"\");\n\nfunction handleSubmit() {\n  //onConversation() //把这个放到aiGpt\n  let message = prompt.value;\n  if (!message || message.trim() === \"\") return;\n  if (loading.value) return;\n  loading.value = true;\n  homeStore.setMyData({\n    act: \"gpt.submit\",\n    actData: { prompt: prompt.value, uuid },\n  });\n  prompt.value = \"\";\n}\n\nasync function onConversation() {\n  let message = prompt.value;\n\n  if (loading.value) return;\n\n  if (!message || message.trim() === \"\") return;\n\n  controller = new AbortController();\n\n  addChat(+uuid, {\n    dateTime: new Date().toLocaleString(),\n    text: message,\n    inversion: true,\n    error: false,\n    conversationOptions: null,\n    requestOptions: { prompt: message, options: null },\n  });\n  scrollToBottom();\n\n  loading.value = true;\n  prompt.value = \"\";\n\n  let options: Chat.ConversationRequest = {};\n  const lastContext =\n    conversationList.value[conversationList.value.length - 1]\n      ?.conversationOptions;\n\n  if (lastContext && usingContext.value) options = { ...lastContext };\n\n  addChat(+uuid, {\n    dateTime: new Date().toLocaleString(),\n    text: \"思考中\",\n    loading: true,\n    inversion: false,\n    error: false,\n    conversationOptions: null,\n    requestOptions: { prompt: message, options: { ...options } },\n  });\n  scrollToBottom();\n\n  try {\n    let lastText = \"\";\n    const fetchChatAPIOnce = async () => {\n      await fetchChatAPIProcess<Chat.ConversationResponse>({\n        prompt: message,\n        options,\n        signal: controller.signal,\n        onDownloadProgress: ({ event }) => {\n          const xhr = event.target;\n          const { responseText } = xhr;\n          // Always process the final line\n          const lastIndex = responseText.lastIndexOf(\n            \"\\n\",\n            responseText.length - 2\n          );\n          let chunk = responseText;\n          if (lastIndex !== -1) chunk = responseText.substring(lastIndex);\n          try {\n            const data = JSON.parse(chunk);\n            updateChat(+uuid, dataSources.value.length - 1, {\n              dateTime: new Date().toLocaleString(),\n              text: lastText + (data.text ?? \"\"),\n              inversion: false,\n              error: false,\n              loading: true,\n              conversationOptions: {\n                conversationId: data.conversationId,\n                parentMessageId: data.id,\n              },\n              requestOptions: { prompt: message, options: { ...options } },\n            });\n\n            if (\n              openLongReply &&\n              data.detail.choices[0].finish_reason === \"length\"\n            ) {\n              options.parentMessageId = data.id;\n              lastText = data.text;\n              message = \"\";\n              return fetchChatAPIOnce();\n            }\n\n            scrollToBottomIfAtBottom();\n          } catch (error) {\n            //\n          }\n        },\n      });\n      updateChatSome(+uuid, dataSources.value.length - 1, { loading: false });\n    };\n\n    await fetchChatAPIOnce();\n  } catch (error: any) {\n    const errorMessage = error?.message ?? t(\"common.wrong\");\n\n    if (error.message === \"canceled\") {\n      updateChatSome(+uuid, dataSources.value.length - 1, {\n        loading: false,\n      });\n      scrollToBottomIfAtBottom();\n      return;\n    }\n\n    const currentChat = getChatByUuidAndIndex(\n      +uuid,\n      dataSources.value.length - 1\n    );\n\n    if (currentChat?.text && currentChat.text !== \"\") {\n      updateChatSome(+uuid, dataSources.value.length - 1, {\n        text: `${currentChat.text}\\n[${errorMessage}]`,\n        error: false,\n        loading: false,\n      });\n      return;\n    }\n\n    updateChat(+uuid, dataSources.value.length - 1, {\n      dateTime: new Date().toLocaleString(),\n      text: errorMessage,\n      inversion: false,\n      error: true,\n      loading: false,\n      conversationOptions: null,\n      requestOptions: { prompt: message, options: { ...options } },\n    });\n    scrollToBottomIfAtBottom();\n  } finally {\n    loading.value = false;\n  }\n}\n\nasync function onRegenerate(index: number) {\n  if (loading.value) return;\n\n  controller = new AbortController();\n\n  const { requestOptions } = dataSources.value[index];\n\n  let message = requestOptions?.prompt ?? \"\";\n\n  let options: Chat.ConversationRequest = {};\n\n  if (requestOptions.options) options = { ...requestOptions.options };\n\n  loading.value = true;\n\n  updateChat(+uuid, index, {\n    dateTime: new Date().toLocaleString(),\n    text: \"\",\n    inversion: false,\n    error: false,\n    loading: true,\n    conversationOptions: null,\n    requestOptions: { prompt: message, options: { ...options } },\n  });\n\n  try {\n    let lastText = \"\";\n    const fetchChatAPIOnce = async () => {\n      await fetchChatAPIProcess<Chat.ConversationResponse>({\n        prompt: message,\n        options,\n        signal: controller.signal,\n        onDownloadProgress: ({ event }) => {\n          const xhr = event.target;\n          const { responseText } = xhr;\n          // Always process the final line\n          const lastIndex = responseText.lastIndexOf(\n            \"\\n\",\n            responseText.length - 2\n          );\n          let chunk = responseText;\n          if (lastIndex !== -1) chunk = responseText.substring(lastIndex);\n          try {\n            const data = JSON.parse(chunk);\n            updateChat(+uuid, index, {\n              dateTime: new Date().toLocaleString(),\n              text: lastText + (data.text ?? \"\"),\n              inversion: false,\n              error: false,\n              loading: true,\n              conversationOptions: {\n                conversationId: data.conversationId,\n                parentMessageId: data.id,\n              },\n              requestOptions: { prompt: message, options: { ...options } },\n            });\n\n            if (\n              openLongReply &&\n              data.detail.choices[0].finish_reason === \"length\"\n            ) {\n              options.parentMessageId = data.id;\n              lastText = data.text;\n              message = \"\";\n              return fetchChatAPIOnce();\n            }\n          } catch (error) {\n            //\n          }\n        },\n      });\n      updateChatSome(+uuid, index, { loading: false });\n    };\n    await fetchChatAPIOnce();\n  } catch (error: any) {\n    if (error.message === \"canceled\") {\n      updateChatSome(+uuid, index, {\n        loading: false,\n      });\n      return;\n    }\n\n    const errorMessage = error?.message ?? t(\"common.wrong\");\n\n    updateChat(+uuid, index, {\n      dateTime: new Date().toLocaleString(),\n      text: errorMessage,\n      inversion: false,\n      error: true,\n      loading: false,\n      conversationOptions: null,\n      requestOptions: { prompt: message, options: { ...options } },\n    });\n  } finally {\n    loading.value = false;\n  }\n}\n\nfunction handleExport() {\n  if (loading.value) return;\n\n  const d = dialog.warning({\n    title: t(\"chat.exportImage\"),\n    content: t(\"chat.exportImageConfirm\"),\n    positiveText: t(\"common.yes\"),\n    negativeText: t(\"common.no\"),\n    onPositiveClick: async () => {\n      try {\n        d.loading = true;\n        const ele = document.getElementById(\"image-wrapper\");\n        const canvas = await html2canvas(ele as HTMLDivElement, {\n          useCORS: true,\n        });\n        const imgUrl = canvas.toDataURL(\"image/png\");\n        const tempLink = document.createElement(\"a\");\n        tempLink.style.display = \"none\";\n        tempLink.href = imgUrl;\n        tempLink.setAttribute(\"download\", \"chat-shot.png\");\n        if (typeof tempLink.download === \"undefined\")\n          tempLink.setAttribute(\"target\", \"_blank\");\n\n        document.body.appendChild(tempLink);\n        tempLink.click();\n        document.body.removeChild(tempLink);\n        window.URL.revokeObjectURL(imgUrl);\n        d.loading = false;\n        ms.success(t(\"chat.exportSuccess\"));\n        Promise.resolve();\n      } catch (error: any) {\n        ms.error(t(\"chat.exportFailed\"));\n      } finally {\n        d.loading = false;\n      }\n    },\n  });\n}\n\nfunction handleDelete(index: number) {\n  if (loading.value) return;\n\n  dialog.warning({\n    title: t(\"chat.deleteMessage\"),\n    content: t(\"chat.deleteMessageConfirm\"),\n    positiveText: t(\"common.yes\"),\n    negativeText: t(\"common.no\"),\n    onPositiveClick: () => {\n      chatStore.deleteChatByUuid(+uuid, index);\n    },\n  });\n}\n\nfunction handleEdit(index: number) {\n  if (loading.value) return;\n\n  const editedMessage = ref(dataSources.value[index].text.slice());\n\n  const inputNode = () => {\n    return h(NInput, {\n      value: editedMessage.value,\n      type: \"textarea\",\n      autosize: { minRows: 1, maxRows: 8 },\n      showCount: true,\n      \"onUpdate:value\": (v: string) => {\n        editedMessage.value = v;\n      },\n    });\n  };\n\n  dialog.warning({\n    title: t(\"common.edit\"),\n    content: inputNode,\n    positiveText: t(\"common.yes\"),\n    negativeText: t(\"common.no\"),\n    onPositiveClick: () => {\n      updateChatSome(+uuid, index, { text: editedMessage.value });\n    },\n  });\n}\n\nfunction handleClear() {\n  if (loading.value) return;\n\n  dialog.warning({\n    title: t(\"chat.clearChat\"),\n    content: t(\"chat.clearChatConfirm\"),\n    positiveText: t(\"common.yes\"),\n    negativeText: t(\"common.no\"),\n    onPositiveClick: () => {\n      chatStore.clearChatByUuid(+uuid);\n    },\n  });\n}\n\nfunction handleEnter(event: KeyboardEvent) {\n  if (!isMobile.value) {\n    if (event.key === \"Enter\" && !event.shiftKey) {\n      event.preventDefault();\n      handleSubmit();\n    }\n  } else {\n    if (event.key === \"Enter\" && event.ctrlKey) {\n      event.preventDefault();\n      handleSubmit();\n    }\n  }\n}\n\nfunction handleStop() {\n  if (loading.value) {\n    homeStore.setMyData({ act: \"abort\" });\n    controller.abort();\n    loading.value = false;\n  }\n}\n\n// 可优化部分\n// 搜索选项计算，这里使用value作为索引项，所以当出现重复value时渲染异常(多项同时出现选中效果)\n// 理想状态下其实应该是key作为索引项,但官方的renderOption会出现问题，所以就需要value反renderLabel实现\nconst searchOptions = computed(() => {\n  if (prompt.value.startsWith(\"/\")) {\n    const abc = promptTemplate.value\n      .filter((item: { key: string }) =>\n        item.key.toLowerCase().includes(prompt.value.substring(1).toLowerCase())\n      )\n      .map((obj: { value: any }) => {\n        return {\n          label: obj.value,\n          value: obj.value,\n        };\n      });\n    mlog(\"搜索选项\", abc);\n    return abc;\n  } else if (prompt.value == \"@\") {\n    const abc = gptsUlistStore.myData.slice(0, 10).map((v: gptsType) => {\n      return {\n        label: v.info,\n        gpts: v,\n        value: v.gid,\n      };\n    });\n    return abc;\n  } else {\n    return [];\n  }\n});\n\nconst goUseGpts = async (item: gptsType) => {\n  const saveObj = { model: `${item.gid}`, gpts: item };\n  gptConfigStore.setMyData(saveObj);\n  if (chatStore.active) {\n    //保存到对话框\n    const chatSet = new chatSetting(chatStore.active);\n    //if( chatSet.findIndex()>-1 ) chatSet.save( saveObj )\n    chatSet.save(saveObj);\n  }\n  ms.success(t(\"mjchat.success2\"));\n  const gptUrl = `https://gpts.ddaiai.com/open/gptsapi/use`;\n  myFetch(gptUrl, item);\n\n  mlog(\"go local \", homeStore.myData.local);\n  if (homeStore.myData.local !== \"Chat\")\n    router.replace({ name: \"Chat\", params: { uuid: chatStore.active } });\n\n  gptsUlistStore.setMyData(item);\n};\n\n// value反渲染key\nconst renderOption = (option: { label: string; gpts?: gptsType }) => {\n  if (prompt.value == \"@\") {\n    //return [ h( NAvatar,{src:'https://cos.aitutu.cc/gpts/gpt4all.jpg',size:\"small\",round:true}),option.label ]\n    return [\n      h(\n        \"div\",\n        {\n          class: \"flex justify-start items-center\",\n          onclick: () => {\n            if (option.gpts) goUseGpts(option.gpts);\n            prompt.value = \"\";\n            setTimeout(() => (prompt.value = \"\"), 80);\n          },\n        },\n        [\n          h(NAvatar, {\n            src: option.gpts?.logo,\n            \"fallback-src\": \"https://cos.aitutu.cc/gpts/3.5net.png\",\n            size: \"small\",\n            round: true,\n            class: \"w-8 h-8\",\n          }),\n          h(\"span\", { class: \"pl-1\" }, option.gpts?.name),\n          h(\n            \"span\",\n            { class: \"line-clamp-1 flex-1 pl-1 opacity-50\" },\n            option.label\n          ),\n        ]\n      ),\n    ];\n  }\n  for (const i of promptTemplate.value) {\n    if (i.value === option.label) return [i.key];\n  }\n  return [];\n};\n\nconst placeholder = computed(() => {\n  if (isMobile.value) return t(\"chat.placeholderMobile\");\n  return t(\"chat.placeholder\");\n});\n\nconst buttonDisabled = computed(() => {\n  return loading.value || !prompt.value || prompt.value.trim() === \"\";\n});\n\nconst footerClass = computed(() => {\n  let classes = [\"p-4\"];\n  if (isMobile.value)\n    classes = [\"sticky\", \"left-0\", \"bottom-0\", \"right-0\", \"p-2\", \"pr-3\"]; //, 'overflow-hidden'\n  return classes;\n});\n\nonMounted(() => {\n  scrollToBottom();\n  if (inputRef.value && !isMobile.value) inputRef.value?.focus();\n});\n\nonUnmounted(() => {\n  if (loading.value) controller.abort();\n  homeStore.setMyData({ isLoader: false });\n});\n\nconst local = computed(() => homeStore.myData.local);\nwatch(\n  () => homeStore.myData.act,\n  (n) => {\n    if (n == \"draw\") scrollToBottom();\n    if (n == \"scrollToBottom\") scrollToBottom();\n    if (n == \"scrollToBottomIfAtBottom\") scrollToBottomIfAtBottom();\n    if (n == \"gpt.submit\" || n == \"gpt.resubmit\") {\n      loading.value = true;\n      if (chatStore.active) {\n        const chatSet = new chatSetting(chatStore.active);\n        if (chatSet.findIndex() == -1) {\n          //如果是空保存到对话框\n          chatSet.save(chatSet.getGptConfig());\n          setTimeout(() => homeStore.setMyData({ act: \"saveChat\" }), 600);\n        }\n      }\n    }\n    if (n == \"stopLoading\") {\n      loading.value = false;\n    }\n  }\n);\nconst st = ref({ inputme: true });\n\nwatch(\n  () => loading.value,\n  (n) => homeStore.setMyData({ isLoader: n })\n);\n\nconst ychat = computed(() => {\n  let text = prompt.value;\n  if (loading.value) text = \"\";\n  else {\n    scrollToBottomIfAtBottom();\n  }\n  return { text, dateTime: t(\"chat.preview\") } as Chat.Chat;\n});\n</script>\n\n<template>\n  <div v-if=\"backgroundImage\" \n    class=\" fixed z-[200] pointer-events-none top-0 left-0 w-full h-full bg-cover bg-center bg-no-repeat\"\n    :style=\"{\n      'background-image': 'url(' + backgroundImage + ')',\n      opacity: 0.19,\n    }\"\n  ></div>\n  <div class=\"flex flex-col w-full h-full\">\n    <!-- v-if=\"isMobile\" -->\n    <HeaderComponent\n      :using-context=\"usingContext\"\n      @export=\"handleExport\"\n      @handle-clear=\"handleClear\"\n    />\n    <main class=\"flex-1 overflow-hidden\">\n      <div\n        id=\"scrollRef\"\n        ref=\"scrollRef\"\n        class=\"h-full overflow-hidden overflow-y-auto\"\n      >\n        <div\n          id=\"image-wrapper\"\n          class=\"w-full max-w-screen-xl m-auto dark:bg-[#101014]\"\n          :class=\"[isMobile ? 'p-2' : 'p-4']\"\n        >\n          <template v-if=\"!dataSources.length\">\n            <div\n              class=\"text-center pt-10\"\n              v-if=\"\n                homeStore.myData.isClient &&\n                (!gptServerStore.myData.OPENAI_API_BASE_URL ||\n                  !gptServerStore.myData.OPENAI_API_KEY)\n              \"\n            >\n              <AiTextSetting />\n            </div>\n            <div\n              v-else-if=\"homeStore.myData.session.notify\"\n              v-html=\"homeStore.myData.session.notify\"\n              class=\"text-neutral-300 mt-4\"\n            ></div>\n            <div\n              class=\"flex items-center justify-center mt-4 text-center text-neutral-300\"\n              v-else\n            >\n              <SvgIcon icon=\"ri:bubble-chart-fill\" class=\"mr-2 text-3xl\" />\n              <span>Aha~</span>\n            </div>\n          </template>\n          <template v-else>\n            <div>\n              <Message\n                v-for=\"(item, index) of dataSources\"\n                :key=\"index\"\n                :date-time=\"item.dateTime\"\n                :text=\"item.text\"\n                :inversion=\"item.inversion\"\n                :error=\"item.error\"\n                :loading=\"item.loading\"\n                @regenerate=\"onRegenerate(index)\"\n                @delete=\"handleDelete(index)\"\n                @edit=\"handleEdit(index)\"\n                :chat=\"item\"\n                :index=\"index\"\n              />\n              <Message\n                v-if=\"ychat.text\"\n                :key=\"dataSources.length\"\n                :inversion=\"true\"\n                :date-time=\"$t('mj.typing')\"\n                :chat=\"ychat\"\n                :text=\"ychat.text\"\n                :index=\"dataSources.length\"\n              />\n              <div class=\"sticky bottom-0 left-0 flex justify-center\">\n                <NButton v-if=\"loading\" type=\"warning\" @click=\"handleStop\">\n                  <template #icon>\n                    <SvgIcon icon=\"ri:stop-circle-line\" />\n                  </template>\n                  {{ t(\"common.stopResponding\") }}\n                </NButton>\n              </div>\n            </div>\n          </template>\n        </div>\n      </div>\n    </main>\n    <footer :class=\"footerClass\" v-if=\"local !== 'draw'\">\n      <div class=\"w-full max-w-screen-xl m-auto\">\n        <aiGptInput\n          v-if=\"\n            ['gpt-4-vision-preview', 'gpt-3.5-turbo-16k'].indexOf(\n              gptConfigStore.myData.model\n            ) > -1 || st.inputme\n          \"\n          v-model:modelValue=\"prompt\"\n          :disabled=\"buttonDisabled\"\n          :searchOptions=\"searchOptions\"\n          :renderOption=\"renderOption\"\n        />\n        <div class=\"flex items-center justify-between space-x-2\" v-else>\n          <!-- \n          <HoverButton v-if=\"!isMobile\" @click=\"handleClear\">\n            <span class=\"text-xl text-[#4f555e] dark:text-white\">\n              <SvgIcon icon=\"ri:delete-bin-line\" />\n            </span>\n          </HoverButton>\n          <HoverButton v-if=\"!isMobile\" @click=\"handleExport\">\n            <span class=\"text-xl text-[#4f555e] dark:text-white\">\n              <SvgIcon icon=\"ri:download-2-line\" />\n            </span>\n          </HoverButton>\n          <HoverButton @click=\"toggleUsingContext\">\n            <span class=\"text-xl\" :class=\"{ 'text-[#4b9e5f]': usingContext, 'text-[#a8071a]': !usingContext }\">\n              <SvgIcon icon=\"ri:chat-history-line\" />\n            </span>\n          </HoverButton>\n          -->\n\n          <NAutoComplete\n            v-model:value=\"prompt\"\n            :options=\"searchOptions\"\n            :render-label=\"renderOption\"\n          >\n            <template #default=\"{ handleInput, handleBlur, handleFocus }\">\n              <NInput\n                ref=\"inputRef\"\n                v-model:value=\"prompt\"\n                type=\"textarea\"\n                :placeholder=\"placeholder\"\n                :autosize=\"{ minRows: 1, maxRows: isMobile ? 4 : 8 }\"\n                @input=\"handleInput\"\n                @focus=\"handleFocus\"\n                @blur=\"handleBlur\"\n                @keypress=\"handleEnter\"\n              />\n            </template>\n          </NAutoComplete>\n          <NButton\n            type=\"primary\"\n            :disabled=\"buttonDisabled\"\n            @click=\"handleSubmit\"\n          >\n            <template #icon>\n              <span class=\"dark:text-black\">\n                <SvgIcon icon=\"ri:send-plane-fill\" />\n              </span>\n            </template>\n          </NButton>\n        </div>\n      </div>\n    </footer>\n  </div>\n\n  <drawListVue />\n  <aiGPT @finished=\"loading = false\" />\n  <AiSiderInput v-if=\"isMobile\" :button-disabled=\"false\" />\n</template>\n"
  },
  {
    "path": "src/views/chat/layout/Layout.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport { NLayout, NLayoutContent,useMessage } from 'naive-ui'\nimport { useRouter ,useRoute } from 'vue-router'\nimport Sider from './sider/index.vue'\nimport Permission from './Permission.vue'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { gptConfigStore, homeStore, useAppStore, useAuthStore, useChatStore } from '@/store'\nimport { aiSider,aiFooter} from '@/views/mj' \nimport aiMobileMenu from '@/views/mj/aiMobileMenu.vue'; \nimport { t } from '@/locales'\nimport { mlog, openaiSetting } from '@/api'\nimport { isObject } from '@/utils/is'\n\nconst router = useRouter()\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\nconst authStore = useAuthStore()\n\nconst rt = useRoute();\nconst ms = useMessage();\nopenaiSetting( rt.query, ms )\nif(rt.name =='GPTs'){ \n  let model= `gpt-4-gizmo-${rt.params.gid.toString()}`  ;\n  gptConfigStore.setMyData({model:model});\n  ms.success(`GPTs ${t('mj.modleSuccess')}`);\n}else if(rt.name=='Setting'){ \n  openaiSetting( rt.query,ms );\n  if(isObject( rt.query ))  ms.success( t('mj.setingSuccess') ); \n}else if(rt.name=='Model'){ \n  let model= `${rt.params.gid.toString()}`  ;\n  gptConfigStore.setMyData({model:model});\n  ms.success( t('mj.modleSuccess') );\n}\n\n \n\nrouter.replace({ name: 'Chat', params: { uuid: chatStore.active } })\nhomeStore.setMyData({local:'Chat'});\nconst { isMobile } = useBasicLayout()\n\n\nconst collapsed = computed(() => appStore.siderCollapsed)\n\nconst needPermission = computed(() => {\n//mlog( 'Layout token',  authStore.token   )\n   \n return  !!authStore.session?.auth && !authStore.token\n})\n\nconst getMobileClass = computed(() => {\n  if (isMobile.value)\n    return ['rounded-none', 'shadow-none']\n  return [ 'shadow-md', 'dark:border-neutral-800'] //'border', 'rounded-md',\n})\n\nconst getContainerClass = computed(() => {\n  return [\n    'h-full',\n    { 'abc': !isMobile.value && !collapsed.value },\n  ]\n}) \n</script>\n\n<template>\n  <div class=\"  dark:bg-[#24272e] transition-all p-0\"  :class=\"[isMobile ? 'h55' : 'h-full' ]\">\n    <div class=\"h-full overflow-hidden\" :class=\"getMobileClass\">\n      <NLayout class=\"z-40 transition\" :class=\"getContainerClass\" has-sider>\n        <aiSider v-if=\"!isMobile\"/>\n        <Sider />\n        <NLayoutContent class=\"h-full\">\n          <RouterView v-slot=\"{ Component, route }\">\n            <component :is=\"Component\" :key=\"route.fullPath\" />\n          </RouterView>\n        </NLayoutContent>\n      </NLayout>\n    </div>\n    <Permission :visible=\"needPermission\" />\n  </div>\n   <aiMobileMenu v-if=\"isMobile\"   /> \n\n  <aiFooter/>\n</template>\n\n<style  >\n.h55{\n  height: calc(100% - 55px);\n}\n</style>\n"
  },
  {
    "path": "src/views/chat/layout/Permission.vue",
    "content": "<script setup lang='ts'>\nimport { computed, ref } from 'vue'\nimport { NButton, NInput, NModal, useMessage } from 'naive-ui'\nimport { fetchVerify } from '@/api'\nimport { useAuthStore } from '@/store'\nimport Icon403 from '@/icons/403.vue'\n\ninterface Props {\n  visible: boolean\n}\n\ndefineProps<Props>()\n\nconst authStore = useAuthStore()\n\nconst ms = useMessage()\n\nconst loading = ref(false)\nconst token = ref('')\n\nconst disabled = computed(() => !token.value.trim() || loading.value)\n\nasync function handleVerify() {\n  const secretKey = token.value.trim()\n\n  if (!secretKey)\n    return\n\n  try {\n    loading.value = true\n    await fetchVerify(secretKey)\n    authStore.setToken(secretKey)\n    ms.success('success')\n    window.location.reload()\n  }\n  catch (error: any) {\n    ms.error(error.message ?? 'error')\n    authStore.removeToken()\n    token.value = ''\n  }\n  finally {\n    loading.value = false\n  }\n}\n\nfunction handlePress(event: KeyboardEvent) {\n  if (event.key === 'Enter' && !event.shiftKey) {\n    event.preventDefault()\n    handleVerify()\n  }\n}\n</script>\n\n<template>\n  <NModal :show=\"visible\" style=\"width: 90%; max-width: 640px\">\n    <div class=\"p-10 bg-white rounded dark:bg-slate-800\">\n      <div class=\"space-y-4\">\n        <header class=\"space-y-2\">\n          <h2 class=\"text-2xl font-bold text-center text-slate-800 dark:text-neutral-200\">\n            403\n          </h2>\n          <p class=\"text-base text-center text-slate-500 dark:text-slate-500\">\n            {{ $t('common.unauthorizedTips') }}\n          </p>\n          <Icon403 class=\"w-[200px] m-auto\" />\n        </header>\n        <NInput v-model:value=\"token\" type=\"password\" placeholder=\"\" @keypress=\"handlePress\" />\n        <NButton\n          block\n          type=\"primary\"\n          :disabled=\"disabled\"\n          :loading=\"loading\"\n          @click=\"handleVerify\"\n        >\n          {{ $t('common.verify') }}\n        </NButton>\n      </div>\n    </div>\n  </NModal>\n</template>\n"
  },
  {
    "path": "src/views/chat/layout/index.ts",
    "content": "import ChatLayout from './Layout.vue'\n\nexport { ChatLayout }\n"
  },
  {
    "path": "src/views/chat/layout/sider/Footer.vue",
    "content": "<script setup lang='ts'>\nimport { defineAsyncComponent, ref } from 'vue'\nimport { HoverButton, SvgIcon, UserAvatar } from '@/components/common'\n\nconst Setting = defineAsyncComponent(() => import('@/components/common/Setting/index.vue'))\n\nconst show = ref(false)\n</script>\n\n<template>\n  <footer class=\"flex items-center justify-between min-w-0 p-4 overflow-hidden border-t dark:border-neutral-800\">\n    <div class=\"flex-1 flex-shrink-0 overflow-hidden\">\n      <UserAvatar />\n    </div>\n\n    <HoverButton @click=\"show = true\">\n      <span class=\"text-xl text-[#4f555e] dark:text-white\">\n        <SvgIcon icon=\"ri:settings-4-line\" />\n      </span>\n    </HoverButton>\n\n    <Setting v-if=\"show\" v-model:visible=\"show\" />\n  </footer>\n</template>\n"
  },
  {
    "path": "src/views/chat/layout/sider/List.vue",
    "content": "<script setup lang='ts'>\nimport { computed ,watch,ref} from 'vue'\nimport { NInput, NPopconfirm, NScrollbar } from 'naive-ui'\nimport { SvgIcon } from '@/components/common'\nimport { gptConfigStore, gptConfigType, homeStore, useAppStore, useChatStore } from '@/store'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { debounce } from '@/utils/functions/debounce'\nimport { chatSetting, mlog } from '@/api'\nimport AiListText from '@/views/mj/aiListText.vue'\nimport { sleep } from '@/api/suno'\n\nconst { isMobile } = useBasicLayout()\n\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\n\nconst dataSources = computed(() => chatStore.history)\n\nasync function handleSelect({ uuid }: Chat.History) {\n  if (isActive(uuid))\n    return\n\n  if (chatStore.active)\n    chatStore.updateHistory(chatStore.active, { isEdit: false })\n  await chatStore.setActive(uuid)\n\n  if (isMobile.value)\n    appStore.setSiderCollapsed(true)\n}\n\nfunction handleEdit({ uuid }: Chat.History, isEdit: boolean, event?: MouseEvent) {\n  event?.stopPropagation()\n  chatStore.updateHistory(uuid, { isEdit })\n}\n\nfunction handleDelete(index: number, event?: MouseEvent | TouchEvent) {\n  event?.stopPropagation()\n  chatStore.deleteHistory(index)\n  if (isMobile.value)\n    appStore.setSiderCollapsed(true)\n}\n\nconst handleDeleteDebounce = debounce(handleDelete, 600)\n\nfunction handleEnter({ uuid }: Chat.History, isEdit: boolean, event: KeyboardEvent) {\n  event?.stopPropagation()\n  if (event.key === 'Enter')\n    chatStore.updateHistory(uuid, { isEdit })\n}\n\nfunction isActive(uuid: number) {\n  return chatStore.active === uuid\n}\n\nconst chatSet= new chatSetting( chatStore.active??1002);\nconst myuid= ref<gptConfigType[]>( []) //computed( ()=>chatSet.getObjs() ) ;\n\n//找假死的原因了 修复卡死\nconst toMyuid=  debounce(  ()=>{\n    mlog('toMyuid7' );\n   // await sleep(500);\n    myuid.value= chatSet.getObjs(); //用了 这个就会卡死？\n   },600);\n\ntoMyuid();\nconst isInObjs= (uuid:number):undefined|gptConfigType =>{\n  if(!myuid.value.length) return ;\n  const index = myuid.value.findIndex((item:gptConfigType)=>{\n    return item.uuid==uuid\n  })\n  if(index==-1) return ;\n  mlog('index 这个地方有bug',uuid,index, myuid.value[index]  );\n  return myuid.value[index] ;\n}\nwatch(()=>homeStore.myData.act,(n:string)=>n=='saveChat' && toMyuid() , {deep:true})\nwatch(()=>gptConfigStore.myData , toMyuid , {deep:true})\n\n</script>\n\n<template>\n  <NScrollbar class=\"px-4\">\n    <div class=\"flex flex-col gap-2 text-sm\">\n      <template v-if=\"!dataSources.length\">\n        <div class=\"flex flex-col items-center mt-4 text-center text-neutral-300\">\n          <SvgIcon icon=\"ri:inbox-line\" class=\"mb-2 text-3xl\" />\n          <span>{{ $t('common.noData') }}</span>\n        </div>\n      </template>\n      <template v-else>\n        <div v-for=\"(item, index) of dataSources\" :key=\"index\">\n          <a\n            class=\"relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]\"\n            :class=\"isActive(item.uuid) && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]', 'dark:bg-[#24272e]', 'dark:border-[#4b9e5f]', 'pr-14']\"\n            @click=\"handleSelect(item)\"\n          >\n             \n             <AiListText   :myObj=\"isInObjs(item.uuid)\" :myItem=\"item\">\n               <NInput\n                v-if=\"item.isEdit\"\n                v-model:value=\"item.title\" size=\"tiny\"\n                @keypress=\"handleEnter(item, false, $event)\"\n              />\n             </AiListText>\n            <div v-if=\"isActive(item.uuid)\" class=\"absolute z-10 flex visible right-1\">\n              <template v-if=\"item.isEdit\">\n                <button class=\"p-1\" @click=\"handleEdit(item, false, $event)\">\n                  <SvgIcon icon=\"ri:save-line\" />\n                </button>\n              </template>\n              <template v-else>\n                <button class=\"p-1\">\n                  <SvgIcon icon=\"ri:edit-line\" @click=\"handleEdit(item, true, $event)\" />\n                </button>\n                <NPopconfirm placement=\"bottom\" @positive-click=\"handleDeleteDebounce(index, $event)\">\n                  <template #trigger>\n                    <button class=\"p-1\">\n                      <SvgIcon icon=\"ri:delete-bin-line\" />\n                    </button>\n                  </template>\n                  {{ $t('chat.deleteHistoryConfirm') }}\n                </NPopconfirm>\n              </template>\n            </div>\n          </a>\n        </div>\n      </template>\n    </div>\n  </NScrollbar>\n</template>\n"
  },
  {
    "path": "src/views/chat/layout/sider/index.vue",
    "content": "<script setup lang='ts'>\nimport type { CSSProperties } from 'vue'\nimport { computed, ref, watch } from 'vue'\nimport { NButton, NLayoutSider, useDialog } from 'naive-ui'\nimport List from './List.vue'\nimport Footer from './Footer.vue'\nimport { useAppStore, useChatStore } from '@/store'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { PromptStore, SvgIcon } from '@/components/common'\nimport { t } from '@/locales'\n\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\n\nconst dialog = useDialog()\n\nconst { isMobile } = useBasicLayout()\nconst show = ref(false)\n\nconst collapsed = computed(() => appStore.siderCollapsed)\n\nfunction handleAdd() {\n  chatStore.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false })\n  if (isMobile.value)\n    appStore.setSiderCollapsed(true)\n}\n\nfunction handleUpdateCollapsed() {\n  appStore.setSiderCollapsed(!collapsed.value)\n}\n\nfunction handleClearAll() {\n  dialog.warning({\n    title: t('chat.deleteMessage'),\n    content: t('chat.clearHistoryConfirm'),\n    positiveText: t('common.yes'),\n    negativeText: t('common.no'),\n    onPositiveClick: () => {\n      chatStore.clearHistory()\n      if (isMobile.value)\n        appStore.setSiderCollapsed(true)\n    },\n  })\n}\n\nconst getMobileClass = computed<CSSProperties>(() => {\n  if (isMobile.value) {\n    return {\n      position: 'fixed',\n      zIndex: 50,\n      height: '100%',\n    }\n  }\n  return {}\n})\n\nconst mobileSafeArea = computed(() => {\n  if (isMobile.value) {\n    return {\n      paddingBottom: 'env(safe-area-inset-bottom)',\n    }\n  }\n  return {}\n})\n\nwatch(\n  isMobile,\n  (val) => {\n    appStore.setSiderCollapsed(val)\n  },\n  {\n    immediate: true,\n    flush: 'post',\n  },\n)\n</script>\n\n<template>\n  <NLayoutSider\n    :collapsed=\"collapsed\"\n    :collapsed-width=\"0\"\n    :width=\"260\"\n    :show-trigger=\"isMobile ? false : 'arrow-circle'\"\n    collapse-mode=\"transform\"\n    \n    bordered\n    :style=\"getMobileClass\"\n    @update-collapsed=\"handleUpdateCollapsed\"\n  >\n    <div class=\"flex flex-col h-full\" :style=\"mobileSafeArea\">\n      <main class=\"flex flex-col flex-1 min-h-0\">\n        <div class=\"p-4\">\n          <NButton dashed block @click=\"handleAdd\">\n            {{ $t('chat.newChatButton') }}\n          </NButton>\n        </div>\n        <div class=\"flex-1 min-h-0 pb-4 overflow-hidden\">\n          <List />\n        </div>\n        <div class=\"flex items-center p-4 space-x-4\">\n          <div class=\"flex-1\">\n            <NButton block @click=\"show = true\">\n              {{ $t('store.siderButton') }}\n            </NButton>\n          </div>\n          <NButton @click=\"handleClearAll\">\n            <SvgIcon icon=\"ri:close-circle-line\" />\n          </NButton>\n        </div>\n      </main>\n      <Footer />\n    </div>\n  </NLayoutSider>\n  <template v-if=\"isMobile\">\n    <div v-show=\"!collapsed\" class=\"fixed inset-0 z-40 w-full h-full bg-black/40\" @click=\"handleUpdateCollapsed\" />\n  </template>\n  <PromptStore v-model:visible=\"show\" />\n</template>\n"
  },
  {
    "path": "src/views/exception/404/index.vue",
    "content": "<script lang=\"ts\" setup>\nimport { NButton } from 'naive-ui'\nimport { useRouter } from 'vue-router'\n\nconst router = useRouter()\n\nfunction goHome() {\n  router.push('/')\n}\n</script>\n\n<template>\n  <div class=\"flex h-full\">\n    <div class=\"px-4 m-auto space-y-4 text-center max-[400px]\">\n      <h1 class=\"text-4xl text-slate-800 dark:text-neutral-200\">\n        Sorry, page not found!\n      </h1>\n      <p class=\"text-base text-slate-500 dark:text-neutral-400\">\n        Sorry, we couldn’t find the page you’re looking for. Perhaps you’ve mistyped the URL? Be sure to check your spelling.\n      </p>\n      <div class=\"flex items-center justify-center text-center\">\n        <div class=\"w-[300px]\">\n          <img src=\"../../../icons/404.svg\" alt=\"404\">\n        </div>\n      </div>\n      <NButton type=\"primary\" @click=\"goHome\">\n        Go to Home\n      </NButton>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/views/exception/500/index.vue",
    "content": "<script lang=\"ts\" setup>\nimport { NButton } from 'naive-ui'\nimport { useRouter } from 'vue-router'\nimport Icon500 from '@/icons/500.vue'\n\nconst router = useRouter()\n\nfunction goHome() {\n  router.push('/')\n}\n</script>\n\n<template>\n  <div class=\"flex h-full dark:bg-neutral-800\">\n    <div class=\"px-4 m-auto space-y-4 text-center max-[400px]\">\n      <header class=\"space-y-2\">\n        <h2 class=\"text-2xl font-bold text-center text-slate-800 dark:text-neutral-200\">\n          500\n        </h2>\n        <p class=\"text-base text-center text-slate-500 dark:text-slate-500\">\n          Server error\n        </p>\n        <div class=\"flex items-center justify-center text-center\">\n          <Icon500 class=\"w-[300px]\" />\n        </div>\n      </header>\n      <NButton type=\"primary\" @click=\"goHome\">\n        Go to Home\n      </NButton>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/views/kling/kgImage.vue",
    "content": "<script setup lang=\"ts\">\nimport { localGet, mlog, url2base64 } from '@/api';\nimport { ref } from 'vue';\nimport { LazyImg } from 'vue-waterfall-plugin-next'\nconst pp= defineProps<{item:any}>();\nconst emit= defineEmits(['kgSuccess','kgClick']);\n\nconst st= ref({uri_base64:'',isLoad:false})\n\n\nconst load = async ()=>{\n     mlog('kg-Image', pp.item  );\n\n      \n     if( pp.item.task && pp.item.task.request_id && pp.item.src){\n       \n     \n        let key= 'kg:'+pp.item.task.request_id;\n         mlog('key>> ',  key );  \n        try {\n            let base64 = await localGet(key );  \n            if(!base64) {\n                const ubase64=  await url2base64(`https://wsrv.nl/?url=${encodeURIComponent(pp.item.src)}`  ,key );\n                base64= ubase64.base64;\n                mlog('图片已保存>>', ubase64.key )\n            }\n            if(base64) st.value.uri_base64= base64 as string;\n            \n        } catch (error) {\n            mlog('图片保存失败',error);\n        }\n     }\n\n      mlog('图片已保存>>',   st.value.uri_base64  )\n\n     st.value.isLoad= true\n    \n    \n\n  \n}\nload();\n</script>\n\n<template>\n<LazyImg :url=\"st.uri_base64?st.uri_base64:pp.item.src\" v-if=\"st.isLoad\"  @success=\"emit('kgSuccess')\"  @click=\"emit('kgClick', {base64:st.uri_base64, src:pp.item.src} )\"  />\n</template>"
  },
  {
    "path": "src/views/kling/kgInput.vue",
    "content": "<script setup lang=\"ts\">\nimport {NTabs, NTabPane} from 'naive-ui';\nimport kgInputVideo from './kgInputVideo.vue';\nimport kgInputImage from './kgInputImage.vue';\n</script>\n<template>\n<div class=\"px-2\">\n    <n-tabs type=\"segment\" animated size=\"small\" default-value=\"video\">\n        <n-tab-pane name=\"video\" :tab=\"$t('video.menu')\">\n            <kg-input-video/>\n        </n-tab-pane>\n        <n-tab-pane name=\"image\" :tab=\"$t('mjchat.draw')\">\n            <kg-input-image/>\n        </n-tab-pane>\n    </n-tabs>\n</div>\n</template>"
  },
  {
    "path": "src/views/kling/kgInputImage.vue",
    "content": "<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue';\nimport {useMessage, NButton,NInput,NTag} from 'naive-ui';\nimport { clearImageBase64, mlog, upImg } from '@/api';\nimport { homeStore } from '@/store';\nimport { klingFeed, klingFetch } from '@/api/kling';\n\nconst f= ref({prompt:'',negative_prompt:'',image:'',image_fidelity:0.5,n:1,aspect_ratio:'1:1'});\nconst st= ref({bili:0,isLoading:false});\n\nconst fsRef= ref() ; \nconst ms = useMessage();\n\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1',value:'1:1'}\n,{s:'width: 100%; height: 75%;',label:'4:3',value:'4:3'}\n,{s:'width: 75%; height: 100%;',label:'3:4',value:'3:4'}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:'16:9'}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:'9:16'}\n ];\n\n\n function selectFile(input:any){\n   // fsFile.value= input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        f.value.image= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n    \n}\n\nconst clearInput = ()=>{\n    f.value.prompt='';\n    f.value.image= '';\n    fsRef.value=''\n}\n\nconst createImg = async ()=>{\n    st.value.isLoading= true\n    f.value.aspect_ratio= vf[st.value.bili].value\n    let abc= {...f.value};\n    if(abc.image) abc.image= clearImageBase64( abc.image )\n    try {\n        const d:any= await klingFetch('/v1/images/generations ' , abc  )\n        mlog('img', d );\n        klingFeed( d.data.task_id ,'image',  f.value.prompt )\n        //f.value.image= ''\n    } catch (error) {\n    }  \n    st.value.isLoading= false\n}\n\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n});\n\nconst test=()=>{\nklingFetch('https://api.openai-hk.com/v1/models').then(d=>mlog('models',d ) )\n}\n//Cl6NIGbYLVQAAAAAALp\n//klingFeed('Cl6NIGbYLVQAAAAAALp-jw','image',\"测试啊\").then(d=>mlog('d>>',d ) ) \n//klingFeed('Cl6NIGbYLVQAAAAAALXTmA','image',\"大雪纷飞\").then(d=>mlog('d>>',d ) ) \n</script>\n<template>\n<div class=\"overflow-y-auto bg-[#fafbfc]   dark:bg-[#18181c] h-full \">\n    <section class=\"mb-4\">\n         <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':index==st.bili}\"  @click=\"st.bili=index\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n\n        </div>\n    </section> \n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.nohead') }}</div>\n          <NInput v-model=\"f.negative_prompt\" size=\"small\"  class=\"!w-[70%]\"  clearable :placeholder=\"$t('mj.negative_prompt')\" />\n    </section>\n     <section class=\"mb-4 flex justify-between items-center\" >\n         \n          <n-input v-model:value=\"f.prompt\" \n                :placeholder=\"$t('mj.ideopls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </section>\n    \n    <section class=\"mb-4 flex justify-between items-end\" >\n        <div class=\"relative\"> \n            <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n            <div   class=\"h-[80px] w-[80px]   overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                <img :src=\"f.image\" v-if=\"f.image\" />\n                <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                \n            </div>\n        </div>\n        <div class=\"text-right\">\n            <div  class=\" cursor-pointer pb-2\" @click=\"clearInput\"  v-if=\"f.image|| f.prompt \"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n\n            <NButton :loading=\"st.isLoading\" type=\"primary\" @click=\"createImg()\" :disabled=\"!f.prompt\"  >{{ $t('mjchat.imgcreate') }}</NButton>\n        </div>\n    </section>\n\n    <!-- <NButton @click=\"test()\">test</NButton> -->\n</div>\n</template>"
  },
  {
    "path": "src/views/kling/kgInputVideo.vue",
    "content": "<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue';\nimport {useMessage, NButton,NInput,NTag,NSelect} from 'naive-ui';\nimport { clearImageBase64, mlog, upImg } from '@/api';\nimport { homeStore } from '@/store';\nimport { klingFeed, klingFetch } from '@/api/kling';\nimport { t } from '@/locales';\n\nconst f= ref({prompt:'',negative_prompt:'',image:'',image_tail:'',aspect_ratio:'1:1',mode:'std', duration:'5',model:'kling-v1-6'});\nconst st= ref({bili:0,isLoading:false,camera_type:''});\n\nconst fsRef= ref() ; \nconst fsRef2= ref() ; \nconst ms = useMessage();\n\n\nconst vf=[\n{s:'width: 100%; height: 100%;',label:'1:1',value:'1:1'}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:'16:9'}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:'9:16'}\n ];\n\nconst modeOptions=[ {label:t('mj.std'),value:'std'},{label:t('mj.pro'),value:'pro'}]\nconst durationOptions=[ {label:'5s',value:'5'},{label:'10s',value:'10'}]\nconst cameraOption=[ {label: t('mj.cnull'),value:''},{label: t('mj.down_back'),value:'down_back'}\n,{label:t('mj.forward_up'),value:'forward_up'},{label:t('mj.right_turn_forward'),value:'right_turn_forward'},{label:t('mj.left_turn_forward'),value:'left_turn_forward'}\n]\nconst mvOption= [\n{label:'kling-v1-6',value: 'kling-v1-6'}\n,{label:'kling-v1-5',value: 'kling-v1-5'}\n,{label:'kling-v1',value: 'kling-v1'}\n,{label:'kling-v2-master',value: 'kling-v2-master'}\n ]\n\nfunction selectFile(input:any){\n   // fsFile.value= input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        f.value.image= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n}\nfunction selectFile2(input:any){ \n    \n    upImg(input.target.files[0]).then(d=>{\n        f.value.image_tail= d;\n        fsRef2.value=''\n        if(f.value.image==''){\n            ms.info( t('mj.needImg'))\n        }\n    }).catch(e=>ms.error(e));\n}\n\n\nconst clearInput = ()=>{\n    f.value.prompt='';\n    f.value.image= '';\n    f.value.image_tail= '';\n    fsRef.value=''\n    fsRef2.value=''\n}\n\nconst createImg = async ()=>{\n    st.value.isLoading= true\n    f.value.aspect_ratio= vf[st.value.bili].value\n    try {\n        let cat= 'text2video'; \n        let abc:any  = {...f.value};\n        //if(abc.image) abc.image= clearImageBase64( abc.image )\n        if(f.value.image!=''){\n            cat='image2video'\n            abc.image= clearImageBase64( abc.image )\n            if( f.value.image_tail) abc.image_tail= clearImageBase64( f.value.image_tail )\n        }else if( st.value.camera_type ){\n            abc.camera_control={ type:st.value.camera_type }\n        }\n        //  mlog('abc>> ',  abc  );\n        // return \n        if (abc.model=='kling-v2-master') {\n            delete abc.mode;\n        }\n\n        const d:any= await klingFetch('/v1/videos/'+ cat , abc  )\n        mlog('img', d );\n        klingFeed( d.data.task_id , cat ,  f.value.prompt )\n    } catch (error) {\n    }  \n    st.value.isLoading= false\n}\n\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n});\n \n</script>\n<template>\n<div class=\"overflow-y-auto  h-full \">\n    <section class=\"mb-4\">\n         <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':index==st.bili}\"  @click=\"st.bili=index\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n\n        </div>\n    </section> \n    \n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mjset.model') }}</div>\n         <n-select v-model:value=\"f.model\" size=\"small\" :options=\"mvOption\"  class=\"!w-[70%]\" />\n         \n    </section>\n      <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.mode') }}</div>\n         <n-select v-model:value=\"f.mode\" size=\"small\" :options=\"modeOptions\"  class=\"!w-[70%]\" />\n         \n    </section>\n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.duration') }}</div>\n         <n-select v-model:value=\"f.duration\" size=\"small\" :options=\"durationOptions\"  class=\"!w-[70%]\" />\n         \n    </section>\n     <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.camera_type') }}</div>\n         <n-select v-model:value=\"st.camera_type\" size=\"small\" :options=\"cameraOption\"  class=\"!w-[70%]\" />\n         \n    </section>\n\n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.nohead') }}</div>\n          <NInput v-model:value=\"f.negative_prompt\" size=\"small\"  class=\"!w-[70%]\"  clearable :placeholder=\"$t('mj.negative_prompt')\" />\n    </section>\n\n     <section class=\"mb-4 flex justify-between items-center\" >\n         \n          <n-input v-model:value=\"f.prompt\" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </section>\n\n    <div class=\"mb-4\">\n        <div class=\"flex justify-start  items-end\">\n            <div> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div   class=\"h-[80px] w-[80px]   overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                    <img :src=\"f.image\" v-if=\"f.image\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                    \n                </div>\n            </div>\n            <div class=\"pl-2\"> \n                <input type=\"file\"  @change=\"selectFile2\"  ref=\"fsRef2\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef2.click()\">\n                    <img :src=\"f.image_tail\" v-if=\"f.image_tail\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.endImg') }}</div> \n                </div>\n            </div>\n           \n        </div>\n    </div>  \n\n    \n    <section class=\"mb-4 flex justify-between items-end\" >\n        <div class=\"relative\"> \n            <div  class=\" cursor-pointer pb-2\" @click=\"clearInput\"  v-if=\"f.image|| f.prompt || f.image_tail\"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n        </div>\n        <div class=\"text-right\">\n\n            <NButton :loading=\"st.isLoading\" type=\"primary\" @click=\"createImg()\" :disabled=\"!f.prompt\"  >{{$t('video.generate')}}</NButton>\n        </div>\n    </section>\n\n    <ul class=\"text-[12px]\" v-html=\"$t('mj.klingInfo')\">\n    \n    </ul>\n</div>\n</template>"
  },
  {
    "path": "src/views/kling/kgList.vue",
    "content": "<script setup lang=\"ts\">\nimport { LazyImg, Waterfall } from 'vue-waterfall-plugin-next'\nimport 'vue-waterfall-plugin-next/dist/style.css'\n\nimport { KlingTask, klingStore } from '@/api/klingStore';\nimport { nextTick, ref, watch } from 'vue';\nimport {NEmpty ,NButton,NPopover, NButtonGroup,NSpin, NImage,NPopconfirm,useMessage} from \"naive-ui\"\nimport { ViewCard } from 'vue-waterfall-plugin-next/dist/types/types/waterfall';\nimport { useBasicLayout } from '@/hooks/useBasicLayout';\nimport { homeStore } from '@/store';\nimport { klingFeed } from '@/api/kling';\nimport { mlog } from '@/api';\nimport { SvgIcon } from '@/components/common';\nimport { t } from '@/locales';\nimport KgImage from './kgImage.vue';\n\nconst list= ref<KlingTask[]>([]);\nconst list2= ref<ViewCard[]>([]);\n \nconst st =ref({show:true ,showImg:'' ,isLoad:false,pIndex:-1,isStart:true });\nconst csuno= new klingStore()\nconst ms= useMessage()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n\n    toList2();\n}\nconst toList2=()=>{\n    list2.value= list.value.map((v,k )=>{\n        let url= v.data.task_result?.images?.[0]?.url||v.data.task_result?.videos?.[0]?.url||''\n        return { url , id: v.request_id,  index: k, src: url ,isLoad:0,task:v } \n    })\n}\n\nconst breakpoints= {\n  2000: { //当屏幕宽度小于等于1200\n    rowPerView: 6,\n  },\n  1600: { //当屏幕宽度小于等于1200\n    rowPerView: 5,\n  },\n  1200: { //当屏幕宽度小于等于1200\n    rowPerView: 4,\n  },\n  800: { //当屏幕宽度小于等于800\n    rowPerView: 3,\n  },\n  500: { //当屏幕宽度小于等于500\n    rowPerView: 2,\n  }\n}\n\nconst { isMobile } = useBasicLayout()\n\nconst showImg= ref<typeof NImage>();\n\n\nconst goShow=( item:any)=>{\n    //console.log('goShow', isMobile );\n    if( isMobile.value)   return ; \n    st.value.show= true;\n    st.value.showImg= item.url ;\n    //console.log('goShow', item);\n    nextTick(() => showImg.value?.click());\n}\nconst goShow2=( item:any)=>{\n    //console.log('goShow', isMobile );\n    if( isMobile.value)   return ; \n    st.value.show= true;\n    st.value.showImg= (item.base64?item.base64: item.src) as string ;\n    //console.log('goShow', item);\n    nextTick(() => showImg.value?.click());\n}\n\ninitLoad();\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='KlingFeed') {\n        st.value.isStart= false;\n        initLoad() \n     }\n});\nconst getFeed=( item:any)=>{\n    mlog('item', item )\n    klingFeed( item.task.data.task_id, item.task.cat, item.task.prompt )\n}\n\nconst deleteGo=(item:any)=>{\n    mlog('deleteGo',item )\n    if( csuno.delete( item.id)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n    <Waterfall :list=\"list2\" :breakpoints=\"breakpoints\"  class=\" !bg-transparent\" v-if=\"list2.length\">\n    <template #item=\"{ item, url, index }\">\n        <div class=\"bg-white dark:bg-[#24272e] rounded-md   overflow-hidden cursor-pointer group/item relative\">\n            <div v-if=\"'failed'==item.task.data.task_status\" >\n                \n                <div class=\"w-full h-[200px] justify-center items-center flex text-center\"> {{ t('video.failed') }}<br>ID: {{ item.task.data.task_id }}</div>   \n               \n            </div>\n            <template v-else-if=\"(!item.task.last_feed|| ((new Date().getTime())-item.task.last_feed)>20*1000) && !item.src \">\n                <div class=\"w-full h-[200px] justify-center items-center flex\">\n                    <NButton  size=\"small\" type=\"primary\" @click=\"getFeed(item)\"    >{{$t('video.repeat')}}</NButton>  \n                </div>\n            </template>\n           \n            <template v-else>\n                <div v-if=\"item.task.cat!='image' && item.src\" style=\"padding-bottom: 0%;\" >\n                    <video v-if=\"item.src\" :src=\"item.src\"   loop  playsinline disableremoteplayback disablepictureinpicture  :controls=\"st.pIndex==index\" class=\"w-full h-full object-cover\"></video>   \n                    <a target=\"_blank\" :href=\"item.src\" class=\" absolute right-[10px] top-[10px] text-[20px] w-[30px] h-[30px] rounded-full bg-white/20 flex justify-center items-center\">\n                        <SvgIcon icon=\"ri:play-fill\"  />\n                    </a>\n                </div>\n                <!-- <LazyImg :url=\"item.src\"  @success=\"item.isLoad=1\"  @click=\"goShow(item )\" v-else-if=\"item.src\" /> -->\n                <KgImage :item=\"item\"  @kg-success=\"item.isLoad=1\"  @kg-click=\"goShow2 \" v-else-if=\"item.src\" />\n                <div v-else class=\"w-[200px] h-[200px]\"></div>\n    \n               \n\n                <section class=\"absolute top-0 left-0 right-0 bottom-0\" v-if=\"(!item.src )  || (item.isLoad==0 && st.isStart && item.task.cat=='image' )\">\n                    <div class=\"flex justify-center items-center w-full h-full\">\n                        <n-spin size=\"large\" />\n                    </div>\n                </section>\n            </template>\n\n             <section v-if=\"item.task.prompt\" class=\"absolute w-full bottom-0   backdrop-blur-sm text-white/70  \" :class=\"item.src?['invisible', 'group-hover/item:visible']:[]\">\n                    <div class=\"p-3  flex justify-between items-baseline\"> \n                        <div class=\"line-clamp-2 text-[13px]\"> \n                            <template v-if=\"item.task.prompt\">{{ item.task.prompt }}</template>\n                        </div>\n                        <div>\n                            <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </div>\n                    </div>\n                </section>\n\n        </div>\n    </template>\n    </Waterfall>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n<NImage   :src=\"st.showImg\"  ref=\"showImg\" v-if=\"st.showImg\" :width=\"1\" />\n</template>"
  },
  {
    "path": "src/views/luma/layout.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport { NLayout, NLayoutContent } from 'naive-ui'\nimport { useRouter, useRoute } from 'vue-router' \nimport Permission from '../chat/layout/Permission.vue'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { homeStore, useAppStore, useAuthStore, useChatStore } from '@/store'\nimport { aiSider ,aiFooter} from '@/views/mj'\nimport aiMobileMenu from '@/views/mj/aiMobileMenu.vue'; \nimport { mlog } from '@/api'\n\nconst router = useRouter()\nconst route = useRoute()\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\nconst authStore = useAuthStore()\n\nmlog('layout', route.name )\nrouter.replace({ name:  route.name??'video', params: { uuid: chatStore.active } })\nhomeStore.setMyData({local:  route.name??'video' });\nconst { isMobile } = useBasicLayout()\n\nconst collapsed = computed(() => appStore.siderCollapsed)\n\nconst needPermission = computed(() => !!authStore.session?.auth && !authStore.token)\n\nconst getMobileClass = computed(() => {\n  if (isMobile.value)\n    return ['rounded-none', 'shadow-none' ]\n  return [ 'shadow-md', 'dark:border-neutral-800' ] //'border', 'rounded-md',\n})\n\nconst getContainerClass = computed(() => {\n  return [\n    'h-full',\n    { 'abc': !isMobile.value && !collapsed.value },\n  ]\n}) \n</script>\n\n<template>\n  <div class=\"dark:bg-[#24272e] transition-all p-0\" :class=\"[isMobile ? 'h55' : 'h-full' ]\">\n    <div class=\"h-full overflow-hidden\" :class=\"getMobileClass\">\n      <NLayout class=\"z-40 transition\" :class=\"getContainerClass\" has-sider  :sider-placement=\"isMobile?'left': 'right'\">\n        <aiSider v-if=\"!isMobile\"/>\n       \n        <NLayoutContent class=\"h-full\">\n          <RouterView v-slot=\"{ Component, route }\">\n            <component :is=\"Component\" :key=\"route.fullPath\" />\n          </RouterView>\n        </NLayoutContent>\n         <!-- <Sider /> -->\n      </NLayout>\n    </div>\n    <Permission :visible=\"needPermission\" />\n  </div>\n   <aiMobileMenu v-if=\"isMobile\"   /> \n  <aiFooter/> \n</template>\n<style  >\n.h55{\n  height: calc(100% - 55px);\n}\n</style>\n"
  },
  {
    "path": "src/views/luma/lumaInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { NInput,NButton, useMessage,NTag ,NPopover,NSelect,NSwitch} from 'naive-ui';\nimport {SvgIcon} from '@/components/common'\nimport { FeedLumaTask, lumaFetch, mlog, upImg } from '@/api';\nimport { gptServerStore, homeStore } from '@/store';\nimport { t } from '@/locales';\nimport { LumaMedia, lumaHkStore } from '@/api/lumaStore';\nimport { sleep } from '@/api/suno';\n\nconst luma= ref({ \"aspect_ratio\": \"16:9\",loop:false, \"expand_prompt\": true,  \"image_url\": \"\",  \"user_prompt\": \"\",\"image_end_url\": \"\", });\nconst st= ref({isDo:false,version:'relax'})\nconst ms = useMessage();\nconst fsRef= ref() ;\nconst fsRef2 = ref() ;\nconst exLuma= ref<LumaMedia>()\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1'}\n,{s:'width: 100%; height: 75%;',label:'4:3'}\n,{s:'width: 75%; height: 100%;',label:'3:4'}\n,{s:'width: 100%; height: 50%;',label:'16:9'}\n,{s:'width: 50%; height: 100%;',label:'9:16'}\n ];\n\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n    st.value.version= gptServerStore.myData.IS_LUMA_PRO?'pro':'relax'\n});\n\n\n\nconst canPost = computed(() => {\n    return luma.value.user_prompt!='' && !st.value.isDo\n})\nconst generate= async ()=>{\n    mlog(\"generate\", luma.value )\n    st.value.isDo= true\n    if(!canPost){\n        ms.error( t('video.plsInput') )\n        return ;\n    }\n    try{\n        let url= '/generations/';\n        if(exLuma.value) url= `/generations/${exLuma.value.id}/extend`\n        //homeStore.myData.is_luma_pro?'/pro':''\n        //if(homeStore)\n        const is_luma_pro=homeStore.myData.is_luma_pro\n        if (is_luma_pro) url= '/pro'+url\n        const d:any=  await lumaFetch(url, luma.value);\n        mlog(\"d\", d )\n        // if(d.id ) FeedLumaTask(d.id )\n        // else FeedLumaTask(d[0].id )\n        \n        const taskID= d.id??d[0].id\n        if( is_luma_pro ){\n            const hk= new lumaHkStore();\n            hk.save({id:taskID,isHK:true})\n        }\n       \n        \n        ms.success( t('video.submitSuccess'))\n         await sleep(500)\n        FeedLumaTask(taskID)\n    }catch(e){\n        \n    }\n    st.value.isDo= false\n    //FeedLumaTask('33ace512-9a46-40ab-9d08-a05eff989831')\n}\n\nfunction selectFile(input:any){\n     \n    upImg(input.target.files[0]).then(d=>{\n        luma.value.image_url= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n    \n}\n\nfunction selectFile2(input:any){\n    upImg(input.target.files[0]).then(d=>{\n        luma.value.image_end_url= d;\n        fsRef2.value=''\n    }).catch(e=>ms.error(e));\n    \n}\n\nconst clearInput = ()=>{\n    luma.value.user_prompt= ''\n    luma.value.image_url= ''\n    luma.value.image_end_url= ''\n    exLuma.value= undefined\n}\n\n//luma.extend\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='luma.extend'){\n        mlog(\"luma.extend\", homeStore.myData.actData )\n        const s= homeStore.myData.actData as LumaMedia\n        exLuma.value= s \n        // cs.value.continue_clip_id= s.id\n        // cs.value.continue_at= Math.ceil(s.metadata.duration/2) \n    }\n});\n\nconst isHK= computed(()=> {\n    const url= gptServerStore.myData.LUMA_SERVER.toLocaleLowerCase();\n    if(url!=''){\n     return (url.indexOf('hk')>-1 &&  url.indexOf('pro')==-1 ) ;\n    }\n   \n    return (homeStore.myData.session && homeStore.myData.session.isHk) ;\n    \n} );\nconst saveMyDate=(is_pro:boolean)=>{\n    homeStore.setMyData({is_luma_pro: is_pro})\n    gptServerStore.setMyData({IS_LUMA_PRO: is_pro})\n}\n\nwatch(()=>isHK.value , (n)=>    saveMyDate( n && st.value.version=='pro' ) ); \nwatch(()=>st.value.version , ()=>  saveMyDate(isHK.value && st.value.version=='pro' ) );\n\nconst mvOption= [\n{label: '版本: relax, 价格实惠',value: 'relax'}\n,{label:'版本: pro, 快且无水印',value: 'pro'}\n ]\n\n</script>\n\n<template>\n<div class=\"p-2\"> \n    <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':luma.aspect_ratio==item.label}\"  @click=\"luma.aspect_ratio=item.label\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n    </div>\n\n    <div class=\"pt-1\" >\n      <n-input v-model:value=\"luma.user_prompt\" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </div>\n    <div class=\"pt-1\">\n        <div class=\"flex justify-between items-center\">\n            <div>\n                <n-switch v-model:value=\"luma.expand_prompt\" size=\"small\">\n                    <template #checked> \n                    Enhance prompt\n                    </template>\n                    <template #unchecked> \n                    Enhance prompt\n                    </template>\n                </n-switch>\n            </div>\n            <div>\n                <n-switch  v-model:value=\"luma.loop\" size=\"small\">\n                    <template #checked> \n                    Loop\n                    </template>\n                    <template #unchecked> \n                    Loop\n                    </template>\n                </n-switch>\n            </div>\n        </div>\n    </div>\n    <div v-if=\"exLuma\" class=\"pt-1\">\n        <div class=\"flex justify-between items-center\">\n            <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">{{ $t('video.extend') }}:{{exLuma.prompt}}</div>\n                    </template>\n                    <div class=\" max-w-[300px]\">{{exLuma.prompt}}</div>\n                </n-popover>\n            </div>\n        </div>\n        <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[5px] overflow-hidden aspect-[16/8.85] \">\n                <video v-if=\"exLuma.video?.url|| exLuma.video?.download_url\" :src=\"exLuma.video?.download_url? exLuma.video?.download_url:exLuma.video?.url\" @error=\"$event.target.src=exLuma.video?.url\" loop  playsinline  controls class=\"w-full h-full object-cover\"></video>    \n        </div>\n            \n    </div>\n\n    <div  class=\"pt-1\" v-if=\"isHK\">\n        <n-select v-model:value=\"st.version\" :options=\"mvOption\" size=\"small\" />\n    </div>\n    \n    <div class=\"pt-1\">\n        <div class=\"flex justify-start  items-end\">\n            <div> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                    <img :src=\"luma.image_url\" v-if=\"luma.image_url\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                </div>\n            </div>\n            <div class=\"pl-2\"> \n                <input type=\"file\"  @change=\"selectFile2\"  ref=\"fsRef2\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef2.click()\">\n                    <img :src=\"luma.image_end_url\" v-if=\"luma.image_end_url\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.endImg') }}</div> \n                </div>\n            </div>\n           \n        </div>\n    </div>  \n     <div class=\"pt-1\">\n        <div class=\"flex justify-between items-end\">\n            <div class=\"pb-1 text-right\">\n                <NTag v-if=\" exLuma|| luma.user_prompt!=''||luma.image_url!=''||luma.image_end_url!=''\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"clearInput()\" >{{$t('video.clear')}}</span></NTag>\n            </div>\n            <div>\n                <NButton  :loading=\"st.isDo\" type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\"><SvgIcon icon=\"ri:video-add-line\"  /> {{$t('video.generate')}}</NButton> \n            </div>\n        </div>  \n    </div>\n    \n    <div class=\"pt-2 text-[12px]\" v-html=\"$t('video.lumainfo')\" v-if=\"isHK\">\n       \n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/pikaInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { mlog, upImg } from '@/api'; \nimport { useMessage,NButton,NInput,NTag,NSelect,NPopover,NSwitch } from 'naive-ui';\n \nimport { t } from \"@/locales\"; \nimport { pikaFeed, pikaFetch } from '@/api/pika';\n\nlet txt2v={\n \t\"pikaffect\": \"\",\n\t\"promptText\": \"\",\n\t\"model\": \"1.5\",\n\t\"options\": {\"aspectRatio\":1.7777777777777777,\"frameRate\":24,\"camera\":{},\"parameters\":{\"guidanceScale\":12,\"motion\":1,\"negativePrompt\":\"\"},\"extend\":false}\n   \n}\nlet img2v={\n \t\"pikaffect\": \"\",\n\t\"promptText\": \"\",\n\t\"model\": \"1.5\",\n\t\"options\": {\"frameRate\":24,\"camera\":{},\"parameters\":{\"guidanceScale\":12,\"motion\":1,\"negativePrompt\":\"\"},\"extend\":false}\n   ,\"image\":\"https://www.openai-hk.com/res/img/open.png\"\n}\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1',value:1}\n,{s:'width: 100%; height: 75%;',label:'4:3',value:1.3333333333333333}\n,{s:'width: 75%; height: 100%;',label:'3:4',value:0.75}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:1.7777777777777777}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:0.5625}\n ];\nconst mvOption= [\n{label:'verion: v2.0',value: '2.0'}\n,{label:'verion: v1.5',value: '1.5'}\n ]\n\nlet ezOption = [\n        {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/peel.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/peel.jpg\",\n            title: \"Peel\"\n            \n        },  {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/poke.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/poke.jpg\",\n            title: \"Poke\"\n            \n        },  {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/tear.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/tear.jpg\",\n            title: \"Tear\"\n            \n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/levitate.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/levitate.jpg\",\n            title: \"Levitate\"\n            \n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/decapitate.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/decapitate.jpg\",\n            title: \"Decapitate\"\n            \n        },{\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/eye-pop.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/eye-pop.jpg\",\n            title: \"Eye-pop\"\n            \n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/tada.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/tada.jpg\",\n            title: \"Ta-da\"\n            \n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/deflate.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/deflate.jpg\",\n            title: 'Deflate'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/crumble.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/crumble.jpg\",\n            title: 'Crumble'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/dissolve.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/dissolve.jpg\",\n            title: 'Dissolve'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/squish.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/squish.jpg\",\n            title: 'Squish'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/inflate.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/inflate.jpg\",\n            title: 'Inflate'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/melt.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/melt.jpg\",\n            title: 'Melt',\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/crush.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/crush.jpg\",\n            title: 'Crush'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/cake-ify.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/cake-ify.jpg\",\n            title:'Cake-ify'\n        }, {\n            video: \"https://cdn.pika.art/feature/v1.5/pikaffect/explode.webm\",\n            poster: \"https://cdn.pika.art/feature/v1.5/pikaffect/explode.jpg\",\n            title: 'Explode',\n            //text:'Explode it'\n        }];\n\nconst pika= ref({image:'',prompt:'',aspectRatio:1.7777777777777777,negativePrompt:'',pe_index:-1,mv:'2.0'});\nconst fsRef= ref() ; \nconst ms = useMessage();\nconst st= ref({ isLoading:false});\n\nfunction selectFile(input:any){\n   // fsFile.value= input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        pika.value.image= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n}\nconst clearInput = ()=>{\n    pika.value.prompt='';\n    pika.value.image= ''; \n    fsRef.value='' \n    pika.value.pe_index= -1;\n}\nconst createVideo = async()=>{\n    let sb= pika.value.image ? {...img2v} : {...txt2v};\n    sb.promptText= pika.value.prompt; \n    sb.options.parameters.negativePrompt= pika.value.negativePrompt;\n    if( pika.value.image ){\n        sb.image= pika.value.image;\n    }else{\n        sb.options.aspectRatio= pika.value.aspectRatio;\n    }\n    if(pika.value.pe_index>=0){\n        sb.pikaffect= ezOption[pika.value.pe_index].title\n    }\n    sb.model= pika.value.mv;\n    mlog('sb>> '  ,  sb  );\n    st.value.isLoading= true\n    try {\n        const a:any= await pikaFetch('/generate' , sb  )\n        st.value.isLoading= false\n        if(a.id){\n            pikaFeed( a.id)\n        }else{\n            ms.error( t('mj.createFail') );//createFail\n        }\n    } catch (error) {\n        st.value.isLoading= false\n    } \n}\n\nconst selecteffect = (i:number)=>{\n    pika.value.pe_index= i ;\n    pika.value.prompt= ezOption[i].title+' it';\n}\n</script>\n<template>\n<div class=\"p-2\"> \n    <div class=\" flex items-center justify-between space-x-1\">\n        <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':pika.aspectRatio==item.value}\"  @click=\"pika.aspectRatio=item.value\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n        </template>\n    </div>\n    \n    <div class=\"pt-1\" >\n      <n-input v-model:value=\"pika.prompt\" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </div>\n    <div  class=\"pt-1\">\n       <n-select v-model:value=\"pika.mv\" :options=\"mvOption\" size=\"small\" />\n    </div>\n    <section class=\"pt-1 flex justify-between items-center\" >\n         <div>{{ $t('mj.nohead') }}</div>\n          <NInput v-model:value=\"pika.negativePrompt\" size=\"small\"  class=\"!w-[70%]\"  clearable :placeholder=\"$t('mj.negative_prompt')\" />\n    </section>\n    <div class=\"pt-2\">\n        <div class=\"flex justify-between  items-end\">\n            <div> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div   class=\"h-[80px] w-[80px]   overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                    <img :src=\"pika.image\" v-if=\"pika.image\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                </div>\n            </div>\n            <div>\n            <NPopover trigger=\"hover\">\n                <template #trigger>\n                    <div   class=\"h-[80px] w-[150px]  relative  overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" >\n                        <template v-if=\"pika.pe_index>-1\">\n                            <img :src=\"ezOption[pika.pe_index].poster\"  />\n                            <div class=\"absolute top-1 right-1 text-white/75 text-[14px]\" >{{ ezOption[pika.pe_index].title }}</div>\n                        </template>\n                        <div class=\"text-center\" v-else>{{ $t('mj.selecteff') }}</div> \n                    </div>\n                </template>\n                <div class=\"w-[320px] h-[400px] overflow-y-auto overflow-hidden mx-[-4px]\">\n                    <div class=\"grid grid-cols-2 gap-2\">\n                        <div v-for=\"(item, index) in ezOption\" :key=\"index\" >\n                            <div class=\"relative   overflow-hidden cursor-pointer \" @click=\"selecteffect(index)\">\n                                <video class=\"h-[72px] w-full rounded-md object-cover\"  :src=\"item.video\"  :poster=\"item.poster\" \n                                 autoplay  loop  playsinline ></video>\n                                <div class=\"absolute top-1 right-1 text-white/75 text-[14px]\" >{{ item.title }}</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </NPopover>\n            </div>\n        </div>\n    </div>\n    <section class=\"pt-2 flex justify-end items-end\">\n            \n            <div  class=\" cursor-pointer pr-2\" @click=\"clearInput\"  v-if=\"pika.image|| pika.prompt\"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n            \n            <div class=\"text-right\">\n\n                    <NButton :loading=\"st.isLoading\" type=\"primary\" @click=\"createVideo()\" :disabled=\"!pika.prompt\"  >{{$t('video.generate')}}</NButton>\n            </div>\n    </section>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/pikaList.vue",
    "content": "<script setup lang=\"ts\">\nimport { pikaFeed } from '@/api/pika';\nimport { PikaTask, pikaStore } from '@/api/pikaStore';\nimport { onMounted, ref, watch } from 'vue';\nimport {NEmpty,NButton,NPopover, NButtonGroup, useMessage,NPopconfirm} from \"naive-ui\"\nimport { mlog } from '@/api';\nimport {SvgIcon} from '@/components/common'\nimport { t } from '@/locales';\nimport { homeStore } from '@/store';\n\nconst st= ref({pIndex:-1});\nconst list= ref<PikaTask[]>([]);\nconst csuno= new pikaStore()\n\nconst ms= useMessage();\n\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\n\nconst deleteGo=(item:PikaTask)=>{\n    mlog('deleteGo',item )\n    if( csuno.delete( item)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\n\n//pikaFeed('66e0818e-05fb-454e-b246-a6f253e9ffbf')\n//pikaFeed('e90a4fa4-009a-4ca8-9002-57d2f2cbb6c3')\n//PikaFeed\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='PikaFeed')  initLoad()\n})\nonMounted(() => {\n    initLoad();\n    homeStore.setMyData({ms:ms });\n})\n</script>\n<template>\n \n<div v-if=\"list.length>0\" class=\"p-4\">\n    <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                \n                <template v-if=\"item.videos.length>0\">\n                    <video   loop  playsinline  :controls=\"st.pIndex==index\" v-if=\"  item.videos[0].resultUrl\"\n                        referrerpolicy=\"no-referrer\" :poster=\"item.videos[0].videoPoster\" \n                        class=\"w-full h-full object-cover\"   >\n                            <source  :src=\"item.videos[0].resultUrl\" referrerpolicy=\"no-referrer\" type=\"video/mp4\" v-if=\"st.pIndex==index\">\n                    </video>\n                    <div v-else-if=\"'error'==item.videos[0].status\" >\n                        <div class=\"w-full h-[200px] justify-center items-center flex text-center\"> \n                        {{ t('video.failed') }}<br>ID: {{ item.id }}\n                        <br>{{ item.videos[0].error }}\n                        </div>   \n                    </div>\n                   <template v-else-if=\"(!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000)  \">\n                        <div class=\"w-full h-[200px] justify-center items-center flex\">\n                            <NButton  size=\"small\" type=\"primary\" @click=\"pikaFeed(item.id)\"    >{{$t('video.repeat')}}</NButton>  \n                        </div>\n                    </template>\n                    <div class=\"pt-2 \" v-else>\n                        <div>\n                        {{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}\n                        </div>\n                        <div v-if=\"item.videos[0].progress\" class=\"text-center\">{{ item.videos[0].progress }}%</div> \n                        <div v-if=\"item.videos[0].status=='queued'\" class=\"text-center\">{{t('video.pending') }}</div> \n                    </div>\n                </template>\n\n            </div>\n            <div class=\"flex justify-between items-center\">\n                <section  >\n                 <div class=\"line-clamp-1\">{{ item.promptText }}</div>\n                </section>\n                <section class=\"flex justify-end items-center pt-1\" > \n                     <n-button-group size=\"tiny\" >\n                        <n-button  size=\"tiny\" round ghost    v-if=\"item.videos[0].resultUrl\" >\n                            <a :href=\"item.videos[0].resultUrl\" download  target=\"_blank\" class=\"flex justify-center items-center\"  >\n                                <SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }}\n                            </a>\n                        </n-button>\n                        <n-button   size=\"tiny\"  round ghost    > \n                            <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </n-button>\n                        <!-- <n-button   size=\"tiny\"  round ghost  @click=\"extend( item )\"  ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button> -->\n                        \n                        \n                      </n-button-group>\n                     \n                </section>\n            </div>\n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n \n</template>"
  },
  {
    "path": "src/views/luma/pixCamera.json",
    "content": "{\n    \"name\": {\n        \"horizontal_left\": \"水平向左\",\n        \"horizontal_right\": \"水平向右\",\n        \"vertical_up\": \"垂直向上\",\n        \"vertical_down\": \"垂直向下\",\n        \"crane_up\": \"上升镜头\",\n        \"hitchcock\": \"希区柯克变焦\",\n        \"zoom_in\": \"放大\",\n        \"zoom_out\": \"缩小\",\n        \"quickly_zoom_in\": \"快速推进\",\n        \"quickly_zoom_out\": \"快速拉远\",\n        \"smooth_zoom_in\": \"平滑推进\",\n        \"super_dolly_out\": \"超级拉远\",\n        \"left_follow\": \"左侧跟拍\",\n        \"right_follow\": \"右侧跟拍\",\n        \"pan_left\": \"左侧环弧\",\n        \"pan_right\": \"右侧环弧\",\n        \"fix_bg\": \"固定镜头\",\n        \"camera_rotation\": \"镜头旋转\",\n        \"robo_arm\": \"机械臂运动\",\n        \"whip_pan\": \"快速摇镜\"\n    },\n    \"image\": {\n        \"horizontal_left\": \"https://media.pixverse.ai/asset/template/web_horizontalleft_250429.gif\",\n        \"horizontal_right\": \"https://media.pixverse.ai/asset/template/web_horizontalright_250429.gif\",\n        \"vertical_up\": \"https://media.pixverse.ai/asset/template/web_verticalup_250429.gif\",\n        \"vertical_down\": \"https://media.pixverse.ai/asset/template/web_verticaldown _250429.gif\",\n        \"crane_up\": \"https://media.pixverse.ai/asset/template/web_craneup_250428.gif\",\n        \"hitchcock\": \"https://media.pixverse.ai/asset/template/Dolly Zoom.gif\",\n        \"zoom_in\": \"https://media.pixverse.ai/asset/template/web_zoomin_250429.gif\",\n        \"zoom_out\": \"https://media.pixverse.ai/asset/template/web_zoomout_250429.gif\",\n        \"quickly_zoom_in\": \"https://media.pixverse.ai/asset/template/web_quicklyzoomin_250428.gif\",\n        \"quickly_zoom_out\": \"https://media.pixverse.ai/asset/template/web_quicklyzoomout_250428.gif\",\n        \"smooth_zoom_in\": \"https://media.pixverse.ai/asset/template/web_smoothzoomin_250428.gif\",\n        \"super_dolly_out\": \"https://media.pixverse.ai/asset/template/web_superdollyout_250428.gif\",\n        \"left_follow\": \"https://media.pixverse.ai/asset/template/Left Tracking Shot.gif\",\n        \"right_follow\": \"https://media.pixverse.ai/asset/template/Right Tracking Shot.gif\",\n        \"pan_left\": \"https://media.pixverse.ai/asset/template/Left Arc Shot.gif\",\n        \"pan_right\": \"https://media.pixverse.ai/asset/template/Right Arc Shot.gif\",\n        \"fix_bg\": \"https://media.pixverse.ai/asset/template/Fixed Shot.gif\",\n        \"camera_rotation\": \"https://media.pixverse.ai/asset/template/web_camerarotation_250428.gif\",\n        \"robo_arm\": \"https://media.pixverse.ai/asset/template/web_roboarm_250428.gif\",\n        \"whip_pan\": \"https://media.pixverse.ai/asset/template/web_whippan_250428.gif\"\n    }\n}"
  },
  {
    "path": "src/views/luma/pixEffact.json",
    "content": "[\n    {\n        \"display_name\": \"Muscle Surge\",\n        \"workflow_tag\": \"muscle_241128\",\n        \"template_id\": 308621408717184,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fwithbaby.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-11-28T17:53:21Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Show off your strong muscles and have everyone hooked.\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"成为肌肉猛男\\\",\\\"display_prompt\\\":\\\"体验猛男快乐\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113750602,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F920dc791-8c9f-4518-8761-82958a827190.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Hug Your Love\",\n        \"workflow_tag\": \"hug_love_241030\",\n        \"template_id\": 303624424723200,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fhug2.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-10-31T12:07:47Z\",\n        \"updated_at\": \"2025-01-06T05:32:42Z\",\n        \"display_prompt\": \"Hug each other\\t\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"爱的抱抱\\\",\\\"display_prompt\\\":\\\"互相拥抱在一起\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Alive Art\",\n        \"workflow_tag\": \"alive_art_241028\",\n        \"template_id\": 302325299721280,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Faliveart.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2025-01-06T05:32:53Z\",\n        \"display_prompt\": \"The [OBJECT] comes to life and walks out of the [SCENE]\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"活灵活现\\\",\\\"display_prompt\\\":\\\"它活了！\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Sheep Curls\",\n        \"workflow_tag\": \"sheep_241208\",\n        \"template_id\": 310371322329472,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FSheepCurls.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"new\",\n        \"created_at\": \"2024-12-08T15:14:11Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Change hairstyle for a better mood\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"万物皆可羊毛卷\\\",\\\"display_prompt\\\":\\\"心情不好，换个发型看看\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Sailor Moon\",\n        \"workflow_tag\": \"meishaonv_241225\",\n        \"template_id\": 313359138372032,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fmeishaonv2.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"\",\n        \"created_at\": \"2024-12-25T12:29:05Z\",\n        \"updated_at\": \"2025-01-06T05:32:33Z\",\n        \"display_prompt\": \"Moon Prism Power, Make Up!\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"成为美少女战士\\\",\\\"display_prompt\\\":\\\"月之水晶力量，变身！\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Black Myth: Wukong\",\n        \"workflow_tag\": \"heiwukong_241225\",\n        \"template_id\": 313359209531840,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fmonkey.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"\",\n        \"created_at\": \"2024-12-25T12:29:40Z\",\n        \"updated_at\": \"2025-01-06T05:32:25Z\",\n        \"display_prompt\": \"I am Sun Wukong, the Victorious Fighting Buddha!\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"黑悟空引擎\\\",\\\"display_prompt\\\":\\\"放马西行，直面天命！\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Santa's Secret Gifts\",\n        \"workflow_tag\": \"santa_gift_241213\",\n        \"template_id\": 311521768592256,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fgift111.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"new\",\n        \"created_at\": \"2024-12-15T03:16:32Z\",\n        \"updated_at\": \"2024-12-30T06:08:16Z\",\n        \"display_prompt\": \"I want a：\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"圣诞礼物盲盒\\\",\\\"display_prompt\\\":\\\"我想要：\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Where is Santa?\",\n        \"workflow_tag\": \"where_is_santa_241213\",\n        \"template_id\": 311521879229312,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fwheresanta.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"new\",\n        \"created_at\": \"2024-12-15T03:17:26Z\",\n        \"updated_at\": \"2024-12-30T06:08:24Z\",\n        \"display_prompt\": \"Discovering Santa Claus in the parallel world!\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"圣诞老人藏在哪？\\\",\\\"display_prompt\\\":\\\"“发现”世界各处的圣诞老人\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":119280295,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fde34a072-325e-4d86-88d9-2daef292e1b4.jpeg\\\"},{\\\"img_id\\\":119280616,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F5b4da0a2-86c3-4204-adda-74bfa7c3d0d1.jpg\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Christmas OOTD\",\n        \"workflow_tag\": \"tobe_santa_241219\",\n        \"template_id\": 312314911869312,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fbesanta33.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"new\",\n        \"created_at\": \"2024-12-19T14:51:09Z\",\n        \"updated_at\": \"2024-12-30T06:08:08Z\",\n        \"display_prompt\": \"Dress up as a Christmas star\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"圣诞战袍\\\",\\\"display_prompt\\\":\\\"测测什么圣诞装适合你\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"We Are Venom!\",\n        \"workflow_tag\": \"venom_241030\",\n        \"template_id\": 303624537709312,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FWeAreVenom.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-10-31T12:08:42Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Transform into a [BLACK] Venom\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"毒液变身！\\\",\\\"display_prompt\\\":\\\"变身成为【黑色】毒液\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113750602,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F920dc791-8c9f-4518-8761-82958a827190.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Hot Harley Quinn\",\n        \"workflow_tag\": \"harley_quinn_241121\",\n        \"template_id\": 307489434436288,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FHotHarleyQuinn.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-22T08:21:19Z\",\n        \"updated_at\": \"2024-12-26T07:40:43Z\",\n        \"display_prompt\": \"Transform into Harley Quinn, mastering allure and chaos\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"小丑女哈莉·奎茵变身\\\",\\\"display_prompt\\\":\\\"化身小丑女哈莉·奎茵，掌控魅惑与疯狂\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113742000,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F19090035-612e-40ed-9c8d-a7aaf781d492.png\\\"},{\\\"img_id\\\":113742074,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F50ed9020-7b58-4dd9-aa39-ff06b9e0df12.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Crazy Cat Woman\",\n        \"workflow_tag\": \"cat_woman_241121\",\n        \"template_id\": 307489548427968,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FCrazyCatWoman.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-22T08:22:15Z\",\n        \"updated_at\": \"2024-12-26T07:40:24Z\",\n        \"display_prompt\": \"Transform into a Crazy Cat Woman and slay\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"疯狂猫女变身\\\",\\\"display_prompt\\\":\\\"变身妖娆猫女，撩翻全场！\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113742074,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F50ed9020-7b58-4dd9-aa39-ff06b9e0df12.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Wonder Woman\",\n        \"workflow_tag\": \"wonder_woman_241202\",\n        \"template_id\": 309283958194560,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FWonderWoman.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-12-02T11:45:11Z\",\n        \"updated_at\": \"2024-12-26T07:40:35Z\",\n        \"display_prompt\": \"Transform into Wonder Woman and conquer the impossible\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"神奇女侠变身\\\",\\\"display_prompt\\\":\\\"成为神奇女侠，征服一切不可能\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113742074,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F50ed9020-7b58-4dd9-aa39-ff06b9e0df12.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Hulk\",\n        \"workflow_tag\": \"hulk_241106\",\n        \"template_id\": 304826314164992,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2FHulk.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-07T07:08:47Z\",\n        \"updated_at\": \"2024-12-26T07:38:48Z\",\n        \"display_prompt\": \"Unleash the Beast\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"召唤绿巨人\\\",\\\"display_prompt\\\":\\\"变身成绿巨人并捶爆一切\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113750602,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F920dc791-8c9f-4518-8761-82958a827190.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Joker's Rebirth\",\n        \"workflow_tag\": \"joker_241106\",\n        \"template_id\": 304826126435072,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_joker.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-07T07:07:16Z\",\n        \"updated_at\": \"2024-12-26T07:38:54Z\",\n        \"display_prompt\": \"Transform into a Joker\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"小丑重生\\\",\\\"display_prompt\\\":\\\"变身成小丑，诡异地微笑\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113750602,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F920dc791-8c9f-4518-8761-82958a827190.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Batman\",\n        \"workflow_tag\": \"bat_man_241106\",\n        \"template_id\": 304826374632192,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_batman.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-07T07:09:17Z\",\n        \"updated_at\": \"2024-12-26T07:39:00Z\",\n        \"display_prompt\": \"Transform into a Batman and embrace the night\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"蝙蝠侠归来\\\",\\\"display_prompt\\\":\\\"变身成蝙蝠侠并守护黑夜\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Iron Man\",\n        \"workflow_tag\": \"iron_man_241106\",\n        \"template_id\": 304826054394624,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_ironman.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-07T07:06:40Z\",\n        \"updated_at\": \"2024-12-26T07:39:06Z\",\n        \"display_prompt\": \"Activate Iron Mode\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"钢铁侠变身\\\",\\\"display_prompt\\\":\\\"激活钢铁模式\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Hair Growth Magic\",\n        \"workflow_tag\": \"hair_magic_241128\",\n        \"template_id\": 308552687706496,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_hairgrowth.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-28T08:34:06Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Grow lots of hair. Never be bald.\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"发量王者\\\",\\\"display_prompt\\\":\\\"长出迷人秀发，永无秃头困扰。\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113750602,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F920dc791-8c9f-4518-8761-82958a827190.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"},{\\\"img_id\\\":113750791,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Ff2853009-8238-4e0f-93ec-cfc68fee28b7.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"COLORFUL Venom!\",\n        \"workflow_tag\": \"random_venom_241104\",\n        \"template_id\": 304358279051648,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_colorfulvenom.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-04T15:39:54Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Transform into a [COLORFUL] Venom\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"毒液！(彩色盲盒版)\\\",\\\"display_prompt\\\":\\\"变身成为【彩色】毒液\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Who is Venom?\",\n        \"workflow_tag\": \"who_is_venom_241112\",\n        \"template_id\": 305714097668480,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_whoisvenom.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-12T07:33:35Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Which one of you guys is Venom? \",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"测测谁是毒液？\\\",\\\"display_prompt\\\":\\\"两人之中，必有一毒，速速现出原形\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":111917190,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F6a6a0f6a-99be-4eac-83a1-9d265ca65823.png\\\"},{\\\"img_id\\\":111917753,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F079945d6-01aa-4688-9e9a-02e308c01db5.png\\\"},{\\\"img_id\\\":111917942,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2F814307ed-4123-4f6b-a32e-4072b55378cb.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\"\n        ]\n    },\n    {\n        \"display_name\": \"Get a Venom buddy\",\n        \"workflow_tag\": \"baby_venom_241114\",\n        \"template_id\": 306059795500352,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_venombuddy.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-14T06:26:53Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"Your Venom buddy appears and gives you a hug\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"召唤毒液兄弟\\\",\\\"display_prompt\\\":\\\"你的毒液兄弟回到你身边，并与你深情相拥\\\"}}\",\n        \"example_list\": \"[{\\\"img_id\\\":113741803,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fb2626bc2-050d-4ea6-a864-e2054c012df5.png\\\"},{\\\"img_id\\\":113750690,\\\"img_url\\\":\\\"https://media.pixverse.ai/upload%2Fddd29e75-beeb-461c-9388-3e14c2709e73.png\\\"}]\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Wicked Shots\",\n        \"workflow_tag\": \"wicked_paintings_241028\",\n        \"template_id\": 303788802773760,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_wickedshot.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-11-01T10:25:30Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"The [SUBJECT] in the picture smiles wickedly and starts firing\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"扫射一切\\\",\\\"display_prompt\\\":\\\"邪魅一笑，并掏出一把机关枪开始扫射\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Squish It\",\n        \"workflow_tag\": \"squish_it_241028\",\n        \"template_id\": 302325299692608,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_squishit.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"A pair of hands appears and squishes the [OBJECT] as if it's slime\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"捏捏更解压\\\",\\\"display_prompt\\\":\\\"变成可以捏捏的软泥\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Lego Blast\",\n        \"workflow_tag\": \"lego_blast_241028\",\n        \"template_id\": 302325299702848,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_legoblast.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"The [OBJECT] shatters into pieces of Legos\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"乐高大爆炸\\\",\\\"display_prompt\\\":\\\"爆炸并碎裂成一片片乐高积木\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Leggy Run\",\n        \"workflow_tag\": \"leggy_run_241028\",\n        \"template_id\": 302325299711040,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_leggyrun.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"The [OBJECT] grows legs and runs away\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"全员腿精\\\",\\\"display_prompt\\\":\\\"长出了一双腿然后开始乱跑\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Monster Invades\",\n        \"workflow_tag\": \"monster_invasion_241028\",\n        \"template_id\": 302325299682368,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_monster.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"default\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"A monster suddenly appears in the [SCENE] and starts walking around\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"怪兽入侵\\\",\\\"display_prompt\\\":\\\"场景中突然出现了一只怪兽\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Wizard Hat\",\n        \"workflow_tag\": \"animal_wizard_241028\",\n        \"template_id\": 302325299661888,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_wizardhat.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"The [SUBJECT] wears a magic wizard hat\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"戴上魔法帽\\\",\\\"display_prompt\\\":\\\"头顶出现了一顶可爱的魔法帽\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Zombie Hand\",\n        \"workflow_tag\": \"zombie_hand_241028\",\n        \"template_id\": 302325299672128,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_weirdhand.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"A zombie hand appears in the [SCENE]\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"僵尸手出没\\\",\\\"display_prompt\\\":\\\"从图片中的场景中钻出一只僵尸的手\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    },\n    {\n        \"display_name\": \"Zombie Mode\",\n        \"workflow_tag\": \"zombie_mode_241028\",\n        \"template_id\": 302325299651648,\n        \"thumbnail_path\": \"https://media.pixverse.ai/asset%2Ftemplate%2Fcapcut_zombiemode.gif\",\n        \"thumbnail_video_path\": \"\",\n        \"marker\": \"hot\",\n        \"created_at\": \"2024-10-24T03:55:29Z\",\n        \"updated_at\": \"2024-12-25T10:19:28Z\",\n        \"display_prompt\": \"The [SUBJECT] suddenly transforms into a zombie.\",\n        \"i18n_json\": \"{\\\"zh-CN\\\":{\\\"display_name\\\":\\\"坏了，我变僵尸了\\\",\\\"display_prompt\\\":\\\"突然变成僵尸\\\"}}\",\n        \"example_list\": \"\",\n        \"qualities\": [\n            \"360p\",\n            \"540p\",\n            \"720p\",\n            \"1080p\"\n        ]\n    }\n]"
  },
  {
    "path": "src/views/luma/pixInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { useMessage,NButton,NInput,NTag,NSelect,NPopover,NSwitch } from 'naive-ui';\nimport { t } from '@/locales';\nimport { mlog, upImg } from '@/api';\nimport { homeStore } from '@/store';\nimport { getRandomInt } from '@/api/runwayml';\nimport { pixFeed, pixFetch } from '@/api/pixverse';\nimport { pixverseTask } from '@/api/pixverseStore';\nimport pixEffacts from \"./pixEffact.json\";\nimport pixCameras from \"./pixCamera.json\";\n\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1',value:'1:1'}\n,{s:'width: 100%; height: 75%;',label:'4:3',value:'4:3'}\n,{s:'width: 75%; height: 100%;',label:'3:4',value:'3:4'}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:'16:9'}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:'9:16'}\n ];\n\n const mvOption= [\n{label:'Verion: V4.5',value: 'v4.5'}\n,{label:'Verion: V4',value: 'v4'}\n ,{label:'Verion: V3.5',value: 'v3.5'}\n// ,{label:'Verion: V3',value: 'v3'}\n// ,{label:'Verion: v2.5',value: 'v2.5'}\n ]\nconst qualityOption= [\n{label:'Quality:  360p Turbo',value: '360p'}\n,{label:'Quality: 540p 1.5X',value: '540p'}\n,{label:'Quality: 720p 2X',value: '720p'}\n,{label:'Quality: 1080p 4X',value: '1080p'}\n ]\n\n const modeOption= [\n{label:t('mj.mode')+': Normal',value: 'normal'}\n,{label:t('mj.mode')+': Performance',value: 'performance'} \n ]\n\n  const styleOption= [\n//{label:'Please select style, can null',value: ''} ,\n{label:'Style: Cyberpunk',value: 'cyberpunk'}\n,{label:'Style: Anime',value: 'anime'} \n,{label:'Style: Comic',value: 'comic'} \n,{label:'Style: Clay',value: 'clay'} \n,{label:'Style: 3D Animation',value: '3d_animation'} \n ]\n \nconst durationOptions=[ {label:t('mj.duration')+':5s',value:5},{label:t('mj.duration')+':8s',value:8}]\n\n\nconst f= ref({pe_index:-1, style:null, prompt:'',quality:'360p',negative_prompt:'',image:'',image_tail:''\n,aspect_ratio:'1:1',model:'v4.5', duration:5,motion_mode:'normal',camera_movement:''});\nconst st= ref({isLoading:false});\nconst fsRef= ref() ; \nconst fsRef2= ref() ; \nconst ms = useMessage();\nconst exItem= ref<pixverseTask>()\nconst clearInput = ()=>{\n    f.value.prompt='';\n    f.value.image= '';\n    f.value.image_tail= '';\n    f.value.style=null\n    fsRef.value=''\n    fsRef2.value='';\n    f.value.pe_index= -1 ; \n    exItem.value= undefined\n    f.value.camera_movement=''\n}\nfunction selectFile(input:any){\n   // fsFile.value= input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        f.value.image= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n}\nfunction selectFile2(input:any){ \n    \n    upImg(input.target.files[0]).then(d=>{\n        f.value.image_tail= d;\n        fsRef2.value=''\n        if(f.value.image==''){\n            ms.info( t('mj.needImg'))\n        }\n    }).catch(e=>ms.error(e));\n}\n\nconst create= async()=>{\n    mlog('createImg', 'asdfdfd')\n    st.value.isLoading= true\n    let  obj={}\n    let objY={\n        \"prompt\": f.value.prompt,\n        \"model\": f.value.model,\n        \"quality\": f.value.quality,\n        \"duration\": f.value.duration,\n        \"aspect_ratio\": f.value.aspect_ratio,\n        \"motion_mode\": f.value.motion_mode,\n        \"seed\":  getRandomInt(648043228, 1648043228)\n    }\n    obj={...objY}\n    if( f.value.image && f.value.image_tail){\n        obj={...objY,'frame':[ f.value.image,f.value.image_tail]}\n    }else if( f.value.image){\n        obj={...objY,'img_url': f.value.image }\n    }\n    if (exItem.value ){\n        obj={...obj,'original_video_id': exItem.value?.video_id, \"extend\": 1,  \"platform\": \"web\"}\n    }\n    if(f.value.style){\n        obj={...obj,style:f.value.style}\n    }\n    if(f.value.pe_index>-1){\n        try {\n            let template_id= pixEffact.value[f.value.pe_index].template_id\n            obj={...obj, template_id}\n        } catch (error) { \n        }\n         \n    }\n    if(f.value.camera_movement ){\n        obj={...obj,camera_movement:f.value.camera_movement} \n    }\n    try {\n        const d:any= await pixFetch('/generate' , obj  )\n        mlog('img', d );\n        if(d.ErrCode==0){ \n            pixFeed(d.Resp.video_id)\n        }\n    } catch (error) {\n        \n    }\n    st.value.isLoading= false\n\n}\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='pix.extend'){\n       mlog(\"pix.extend\", homeStore.myData.actData )\n       exItem.value = homeStore.myData.actData as pixverseTask\n     }\n});\n\nonMounted(() => {\n    homeStore.setMyData({ms:ms}) \n     \n});\n\nconst selecteffect = (i:number)=>{\n    f.value.pe_index= i ; \n    \n    f.value.prompt= pixEffact.value[i].display_prompt\n}\nconst pixEffact= computed(()=>{\n    \n    return pixEffacts;\n});\n\nconst pixCamera = computed(()=>{\n    \n    return pixCameras;\n});\n\n</script>\n<template>\n<div class=\"p-2\">  \n    <div class=\" flex items-center justify-between space-x-1\">\n        <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':f.aspect_ratio==item.value}\"  @click=\"f.aspect_ratio=item.value\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n        </template>\n    </div>\n    <div class=\"pt-1\" >\n      <n-input v-model:value=\"f.prompt\" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </div>\n    <div  class=\"pt-1\">\n       <n-select v-model:value=\"f.model\" :options=\"mvOption\" size=\"small\" />\n    </div>\n     <div  class=\"pt-1\">\n       <n-select v-model:value=\"f.quality\" :options=\"qualityOption\" size=\"small\" />\n    </div>\n     <div  class=\"pt-1\">\n       <n-select v-model:value=\"f.motion_mode\" :options=\"modeOption\" size=\"small\" />\n    </div>\n    <div  class=\"pt-1\">\n       <n-select v-model:value=\"f.duration\" :options=\"durationOptions\" size=\"small\" />\n    </div>\n     <div  class=\"pt-1\">\n       <n-select v-model:value=\"f.style\" :options=\"styleOption\" size=\"small\" clearable  placeholder=\"Please select style\" />\n    </div>\n    <div class=\"pt-2\">\n        <div class=\"flex justify-start  items-end\">\n            <div> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div   class=\"h-[80px] w-[80px]   overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                    <img :src=\"f.image\" v-if=\"f.image\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                    \n                </div>\n            </div>\n            <div class=\"pl-2\"> \n                <input type=\"file\"  @change=\"selectFile2\"  ref=\"fsRef2\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef2.click()\">\n                    <img :src=\"f.image_tail\" v-if=\"f.image_tail\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.endImg') }}</div> \n                </div>\n            </div>\n           \n        </div>\n    </div>  \n\n    <div class=\"pt-2 flex items-end justify-between\">\n         <div>\n            <NPopover trigger=\"hover\">\n                <template #trigger>\n                    <div   class=\"h-[70px] w-[120px]  relative  overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" >\n                        <template v-if=\"f.pe_index>-1\">\n                            <img :src=\"pixEffact[f.pe_index].thumbnail_path\"  />\n                            <div class=\"absolute top-1 right-1 text-white/75 text-[14px]\" >{{pixEffact[f.pe_index].display_name }}</div>\n                        </template>\n                        <div class=\"text-center\" v-else>{{ $t('mj.selecteff') }}</div> \n                    </div>\n                </template>\n                <div class=\"w-[320px] h-[400px] overflow-y-auto overflow-hidden mx-[-4px]\">\n                    <div class=\"grid grid-cols-2 gap-2\">\n                        <div v-for=\"(item, index) in pixEffact\" :key=\"index\" >\n                            <div class=\"relative   overflow-hidden cursor-pointer \" @click=\"selecteffect(index)\">\n                                <!-- <video class=\"h-[72px] w-full rounded-md object-cover\"  :src=\"item.video\"  :poster=\"item.poster\" \n                                 autoplay  loop  playsinline ></video> -->\n                                  <img :src=\"item.thumbnail_path\"  />\n                                <div class=\"absolute top-1 right-1 text-white/75 text-[14px]\" >{{ item.display_name }}</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </NPopover>\n        </div>\n\n        <div>\n            <NPopover trigger=\"hover\">\n                <template #trigger>\n                    <div   class=\"h-[70px] w-[120px]  relative  overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" >\n                        <template v-if=\"f.camera_movement!='' \">\n                            <img :src=\"pixCamera.image[f.camera_movement]\"  />\n                            <div class=\"absolute top-1 right-1 text-white/75 text-[14px]\" >{{ pixCamera.name[f.camera_movement]??f.camera_movement }}</div>\n                        </template>\n                        <div class=\"text-center\" v-else>运镜</div> \n                    </div>\n                </template>\n                <div class=\"w-[320px] h-[400px] overflow-y-auto overflow-hidden mx-[-4px]\">\n                    <div class=\"grid grid-cols-2 gap-2\">\n                         <div v-for=\"(item, index) in pixCamera.image\" :key=\"index\"  @click=\"f.camera_movement=index\" >\n                            <div class=\"relative   overflow-hidden cursor-pointer \"  >\n                                <!-- <video class=\"h-[72px] w-full rounded-md object-cover\"  :src=\"item.video\"  :poster=\"item.poster\" \n                                 autoplay  loop  playsinline ></video> -->\n                                  <img :src=\"item\"  />\n                                <div class=\"absolute bottom-1 right-1 text-white/75 text-[14px]\" >{{ pixCamera.name[index]??index }}</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </NPopover>\n        </div>\n    </div>\n\n    <div v-if=\"exItem && exItem.data\" class=\"pt-2\">\n        <div class=\"flex justify-between items-center\">\n            <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">\n                    {{ $t('video.extend') }}: \n                     <template   v-if=\"exItem.data.prompt\">{{ exItem.data.prompt?exItem.data.prompt:exItem.video_id }}</template>\n                     \n                    </div>\n                    </template>\n                    <div v-if=\"exItem.video_id\" >ID: {{ exItem.video_id }}</div>\n                    <div v-if=\"exItem.data.video_duration\" class=\" justify-between flex\" >\n                        <div>{{ t('mj.duration') }}: {{exItem.data.video_duration}}s</div>\n                        <div>Model: {{ exItem.data.model }}</div>\n                    </div>\n                    <div class=\" justify-between flex\">\n                        <div>{{ t('mj.mode') }}: {{ exItem.data.motion_mode  }}</div>\n                        <div>Quality:  {{ exItem.data.quality  }}</div>\n                    </div>\n                    <div v-if=\"exItem.data.created_at\" >createdAt: {{ new Date( exItem.data.created_at).toLocaleString() }}</div>\n\n                    \n                    \n                </n-popover>\n            </div>\n        </div>\n        <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[5px] overflow-hidden aspect-[16/8.85] \">\n            <video   loop  playsinline  controls  \n                referrerpolicy=\"no-referrer\" :poster=\"exItem.data.first_frame\" \n                class=\"w-full h-full object-cover\"  >\n                <source  :src=\"exItem.data.url\" referrerpolicy=\"no-referrer\" type=\"video/mp4\"  >\n            </video>   \n        </div>\n            \n    </div>\n\n     <section class=\"pt-2 flex justify-between items-end\" >\n        <div class=\"relative\"> \n            <div  class=\" cursor-pointer pb-2\" @click=\"clearInput\"  v-if=\"f.image|| f.prompt || f.image_tail||f.camera_movement\"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n        </div>\n        <div class=\"text-right\">\n\n            <NButton :loading=\"st.isLoading\" type=\"primary\" @click=\"create()\" :disabled=\"!f.prompt\"  >{{$t('video.generate')}}</NButton>\n        </div>\n    </section>\n\n    \n    <div class=\"pt-2 text-[12px]\" v-html=\"$t('mj.pixinfo')\"></div>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/pixList.vue",
    "content": "<script setup lang=\"ts\">\nimport { pixverseStore,pixverseTask } from '@/api/pixverseStore';\nimport { homeStore } from '@/store';\nimport { ref, watch } from 'vue';\nimport {NEmpty ,NButton,NPopover, NButtonGroup, useMessage,NPopconfirm} from \"naive-ui\"\nimport { pixFeed } from '@/api/pixverse';\nimport { t } from '@/locales';\nimport {SvgIcon} from '@/components/common'\nimport { mlog } from '@/api';\n\n\n\nconst ms= useMessage()\nconst st= ref({pIndex:-1});\nconst list= ref<pixverseTask[]>([]);\nconst csuno= new pixverseStore()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\n\nconst deleteGo=(item:pixverseTask)=>{\n    //..mlog('deleteGo',item )\n    if( csuno.delete( item.video_id)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\nconst extend2=  (item:pixverseTask )=>{ \n    \n    mlog(\"extend \", item )  \n    homeStore.setMyData({act:\"pix.extend\", actData: item  })\n}\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='PixFeed')  initLoad() \n});\ninitLoad()\n</script>\n\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n        <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                <template  v-if=\"item.data && item.data.video_status==1  \"> \n                   <video :src=\" item.data.url\"  :poster=\"item.data.first_frame\" loop  playsinline  :controls=\"st.pIndex==index\" class=\"w-full h-full object-cover\"></video>\n                </template>\n                <div class=\" text-center\" v-else>\n                    <div v-if=\"!item.data || item.data.video_status==100\"   >\n                        {{ $t('video.failed') }}\n                        <!-- <div v-text=\"item.failure\"  class=\"p-2\"></div> -->\n                    </div> \n                    <NButton  size=\"small\" type=\"primary\" @click=\"pixFeed( item.video_id )\"   v-else-if=\"!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000\" >{{$t('video.repeat')}}</NButton>\n                    <div class=\"pt-2\" v-else>\n                        <div>{{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}</div>\n                        <div  >Status: {{ item.data.video_status }}</div> \n                    </div>\n                   \n                </div>\n                \n             </div>\n\n             <div class=\"flex justify-between items-center\">\n                <div  >\n                <n-popover trigger=\"hover\" v-if=\"item.data\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">{{item.data.prompt}}</div>\n                    </template>\n                    <div v-if=\"item.video_id\" >ID: {{ item.video_id }}</div>\n                    <div v-if=\"item.data.video_duration\" class=\" justify-between flex\" >\n                        <div>{{ t('mj.duration') }}: {{item.data.video_duration}}s</div>\n                        <div>Model: {{ item.data.model }}</div>\n                    </div>\n                    <div class=\" justify-between flex\">\n                        <div>{{ t('mj.mode') }}: {{ item.data.motion_mode  }}</div>\n                        <div>Quality:  {{ item.data.quality  }}</div>\n                    </div>\n                    <div v-if=\"item.data.created_at\" >createdAt: {{ new Date( item.data.created_at).toLocaleString() }}</div>\n\n                    <div class=\" max-w-[400px]\">{{ t('mjchat.prompt') }}: {{item.data.prompt}}</div>  \n                </n-popover>\n                \n                </div>\n                <div class=\"flex justify-end items-center pt-1\"   v-if=\"item.data \" > \n                        \n                        \n                      <n-button-group size=\"tiny\">\n                        <n-button  size=\"tiny\" round ghost   v-if=\"item.data.video_status==1\" ><a :href=\"item.data.url\" target=\"_blank\" class=\"flex\"><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }} </a></n-button>\n                        <n-button   size=\"tiny\"  round ghost    > \n                             <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <div class=\" cursor-pointer\"><SvgIcon icon=\"mdi:delete\"  /></div></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </n-button>  \n                        <n-button   size=\"tiny\"  round ghost  @click=\"extend2( item )\"  ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button>\n                      </n-button-group>\n                \n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/runInput.vue",
    "content": "<script lang=\"ts\" setup>\nimport { NTabs, NTabPane } from 'naive-ui';\n\nimport RunwayInput from './runwayInput.vue'\nimport RunmlInput from './runmlInput.vue'\nimport { gptServerStore } from '@/store';\nimport { mlog } from '@/api';\nimport { ref } from 'vue'; \n\nconst st= ref({tab:'runway'});\nconst handleUpdateValue=(v:string)=>{\n   mlog(\"handleUpdateValue\",v)\n   gptServerStore.setMyData({TAB_VIDEO:v})\n}\nconst initLoad=()=>{\n    st.value.tab='runway'\n    if( gptServerStore.myData.TAB_VIDEO=='runwayml'){\n         st.value.tab='runwayml'\n    }\n}\n\ninitLoad();\n\n\n</script>\n<template>\n<div class=\"px-2\">\n    <n-tabs type=\"segment\"  animated :default-value=\"st.tab\"  @update:value=\"handleUpdateValue\">\n        <n-tab-pane name=\"runway\" tab=\"Website\">\n            <RunwayInput/>\n        </n-tab-pane>\n        <n-tab-pane name=\"runwayml\" tab=\"API\">\n            <RunmlInput/>\n        </n-tab-pane>\n    </n-tabs> \n</div>\n</template>"
  },
  {
    "path": "src/views/luma/runmlInput.vue",
    "content": "<script setup lang=\"ts\">\nimport {useMessage, NButton,NInput,NTag,NRadioGroup,NRadioButton,NSelect} from 'naive-ui';\n \nimport { getRandomInt, runwayMlFeed, runwayMlFeedById, runwayMlFetch } from '@/api/runwayml';\nimport { computed, onMounted, ref } from 'vue';\nimport { mlog, upImg } from '@/api';\nimport { homeStore } from '@/store';\nimport { t } from '@/locales';\n\n \nconst ms = useMessage();\nconst f= ref({\n    \"promptImage\": [\n       {\"uri\":\"\",\"position\":\"last\"}\n    ],\n    \"seed\": 4294967295,\n    \"model\": \"gen4_turbo\",\n    \"promptText\": \"\",\n    \"watermark\": false,\n    \"duration\": 5,\n    \"ratio\": \"1280:768\"\n  }\n);\nconst luma=ref({image_url:'',image_end_url:''});\nconst st= ref({isLoading:false })\nconst vf=[ \n{s:'width: 100%; height: 50%;',label: t('mj.rml_heng'),value:'1280:768'}\n,{s:'width: 50%; height: 100%;',label:t('mj.rml_shu'),value:'768:1280'}\n ];\n const vf2=[{s:'width: 100%; height: 100%;',label:'1:1',value:'960:960'}\n,{s:'width: 100%; height: 75%;',label:'4:3',value:'1104:832'}\n,{s:'width: 75%; height: 100%;',label:'3:4',value:'832:1104'}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:'1280:720'}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:'720:1280'}\n,{s:'width: 100%; height: 30%;',label:'21:9',value:'1584:672'}\n ];\n const duanConfig=[\n{key:5,value: '5s'},\n{key:10,value:'10s'}\n]\n\nconst fsRef= ref() ;\nconst fsRef2 = ref() ;\n\nfunction selectFile(input:any){\n     \n    upImg(input.target.files[0]).then(d=>{\n        luma.value.image_url= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n    \n}\n\nfunction selectFile2(input:any){\n    upImg(input.target.files[0]).then(d=>{\n        luma.value.image_end_url= d;\n        fsRef2.value=''\n    }).catch(e=>ms.error(e));\n    \n}\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n    \n});\nconst clearInput = ()=>{\n    f.value.promptImage=[];\n    f.value.promptText= '';\n    luma.value.image_end_url= '';\n    luma.value.image_url= '';\n    fsRef.value=''\n    fsRef2.value=''\n}\nconst canPost= computed(()=>{\n    return f.value.promptText && luma.value.image_url\n});\n\nconst create= async ()=>{ \n    f.value.promptImage=[];\n    f.value.promptImage.push({uri:luma.value.image_url,\"position\":\"first\"});\n    if(luma.value.image_end_url ) f.value.promptImage.push({uri:luma.value.image_end_url,\"position\":\"last\"});\n    f.value.seed= getRandomInt(1375247627, 3975247627);\n    st.value.isLoading=true\n    //mlog('create', f.value  )\n    try {\n         let d:any= await runwayMlFetch('/v1/image_to_video', f.value)\n         runwayMlFeed(d.id ,{model:'gen3a_turbo',promptText:f.value.promptText })\n    } catch (error) {\n        \n    }\n    st.value.isLoading=false \n}\nconst mvOption= [\n{label: 'Model : gen4_turbo',value: 'gen4_turbo'}\n// ,{label:t('video.rwgen3'),value: 'europa'}\n// ,{label:t('video.rwgen3fast'),value: 'europa-fast'}\n,{label:'Model : gen3a_turbo',value: 'gen3a_turbo'}\n ]\n</script>\n<template> \n<div>\n    <section class=\"mb-2 flex justify-between items-center\" >\n            <n-select v-model:value=\"f.model\" :options=\"mvOption\" size=\"small\" />\n    </section>\n    <section class=\"mb-2\">\n         <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf2\"  v-if=\"f.model=='gen4_turbo'\">\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':item.value==f.ratio}\"  @click=\" f.ratio=item.value \">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n            <template  v-for=\"(item,index) in vf\"  v-else>\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':item.value==f.ratio}\"  @click=\" f.ratio=item.value \">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n\n        </div>\n    </section>\n    <section class=\"mb-2 flex justify-between items-center\" >\n         \n          <n-input v-model:value=\"f.promptText \" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </section>\n   \n    <section class=\"mb-2\">\n        <div class=\"flex justify-start  items-top\">\n            <div> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                    <img :src=\"luma.image_url\" v-if=\"luma.image_url\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                </div>\n            </div>\n            <div class=\"pl-2\"> \n                <input type=\"file\"  @change=\"selectFile2\"  ref=\"fsRef2\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n                <div class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef2.click()\">\n                    <img :src=\"luma.image_end_url\" v-if=\"luma.image_end_url\" />\n                    <div class=\"text-center\" v-else>{{ $t('video.endImg') }}</div> \n                </div>\n            </div>\n            <div class=\"pl-2\">\n                <n-radio-group v-model:value=\"f.duration\" name=\"radiobuttongroup1\" size=\"small\">\n                    <n-radio-button   v-for=\"song in duanConfig\"  :key=\"song.key\" :value=\"song.key\" :label=\"song.value\"> </n-radio-button>  \n                </n-radio-group>\n            </div>\n           \n        </div>\n    </section>  \n    <section class=\"mb-4 flex justify-between items-end\" >\n        <div class=\"relative\"> \n            <div  class=\" cursor-pointer pb-2\" @click=\"clearInput\"  v-if=\"luma.image_end_url|| luma.image_url || f.promptText\"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n        </div>\n        <div class=\"text-right\">\n\n            <NButton :loading=\"st.isLoading\" type=\"primary\" @click=\"create()\"  :disabled=\"!canPost\"  >{{$t('video.generate')}}</NButton>\n        </div>\n    </section>\n\n       <div v-html=\"t('mj.rml_info')\"  class=\"mb-4  text-[12px]\"></div>\n\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/runmlList.vue",
    "content": "<script setup lang=\"ts\">\nimport {NEmpty, useMessage,NPopover,NPopconfirm,NButton,NButtonGroup  } from 'naive-ui'\nimport { RunwayMlStore, RunwayMlTask } from '@/api/runwaymlStore';\nimport { ref, watch } from 'vue';\nimport {runwayMlFeedById} from \"@/api/runwayml\"\nimport { t } from '@/locales';\nimport {SvgIcon} from '@/components/common'\nimport { homeStore } from '@/store';\n\n\n//runwayml.feed\nconst ms= useMessage()\nconst st= ref({pIndex:-1});\nconst list= ref<RunwayMlTask[]>([]);\nconst csuno= new RunwayMlStore()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\n\nconst deleteGo=(item:RunwayMlTask)=>{\n    //..mlog('deleteGo',item )\n    if( csuno.delete( item)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\n \nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='runwayml.feed')  initLoad() \n});\n\ninitLoad();\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n    <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                <template  v-if=\"item.status=='SUCCEEDED' && item.output && item.output.length>0 \"> \n                   <video :src=\"item.output[0]\"  loop  playsinline  :controls=\"st.pIndex==index\" class=\"w-full h-full object-cover\"></video>\n                </template>\n                <div class=\" text-center\" v-else>\n                    <div v-if=\"item.status=='FAILED'\"   >\n                        {{ $t('video.failed') }}\n                        <div v-text=\"item.failure\"  class=\"p-2\"></div>\n                    </div> \n                    <NButton  size=\"small\" type=\"primary\" @click=\"runwayMlFeedById( item.id )\"   v-else-if=\"!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000\" >{{$t('video.repeat')}}</NButton>\n                    <div class=\"pt-2\" v-else>\n                        <div>{{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}</div>\n                        <div  >Status: {{ item.status }}</div> \n                        <!-- <div v-if=\"item.state=='processing'\">{{ $t('video.processing') }}</div>  -->\n\n                    </div>\n                   \n                </div>\n                \n             </div>\n\n             <div class=\"flex justify-between items-center\">\n                <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">{{item.promptText}}</div>\n                    </template>\n                    <div v-if=\"item.id\" >ID: {{ item.id }}</div>\n                    <div v-if=\"item.createdAt\" >createdAt: {{ new Date( item.createdAt).toLocaleString() }}</div>\n\n                    <div class=\" max-w-[300px]\">{{item.promptText}}</div>\n                </n-popover>\n                \n                </div>\n                <div class=\"flex justify-end items-center pt-1\"   v-if=\"item.status=='SUCCEEDED' || item.status=='FAILED' \" > \n                        \n                        \n                      <n-button-group size=\"tiny\">\n                        <n-button  size=\"tiny\" round ghost   v-if=\"item.status=='SUCCEEDED'\" ><a :href=\"item.output[0]\" target=\"_blank\" class=\"flex\"><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }} </a></n-button>\n                        <n-button   size=\"tiny\"  round ghost    > \n                             <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <div class=\" cursor-pointer\"><SvgIcon icon=\"mdi:delete\"  /></div></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </n-button>  \n                        <!-- <n-button   size=\"tiny\"  round ghost  @click=\"extend( item )\"  ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button> -->\n                      </n-button-group>\n                     <!-- <a :href=\"item.video?.download_url? item.video?.download_url:item.video?.url\" download  target=\"_blank\" v-if=\"item.video?.url|| item.video?.download_url\"  ><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a> -->\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/runwayInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog, upImg } from '@/api';\nimport { runwayFeed, runwayFetch, runwayUpload } from '@/api/runway';\nimport { gptServerStore, homeStore } from '@/store';\nimport { useMessage,NInput,NButton, NTag,NSelect,NPopover,NSwitch } from 'naive-ui';\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { SvgIcon } from '@/components/common';\nimport { t } from '@/locales'; \nimport { RunwayTask } from '@/api/runwayStore';\n\nconst fsRef= ref() ;\nconst runway= ref<{image_prompt?:string,seed:number,text_prompt:string}>({image_prompt:'',seed:1675247627,text_prompt:''});\nconst st= ref({isDo:false,uploading:false, version:'gen2',time:5,image_as_end_frame:false});\nconst ms = useMessage();\nconst exRunway= ref<RunwayTask>()\nasync function  selectFile(input:any){\n    mlog(\"selectFile\", input.target.files[0])\n    const file = input.target.files[0]  \n\n    st.value.uploading= true\n    try{\n    let d= await runwayUpload( file,'DATASET_PREVIEW')\n    mlog(\"runwayFetch\",d)\n    runway.value.image_prompt= d.url\n    }catch(e :any){\n       ms.error(e )\n    }\n     st.value.uploading= false\n    \n}\nfunction getRandomInt(min: number, max: number): number {\n    min = Math.ceil(min);\n    max = Math.floor(max);\n    return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nconst canPost = computed(() => {\n    return (runway.value.image_prompt!='' || runway.value.text_prompt!='' ) && !st.value.isDo\n})\n\nconst generate= async ()=>{\n    st.value.isDo= true\n    //runway.value.seed= getRandomInt(1675247627, 3275247627)\n    let seed= getRandomInt(1375247627, 3975247627);\n    try{\n        let obj={\n            \"taskType\": \"gen2\",\n            \"internal\": false,\n            \"options\": {\n                \"name\": `Gen-2 ${seed}`,\n                \"seconds\": 4,\n                \"gen2Options\": {\n                \"mode\": \"gen2\",\n                \"seed\": seed,\n                \"interpolate\": true,\n                \"upscale\": false,\n                \"watermark\": true,\n                \"motion_score\": 22,\n                \"use_motion_score\": true,\n                \"use_motion_vectors\": false,\n                \"text_prompt\":  runway.value.text_prompt,\n                \"image_prompt\": runway.value.image_prompt, \n                \"init_image\": runway.value.image_prompt\n                },\n                \"exploreMode\": false,\n                \"assetGroupName\": \"Generative Video\"\n            },\n           // \"asTeamId\": 17485144\n        }\n\n//         {\n//   \"name\": \"Gen-3 Alpha 2584627205, 笑起来, Cropped - cqkrcrc8j3\",\n//   \"seconds\": 5,\n//   \"text_prompt\": \"笑起来\",\n//   \"seed\": 2584627205,\n//   \"exploreMode\": true,\n//   \"watermark\": false,\n//   \"enhance_prompt\": true,\n//   \"init_image\": \"https://d2jqrm6oza8nb6.cloudfront.net/previews/21fb66fc-c9d0-4c92-863d-623b77ab742b.webp?_jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXlIYXNoIjoiNjI5MzQ4YTc0ODIwYWZiMiIsImJ1Y2tldCI6InJ1bndheS1kYXRhc2V0cyIsInN0YWdlIjoicHJvZCIsImV4cCI6MTcyMjY0MzIwMH0.x5f94vMk6Yt4dQTw4ueBnWOJ1EFRqOAp_vaLUcT5bs0\",\n//   \"resolution\": \"720p\",\n//   \"assetGroupName\": \"Generative Video\"\n// }\n        let gen3= {\n                \"taskType\": \"europa\",\n                \"internal\": false,\n                \"options\": {\n                    \"name\": `Gen-3 Alpha  ${seed}`,\n                    \"seconds\": st.value.time,\n                    \"text_prompt\":runway.value.text_prompt,\n                    \"seed\":seed,\n                    \"exploreMode\": true,\n                    \"watermark\": false,\n                    \"enhance_prompt\": true,\n                    \"width\": 1280,\n                    \"height\": 768,\n                    \"image_as_end_frame\": false,\n                    \"assetGroupName\": \"Generative Video\",\n                    \"init_image\": runway.value.image_prompt,\n                    \"resolution\": '720p'// runway.value.image_prompt,\n                    ,\"extended_from_task_id\":(exRunway.value&&exRunway.value.id)?exRunway.value.id:undefined\n                    ,\"init_video\": ( exRunway.value && exRunway.value.artifacts && exRunway.value.artifacts[0].url)?exRunway.value.artifacts[0].url:undefined\n                },\n            //    \"asTeamId\": 17511575\n        }\n        let gen3_trubo=    {\n                \"taskType\": \"gen3a_turbo\",\n                \"internal\": false,\n                \"options\": {\n                    \"name\": `Gen-3 Alpha Turbo ${seed}`,\n                    \"seconds\":st.value.time,\n                    \"text_prompt\": runway.value.text_prompt ,\n                    \"seed\": seed,\n                    \"exploreMode\": false,\n                    \"watermark\": false,\n                    \"enhance_prompt\": true,\n                    \"init_image\":  runway.value.image_prompt,\n                    \"resolution\": \"720p\",\n                    \"image_as_end_frame\": false,\n                    \"assetGroupName\": \"Generative Video\"\n                   ,\"extended_from_task_id\":(exRunway.value&&exRunway.value.id)?exRunway.value.id:undefined\n                    ,\"init_video\": ( exRunway.value && exRunway.value.artifacts && exRunway.value.artifacts[0].url)?exRunway.value.artifacts[0].url:undefined\n                }\n        }\n        let v_gen3={\n            \"taskType\": \"europa\",\n            \"internal\": false,\n            \"options\": {\n                \"name\": `Gen-3 Alpha  ${seed}`,\n                \"seconds\": st.value.time,\n                \"text_prompt\":runway.value.text_prompt,\n                \"seed\":seed,\n                \"exploreMode\": true,\n                \"watermark\": false,\n                \"enhance_prompt\": true,\n                \"video_prompt\":  runway.value.image_prompt ,\n                \"structure_transformation\": 0.3,\n                \"width\": 1280,\n                \"height\": 768,\n                \"assetGroupName\": \"Generative Video\"\n            }\n        }\n  \n\n        if( obj.options.gen2Options.image_prompt==''){\n            delete obj.options.gen2Options.image_prompt;\n            delete obj.options.gen2Options.init_image;\n        }\n        if( gen3.options.init_image=='' ){\n            delete gen3.options.init_image;\n            delete gen3_trubo.options.init_image;\n        }\n        if( !gen3.options.init_video  ){\n            delete gen3.options.init_video;\n            delete gen3_trubo.options.init_video;\n        }\n        if( !gen3.options.extended_from_task_id  ){\n            delete gen3.options.extended_from_task_id;\n            delete gen3_trubo.options.extended_from_task_id;\n        }\n        gen3.options.image_as_end_frame=st.value.image_as_end_frame\n        gen3_trubo.options.image_as_end_frame=st.value.image_as_end_frame\n        \n        gen3.options.exploreMode= st.value.version=='europa'\n        v_gen3.options.exploreMode= st.value.version=='europa'\n        let sobj:any = gen3;\n        if(  st.value.version=='gen2' ){\n            sobj= obj\n        }\n        if(  st.value.version=='gen3a_turbo' ){\n            sobj= gen3_trubo\n            if(gen3_trubo.options.init_image=='') {\n                ms.error( t('video.gen3a_turbo_img') )\n                return \n            }\n        }\n        if(runway.value.image_prompt && isMp4(runway.value.image_prompt)){\n            if( st.value.version=='gen2'){\n                ms.error( 'gen2 不支持视频' )\n                return \n            }\n            v_gen3.taskType='europa'\n            if( st.value.version=='gen3a_turbo' ){\n                v_gen3.taskType='gen3a_turbo'\n            }\n            sobj= v_gen3\n        }\n       // const d=  await runwayFetch('/tasks', st.value.version=='gen2'?obj: gen3 ) \n        const d=  await runwayFetch('/tasks',  sobj ) \n        mlog(\"runwayGen2\",d) \n        d.task && d.task.id&& runwayFeed(d.task.id)\n    }catch(e:any){\n        ms.error(e)\n    }\n    st.value.isDo=false\n\n}\nconst isMp4=(url:string)=>{\n    return url.indexOf('.mp4')>0\n}\n\nconst mvOption= [\n{label: t('video.rwgen2'),value: 'gen2'}\n,{label:t('video.rwgen3'),value: 'europa'}\n,{label:t('video.rwgen3fast'),value: 'europa-fast'}\n,{label:t('video.rwgen3turbo'),value: 'gen3a_turbo'}\n ]\n const timeOption= [\n{label: 'Duration: 5s',value: 5}\n,{label:'Duration: 10s',value: 10}\n ]\n\n \n\nconst clearInput=()=>{\n    runway.value.image_prompt ='' \n    runway.value.text_prompt =''\n    exRunway.value= undefined\n}\nwatch(()=>st.value.version,(n:string)=>{\n    gptServerStore.setMyData({RRUNWAY_VERSION:n})\n})\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n    st.value.version= gptServerStore.myData.RRUNWAY_VERSION?gptServerStore.myData.RRUNWAY_VERSION: 'gen2'\n});\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='runway.extend'){\n       mlog(\"runway.extend\", homeStore.myData.actData )\n       exRunway.value = homeStore.myData.actData as RunwayTask\n     }\n});\n</script>\n<template>\n<div > \n    <div  class=\"pt-1\"  >\n        <n-select v-model:value=\"st.version\" :options=\"mvOption\" size=\"small\" />\n    </div>\n    <div class=\"pt-1\">\n      <n-input v-model:value=\"runway.text_prompt\" \n                :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </div>\n\n    <div v-if=\"exRunway\" class=\"pt-1\">\n        <div class=\"flex justify-between items-center\">\n            <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">\n                    {{ $t('video.extend') }}: \n                     <template   v-if=\"exRunway.options.text_prompt\">{{ exRunway.options.text_prompt }}</template>\n                     <template v-else  >{{ exRunway.options.gen2Options?.text_prompt?exRunway.options.gen2Options.text_prompt: exRunway.name }}</template>\n                    </div>\n                    </template>\n                    <div class=\" max-w-[300px]\">{{exRunway.id}}</div>\n                    \n                    <div v-if=\"exRunway.taskType=='gen3a'\" >Version: Gen-3</div>\n                    <div v-if=\"exRunway.taskType=='gen3a_turbo'\" >Version: Gen-3-turbo</div>\n                    <div v-if=\"exRunway.taskType=='gen2'\" >Version: Gen-2</div>\n                    <div v-if=\"exRunway.createdAt\" >createdAt: {{ new Date( exRunway.createdAt).toLocaleString() }}</div>\n                    <div class=\" max-w-[300px]\" v-if=\"exRunway.options.text_prompt\">{{ exRunway.options.text_prompt }}</div>\n                    <div class=\" max-w-[300px]\">{{ exRunway.options.gen2Options?.text_prompt?exRunway.options.gen2Options.text_prompt: exRunway.name }}</div>\n                \n                </n-popover>\n            </div>\n        </div>\n        <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[5px] overflow-hidden aspect-[16/8.85] \">\n            <video   loop  playsinline  controls v-if=\"exRunway.artifacts && exRunway.artifacts[0].url\"\n                referrerpolicy=\"no-referrer\" :poster=\"exRunway.artifacts[0].previewUrls[0]\" \n                class=\"w-full h-full object-cover\"  >\n                <source  :src=\"exRunway.artifacts[0].url\" referrerpolicy=\"no-referrer\" type=\"video/mp4\"  >\n            </video>   \n        </div>\n            \n    </div>\n\n    <div  class=\"pt-1\" v-if=\"st.version!='gen2'\" >\n        <n-select v-model:value=\"st.time\" :options=\"timeOption\" size=\"small\" />\n    </div>\n\n\n\n    <div class=\"pt-1\">\n        <div class=\"flex justify-between  items-end\">\n            <div class=\" relative\"> \n                <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif, .mp4\"/>\n                \n                <!-- <div v-if=\"st.version=='europa'\"\n                 class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center\"\n                >\n                 {{ $t('video.nosup') }} \n                </div> -->\n                <div   class=\"h-[80px] w-[80px] overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                  \n                   \n                    <SvgIcon icon=\"line-md:uploading-loop\" class=\"text-[60px] text-green-300\"  v-if=\"st.uploading\"  ></SvgIcon>\n                    <!-- <video :src=\"runway.image_prompt\" v-else-if=\"runway.image_prompt && isMp4(runway.image_prompt)\" /> -->\n                    <video   loop  playsinline    v-else-if=\"runway.image_prompt && isMp4(runway.image_prompt)\"\n                        referrerpolicy=\"no-referrer\" \n                        class=\"w-full h-full object-cover\"  >\n                        <source  :src=\"runway.image_prompt\" referrerpolicy=\"no-referrer\" type=\"video/mp4\"  >\n                    </video>  \n                    <img :src=\"runway.image_prompt\" v-else-if=\"runway.image_prompt\" />\n                    <div class=\"text-center\"  v-else >{{ $t('video.selectimg') }}</div> \n                   \n                </div>\n\n                <div class=\" absolute bottom-[-5px] right-[-15px]\" v-if=\"runway.image_prompt&&st.version!='gen2' \">\n                     <a :href=\"runway.image_prompt\" class=\"cursor-pointer\" target=\"_blank\" v-if=\"isMp4(runway.image_prompt) \">\n                      <NTag  type=\"success\" size=\"small\"  class=\"cursor-pointer\" round :bordered=\"false\">Vidoe</NTag>\n                     </a>\n                     <NSwitch v-model:value=\"st.image_as_end_frame\" size=\"small\" v-else>\n                        <template #checked>尾帧</template> \n                        <template #unchecked>首帧</template>\n                    </NSwitch>\n                   \n                </div>\n            </div>\n            <div class=\"text-right \">\n                <div class=\"pb-1 flex justify-between items-center\">\n                    \n                       \n                     \n                        <NTag v-if=\"runway.text_prompt!='' || runway.image_prompt!='' || exRunway\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"clearInput()\" >{{$t('video.clear')}}</span></NTag>\n                     \n                </div>\n                <NButton  :loading=\"st.isDo\" type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\"><SvgIcon icon=\"ri:video-add-line\"  /> {{$t('video.generate')}}</NButton> \n            </div>\n        </div>\n    </div>\n\n    <div class=\"pt-2 text-[12px]\" v-html=\"$t('video.runwayinfo')\">\n        \n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/runwayList.vue",
    "content": "<script setup lang=\"ts\">\nimport { RunwayTask, runwayStore } from '@/api/runwayStore';\nimport { ref, watch } from 'vue';\nimport {NEmpty ,NButton,NPopover, NButtonGroup, useMessage,NPopconfirm} from \"naive-ui\"\nimport {runwayFeed} from \"@/api/runway\"\nimport { mlog } from '@/api';\nimport { homeStore } from '@/store';\nimport {SvgIcon} from '@/components/common'\nimport { t } from '@/locales';\n\nconst ms= useMessage();\nconst mapRef = ref(new Map<string, number>());\n\nconst st= ref({pIndex:-1});\nconst list= ref<RunwayTask[]>([]);\nconst csuno= new runwayStore()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\nconst RunwayTaskDown=(item:RunwayTask)=>{\n    mlog(\"RunwayTaskDown\", item)\n    if(  !item.artifacts ||  item.artifacts.length==0 ) return;\n\n    const link = document.createElement('a');\n\n    link.href = item.artifacts[0].url ;\n    link.download = item.id+\".mp4\";\n    link.target = '_blank';\n    link.rel='noreferrer'\n    document.body.appendChild(link);\n    link.click();\n    document.body.removeChild(link);\n}\n\nconst extend=  (item:RunwayTask )=>{\n    mlog(\"extend \", item ) \n    homeStore.setMyData({act:\"runway.extend\", actData: item  })\n}\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='RunwayFeed')  initLoad() \n});\n\nconst videoError=(item:RunwayTask, index:number)=>{\n    //if(  st.value.pIndex!=index ) return;\n    mlog(\"videoError\", index , item)\n    //item.artifacts[0].url= item.artifacts[0].previewUrls[0]\n    mapRef.value.set(item.id, index+1 )\n};\n\nconst reRunwayFeed= async(id:string)=>{ \n    await runwayFeed(id)\n    mapRef.value.delete( id)\n}\n\nconst deleteGo=(item:RunwayTask)=>{\n    mlog('deleteGo',item )\n    if( csuno.delete( item)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\n\ninitLoad();\n\n\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n    <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                \n                <template  v-if=\"item.artifacts && item.artifacts.length>0  && item.artifacts[0].url\">\n                    <div v-if=\"mapRef.has(item.id)   \">\n                        <NButton  size=\"small\" type=\"primary\" @click=\"reRunwayFeed( item.id )\"   >{{$t('video.repeat2')}}</NButton>\n                    </div>\n                    <video v-else  loop  playsinline  :controls=\"st.pIndex==index\"\n                    referrerpolicy=\"no-referrer\" :poster=\"item.artifacts[0].previewUrls[0]\" \n                    class=\"w-full h-full object-cover\" @error=\"videoError(item, index)\"  >\n                        <source  :src=\"item.artifacts[0].url\" referrerpolicy=\"no-referrer\" type=\"video/mp4\" v-if=\"st.pIndex==index\">\n                    </video>\n                </template>\n                <div class=\" text-center\" v-else>\n                    <div v-if=\"item.status=='FAILED'\" class=\"pt-2\" >\n                        <div>{{ $t('video.failed') }}</div>\n                    <div class=\"line-clamp-3\" >{{ item.progressText }}</div>\n                    </div> \n                    <NButton  size=\"small\" type=\"primary\" @click=\"runwayFeed( item.id )\"   v-else-if=\"!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000\" >{{$t('video.repeat')}}</NButton>\n                    <div class=\"pt-2\" v-else>\n                        <div>\n                        {{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}\n                        </div>\n                        <div v-if=\"item.progressRatio\">{{  (parseFloat(item.progressRatio)*100).toFixed(0) }}%</div> \n                        <div v-else-if=\"item.estimatedTimeToStartSeconds && item.estimatedTimeToStartSeconds>0\">{{ item.estimatedTimeToStartSeconds.toFixed(1) }}秒后开始执行</div>\n                        <!-- estimatedTimeToStartSeconds -->\n                        <!-- <div v-if=\"item.estimatedTimeToStartSeconds && item.estimatedTimeToStartSeconds>0\">{{ item.estimatedTimeToStartSeconds.toFixed(1) }}s 开始执行</div> -->\n                        <!-- <div v-if=\"item.state=='processing'\">{{ $t('video.processing') }}</div>  -->\n\n                    </div>\n                   \n                </div>\n            </div>\n            <div class=\"flex justify-between items-center\">\n                <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">\n                     <template   v-if=\"item.options.text_prompt\">{{ item.options.text_prompt }}</template>\n                     <template v-else  >{{ item.options.gen2Options?.text_prompt?item.options.gen2Options.text_prompt: item.name }}</template>\n               \n                    </div>\n                    </template>\n                    <div v-if=\"item.id\" >ID: {{ item.id }}</div>\n                    <div v-if=\"item.taskType=='gen3a'\" >Version: Gen-3</div>\n                    <div v-if=\"item.taskType=='gen3a_turbo'\" >Version: Gen-3-turbo</div>\n                    <div v-if=\"item.taskType=='gen2'\" >Version: Gen-2</div>\n                    <div v-if=\"item.createdAt\" >createdAt: {{ new Date( item.createdAt).toLocaleString() }}</div>\n                    <div class=\" max-w-[300px]\" v-if=\"item.options.text_prompt\">{{ item.options.text_prompt }}</div>\n                    <div class=\" max-w-[300px]\">{{ item.options.gen2Options?.text_prompt?item.options.gen2Options.text_prompt: item.name }}</div>\n                </n-popover>\n                \n                </div>\n                <div class=\"flex justify-end items-center pt-1\"  v-if=\"item.artifacts && item.artifacts.length>0  && item.artifacts[0].url\"> \n                     <!-- <span    @click=\"FeedLumaTaskDown( item.id )\" class=\"cursor-pointer\" ><SvgIcon icon=\"mdi:download\" /></span> -->\n\n                    \n                      <n-button-group size=\"tiny\">\n                        <n-button  size=\"tiny\" round ghost   @click=\"RunwayTaskDown( item )\"  ><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }}</n-button>\n                        <n-button   size=\"tiny\"  round ghost    > \n                            <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </n-button>\n                        <n-button   size=\"tiny\"  round ghost  @click=\"extend( item )\"  ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button>\n                        <!-- <n-button  size=\"tiny\" round ghost   @click=\"RunwayTaskDown( item )\"  ><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }}</n-button> -->\n                        \n                      </n-button-group>\n                     <!-- <a :href=\"item.video?.download_url? item.video?.download_url:item.video?.url\" download  target=\"_blank\" v-if=\"item.video?.url|| item.video?.download_url\"  ><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a> -->\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/luma/video.vue",
    "content": " <script setup lang=\"ts\">\n import VoInput from './voInput.vue';\n //import VoInput from './lumaInput.vue';\n import VoList from './voList.vue';\n import RunwayList from './runwayList.vue';\n import PikaList from './pikaList.vue';\n import KlingList from '../kling/kgList.vue';\n import RunmlList from './runmlList.vue';\n import PixList from './pixList.vue';\n import VideoList from '../video/list.vue';\nimport { gptServerStore } from '@/store';\n </script>\n<template>\n\n<div class=\"flex w-full h-full   \">\n    <div class=\"w-[300px] h-full  overflow-y-auto \">\n         <VoInput/>\n    </div>\n    <div class=\" flex-1  h-full bg-[#fafbfc] pt-2 dark:bg-[#18181c] overflow-y-auto \" >\n\n        <RunwayList v-if=\"gptServerStore.myData.TAB_VIDEO=='runway'\"/>\n        <KlingList v-else-if=\"gptServerStore.myData.TAB_VIDEO=='kling'\"/>\n        <PikaList v-else-if=\"gptServerStore.myData.TAB_VIDEO=='pika'\"/>\n        <RunmlList v-else-if=\"gptServerStore.myData.TAB_VIDEO=='runwayml'\"/>\n        <PixList v-else-if=\"gptServerStore.myData.TAB_VIDEO=='pixverse'\"/>\n        <VideoList v-else-if=\"gptServerStore.myData.TAB_VIDEO=='all'\"/>\n        <VoList v-else/>\n    </div>\n     \n</div>\n</template> "
  },
  {
    "path": "src/views/luma/voInput.vue",
    "content": "<script setup lang=\"ts\"> \nimport { NTabs, NTabPane } from 'naive-ui';\nimport LumaInput from './lumaInput.vue'\nimport RunwayInput from './runInput.vue'\nimport KlingInput from '../kling/kgInput.vue'\nimport PikaInput from './pikaInput.vue'\nimport { mlog } from '@/api';\nimport { gptServerStore } from '@/store';\nimport {  ref } from 'vue';\nimport { useRoute } from 'vue-router';\nimport PixInput from './pixInput.vue';\nimport VideoInput from '../video/input.vue';\n\nconst route = useRoute(); // 获取当前路由对象\n\nconst st= ref({tab:''});\nconst handleUpdateValue=(v:string)=>{\n   mlog(\"handleUpdateValue\",v)\n   gptServerStore.setMyData({TAB_VIDEO:v})\n}\n\nconst initLoad=()=>{\n    if(route.query.tab){\n        //st.value.tab=route.query.tab as string;\n        st.value.tab= 'pixverse' \n        let tt= (route.query.tab as string).toLocaleLowerCase();\n        if( ['luma','runway','pika','kling','runwayml','pixverse','all'].indexOf(tt)>-1 ){\n           st.value.tab=tt;\n        }\n        handleUpdateValue(  st.value.tab )\n    }\n    else st.value.tab=( gptServerStore.myData.TAB_VIDEO?gptServerStore.myData.TAB_VIDEO:'pixverse')\n    if( st.value.tab=='runwayml') st.value.tab='runway'\n}\ninitLoad();\n</script>\n\n<template>\n<div  >\n    <n-tabs type=\"line\"  :tabs-padding=\"1\" class=\"abc1234\" animated :default-value=\"st.tab\"  @update:value=\"handleUpdateValue\">\n        <!-- <n-tab-pane name=\"\" tab=\"\">\n        </n-tab-pane> -->\n        \n        <n-tab-pane name=\"all\" tab=\"All\">\n            <VideoInput />\n        </n-tab-pane>\n        <n-tab-pane name=\"pixverse\" tab=\"Pixverse\">\n            <PixInput />\n        </n-tab-pane>\n\n        <n-tab-pane name=\"kling\" :tab=\"$t('mj.kling')\">\n            <KlingInput />\n        </n-tab-pane>\n\n       \n        <n-tab-pane name=\"pika\" tab=\"Pika\">\n            <PikaInput />\n        </n-tab-pane>\n        <n-tab-pane name=\"luma\" tab=\"Luma\">\n            <LumaInput />\n        </n-tab-pane>\n         <n-tab-pane name=\"runway\" tab=\"Runway\" style=\"--n-tab-gap:10px\">\n            <RunwayInput />\n        </n-tab-pane>\n    </n-tabs>\n</div>\n</template>\n\n<style lang=\"css\"  scoped>\n.abc1234  {\n    --n-tab-gap:20px  !important;\n}\n</style>"
  },
  {
    "path": "src/views/luma/voList.vue",
    "content": "<script setup lang=\"ts\">\nimport { LumaMedia, lumaStore } from '@/api/lumaStore';\nimport { computed, ref, watch } from 'vue';\nimport {NEmpty ,NButton,NPopover, NTag,NButtonGroup,useMessage,NPopconfirm } from 'naive-ui'\nimport {FeedLumaTask, lumaFetch, mlog} from '@/api';\nimport { homeStore } from '@/store';\nimport {SvgIcon} from '@/components/common'\nimport { myTestTranscode } from '@/api/mp4img';\nimport { t } from '@/locales';\n//import { myTestTranscode } from '@/api/mp4img';\n\nconst st= ref({pIndex:-1});\nconst list= ref<LumaMedia[]>([]);\nconst csuno= new lumaStore()\nconst ms= useMessage()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\nconst nowTime= computed(()=>{\n    return new Date().getTime()\n})\nconst FeedLumaTaskDown=async (item:LumaMedia)=>{\n    //FeedLumaTask(id)\n    let id= item.id;\n    let url='';\n    try{\n        let d:any= await lumaFetch('/generations/'+id+'/download_video_url' );\n        mlog(\"d\", d )\n        url=d.url?? item.video?.url\n    }catch(e){\n         url= item.video?.url??''\n    }\n     \n        //window.open(d.url)\n    const link = document.createElement('a');\n    link.href = url ;\n    link.download = id+\".mp4\";\n    link.target = '_blank';\n    document.body.appendChild(link);\n    link.click();\n    document.body.removeChild(link);\n    \n}\n\n//getLastFrameBase64\nconst extend= async(item:LumaMedia )=>{\n    \n    mlog(\"extend \", item ) \n    homeStore.setMyData({act:\"luma.extend\", actData: item  })\n\n}\n\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='FeedLumaTask')  initLoad() \n});\nconst deleteGo=(item:LumaMedia)=>{\n    mlog('deleteGo',item )\n    if( csuno.delete( item)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\ninitLoad();\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n    <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                <video v-if=\"item.video?.url|| item.video?.download_url\" :src=\"item.video?.download_url? item.video?.download_url:item.video?.url\" @error=\"$event.target.src=item.video?.url\" loop  playsinline  :controls=\"st.pIndex==index\" class=\"w-full h-full object-cover\"></video>\n                <div class=\" text-center\" v-else>\n                    <div v-if=\"item.state=='failed'\" class=\"pt-2\" >{{ $t('video.failed') }}</div> \n                    <NButton  size=\"small\" type=\"primary\" @click=\"FeedLumaTask( item.id )\"   v-else-if=\"!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000\" >{{$t('video.repeat')}}</NButton>\n                    <div class=\"pt-2\" v-else>\n                        <div>{{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}</div>\n                        <div v-if=\"item.state=='pending'\">{{ $t('video.pending') }}</div> \n                        <div v-if=\"item.state=='processing'\">{{ $t('video.processing') }}</div> \n\n                    </div>\n                   \n                </div>\n            </div>\n            <div class=\"flex justify-between items-center\">\n                <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">{{item.prompt}}</div>\n                    </template>\n                    <div v-if=\"item.id\" >ID: {{ item.id }}</div>\n                    <div v-if=\"item.created_at\" >createdAt: {{ new Date( item.created_at).toLocaleString() }}</div>\n\n                    <div class=\" max-w-[300px]\">{{item.prompt}}</div>\n                </n-popover>\n                \n                </div>\n                <div class=\"flex justify-end items-center pt-1\"  v-if=\"item.video?.url|| item.video?.download_url\"> \n                     <!-- <span    @click=\"FeedLumaTaskDown( item.id )\" class=\"cursor-pointer\" ><SvgIcon icon=\"mdi:download\" /></span> -->\n\n                    \n                      <n-button-group size=\"tiny\">\n                        <n-button  size=\"tiny\" round ghost   @click=\"FeedLumaTaskDown( item )\"  ><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }}</n-button>\n                        <n-button   size=\"tiny\"  round ghost    > \n                            <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </n-button>\n                        <n-button   size=\"tiny\"  round ghost  @click=\"extend( item )\"  ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button>\n                      </n-button-group>\n                     <!-- <a :href=\"item.video?.download_url? item.video?.download_url:item.video?.url\" download  target=\"_blank\" v-if=\"item.video?.url|| item.video?.download_url\"  ><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a> -->\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/mj/aiBlend.vue",
    "content": "<script setup lang=\"ts\">\nimport {computed, ref} from 'vue';\nimport {useMessage, NButton,NImage,NSelect} from 'naive-ui';\nimport {upImg} from '@/api'\nimport { homeStore } from '@/store';\nimport { SvgIcon } from '@/components/common';\nimport config from \"./draw.json\";\nimport { t } from \"@/locales\";\n\nconst ms = useMessage();\nconst fsRef= ref() ;\nconst st= ref({status:'',isGo:false,dimensions:'SQUARE'})\nconst base64Array= ref<string[]>([]);\nconst selectFile=(input:any)=>{\n    upImg(input.target.files[0]).then(d=>{\n        fsRef.value.value='';\n        const index = base64Array.value.findIndex(item => item == d);\n        if(index>-1){\n            ms.error(t('mjchat.no2add') )\n            return ;\n        }\n        base64Array.value.push(d);\n        if(base64Array.value.length>1) st.value.isGo=true;\n        //if(st)\n    }).catch(e=>ms.error(e));\n}\nconst send= ()=>{\n    if(base64Array.value.length<2){\n        ms.error( t('mjchat.add2more') )\n        return ;\n    }\n    let obj={\n            action:'blend',\n            data:{\n                base64Array:base64Array.value\n                ,\"botType\": \"MID_JOURNEY\",\n                dimensions:st.value.dimensions?st.value.dimensions:'SQUARE'\n            }\n        }\n        homeStore.setMyData({act:'draw',actData:obj});\n        st.value.isGo=false;\n}\nconst drawlocalized = computed(() => {\n\tlet localizedConfig = {};\n\tObject.keys(config).forEach((key) => {\n\t\tlocalizedConfig[key] = config[key].map((option) => {\n\t\t\t// 假设 labelKey 如 \"draw.qualityList.general\"\n\t\t\tlet path = option.labelKey; // 直接使用 labelKey 作为路径\n\t\t\treturn {\n\t\t\t\t...option,\n\t\t\t\tlabel: t(path), // 从 i18n 中获取本地化的标签\n\t\t\t};\n\t\t});\n\t});\n\treturn localizedConfig;\n});\n</script>\n<template>\n\n<input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n<section class=\"mb-4 flex justify-between items-center\"  >\n     <div>{{ $t('mjchat.size') }}</div>\n    <n-select v-model:value=\"st.dimensions\" :options=\"drawlocalized.dimensionsList\" size=\"small\"  class=\"!w-[70%]\" :clearable=\"true\" />\n</section>\n<div class=\"flex justify-start items-center flex-wrap myblend\">\n    <div class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mr-2 mt-2 bg-[#ddd] overflow-hidden rounded-sm relative group \" v-for=\"item in base64Array\">\n        <NImage :src=\"item\" object-fit=\"cover\"></NImage>\n        <SvgIcon icon=\"fluent:delete-12-filled\"\n        class=\"absolute top-0 right-0 text-red-600 text-[20px] cursor-pointer hidden group-hover:block \"\n        @click=\"base64Array.splice(base64Array.indexOf(item),1)\"></SvgIcon>\n    </div>\n    <div class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mt-2 bg-[#999] overflow-hidden rounded-sm flex justify-center items-center cursor-pointer\"\n     @click=\"fsRef.click()\" v-if=\"base64Array.length<6\">\n        <SvgIcon icon=\"mdi:add-bold\" class=\"text-[40px] text-[#fff]\"></SvgIcon>\n    </div>\n</div>\n<div   class=\"flex justify-end pt-5\"><NButton @click=\"send\" type=\"primary\" :disabled=\"!st.isGo\">{{$t('mjchat.blendStart')}}</NButton> </div>\n\n<ul class=\"pt-4\" v-html=\"$t('mjchat.blendInfo')\">\n\n</ul>\n\n</template>\n<style scoped>\n.myblend{\n    --my-blend-img-size:80px\n}\n</style>\n"
  },
  {
    "path": "src/views/mj/aiCanvas.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref,onMounted,onUnmounted } from \"vue\";\n//import { CavansDemo } from \"@/views/aidutu\";\nconst pp= defineProps<{chat?:Chat.Chat,base64:string}>() \nconst st = ref({q:''}); \nconst ifdiv =ref<HTMLIFrameElement>();\nconst emits = defineEmits(['success']);\n\nonMounted( ()=>{ \n    // iframe.contentWindow && iframe.contentWindow.postMessage( JSON.stringify({act:'del',obj }), '*');\n    const data = {\n      instance_id: `1`,//固定值\n      custom_id: `2`,//固定值\n      channel_id: `3`,//固定值\n      guild_id: `4`,//固定值\n      frame_id: '5', //固定值\n      platform: 'desktop', //固定值\n      prompt: pp.chat?.text , // 按实际传入\n      img_type: 'png'// 按实际传入\n     // ,img_info:''\n      ,img_info: JSON.stringify({\"image_url\":  '' ,\"prompt\":\"sunglasses\"})  // 按实际传入\n      }\n    st.value.q=  Object.keys(data).map(key =>key + '=' + encodeURIComponent(data[key])).join('&')\n    window.addEventListener('message', messageFun )\n})\nonUnmounted(()=>{\n   window.removeEventListener('message', messageFun )\n})\n\n//收到iframe的消息\nconst messageFun=(e:MessageEvent)=>{\n   //console.log('我收到消息了', e.data );\n   if( !e?.data) return ;\n   const obj= JSON.parse( e.data );\n   emits('success', obj );\n}\nconst loadOk= (e:Event)=>{\n   //console.log('loadOk','good news' );\n    const iframe= e.target as HTMLIFrameElement;\n    iframe.contentWindow && iframe.contentWindow.postMessage( JSON.stringify({act:'go',img_info: {\"image_url\":  pp.base64==''?pp.chat?.opt?.imageUrl : pp.base64 ,\"prompt\":'' }  }), '*');// pp.chat?.text\n}\n</script>\n<template>\n    <!-- <iframe @load=\"loadOk\" ref=\"ifdiv\" :src=\"`./mitf/index.html?${st.q}`\"  class=\" h-[80vh] w-full\" style=\"border-width: 0px; border-style: none; overflow: hidden;\" v-if=\"st.q\"></iframe> -->\n    <!-- <iframe @load=\"loadOk\" ref=\"ifdiv\" :src=\"`https://static.aitutu.cc/res/mitf/index.html?${st.q}`\"  class=\" h-[80vh] w-full\" style=\"border-width: 0px; border-style: none; overflow: hidden;\" v-if=\"st.q\"></iframe> -->\n    <iframe @load=\"loadOk\" ref=\"ifdiv\" :src=\"`https://cdn.aidutu.cn/res/mitf/index.html?${st.q}`\"  class=\" h-[80vh] w-full\" style=\"border-width: 0px; border-style: none; overflow: hidden;\" v-if=\"st.q\"></iframe>\n\n</template>"
  },
  {
    "path": "src/views/mj/aiDall.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref ,computed,watch} from 'vue';\nimport {useMessage, NButton,NSelect,NInput, NImage, c} from 'naive-ui';\nimport {gptFetch, mlog, upImg} from '@/api'\nimport { homeStore } from '@/store';\nimport { SvgIcon } from '@/components/common';\nimport { t } from '@/locales';\n\nconst ms = useMessage();\nconst config = ref( {\nmodel:[\n{  \"label\": \"DALL·E 3\", \"value\": \"dall-e-3\" }\n ,{  \"label\": \"GPT-Image-1\", \"value\": \"gpt-image-1\" }\n ,{  \"label\": \"GPT-Image-1.5\", \"value\": \"gpt-image-1.5\" }\n ,{  \"label\": \"flux-kontext-pro\", \"value\": \"flux-kontext-pro\" }\n ,{  \"label\": \"flux-kontext-max\", \"value\": \"flux-kontext-max\" }\n ,{  \"label\": \"nano-banana-2\", \"value\": \"nano-banana-2\" }\n ,{  \"label\": \"nano-banana\", \"value\": \"nano-banana\" }\n ,{  \"label\": \"nano-banana-hd\", \"value\": \"nano-banana-hd\" }\n ,{  \"label\": \"gemini-3.1-flash-image-preview\", \"value\": \"gemini-3.1-flash-image-preview\" }\n ,{  \"label\": \"DALL·E 2\", \"value\": \"dall-e-2\" }\n ,{  \"label\": \"Flux\", \"value\": \"flux\" }\n ,{  \"label\": \"Flux-Dev\", \"value\": \"flux-dev\" }\n ,{  \"label\": \"Flux-Pro\", \"value\": \"flux-pro\" }\n ,{  \"label\": \"Flux-Pro-1.1\", \"value\": \"flux-pro-1.1\" }\n ,{  \"label\": \"Flux-Pro-1.1-Ultra\", \"value\": \"flux-pro-1.1-ultra\" }\n]\n});\ninterface myFile{\n    file:any\n    base64:string\n}\nconst st =ref({isGo:false,quality:'medium' }); \nconst fsRef= ref() ; \nconst base64Array= ref<myFile[]>([]);    \nconst f = ref({size:'1024x1024', prompt:'',\"model\": \"dall-e-3\",\"n\": 1});\nconst isDisabled= computed(()=>{\n    if(st.value.isGo) {\n        //console.log('st.value.isGo',st.value.isGo);\n        return true;\n    }\n    if(f.value.prompt.trim()=='') {\n        //console.log('prompt',\"空\");\n        return true;\n    }\n    return false;\n});\nconst create= async ()=>{\n    // const d= await gptFetch('/v1/embeddings',{\n    // \"input\":  f.value.prompt,\n    // \"model\": \"text-embedding-ada-002\"\n    // });\n    // mlog('test',d );\n    //return ;\n    let obj= {\n        action:'gpt.dall-e-3',\n        data:{} //f.value\n    }\n    obj.data= { ...f.value}\n    if(isCanImageEdit.value){\n        obj.data= {...obj.data ,quality:st.value.quality};\n    }\n    if (isCanImageEdit.value && base64Array.value.length>0){ \n         \n        obj.data= {...obj.data, 'base64Array':base64Array.value,quality:st.value.quality};\n        mlog(\"data\", '我加东西了：',  base64Array.value  )\n    }\n    homeStore.setMyData({act:'draw', actData:obj});\n    st.value.isGo=true;\n}\nwatch(()=>homeStore.myData.act,(n)=>{\n    if(n=='dallReload') {\n        st.value.isGo=false;\n        f.value.prompt='';\n    }\n    if(n=='updateChat')  st.value.isGo=false;  \n})\n\n \nconst qualityOption=  computed(()=>{ \n    return [\n{label:'High',value: 'high'}\n,{label:'Medium',value: 'medium'}\n,{label:'Low',value: 'low'}\n \n]\n});\nconst dimensionsList= computed(()=>{\n    if(f.value.model=='dall-e-2'){\n        return [{ \n                \"label\": \"1024px*1024px\",\n                \"value\": \"1024x1024\"\n            }, {\n                \"label\": \"512px*512px\",\n                \"value\": \"512x512\"\n            }, {\n                \"label\": \"256px*256px\",\n                \"value\": \"256x256\"\n            }\n    ];\n    } \n    if(f.value.model=='gpt-image-1'){\n        return [{ \n                    \"label\": \"1024px*1024px\",\n                    \"value\": \"1024x1024\"\n                }, {\n                    \"label\": \"1536px*1024px\",\n                    \"value\": \"1536x1024\"\n                }, {\n                    \"label\": \"1024px*1536px\",\n                    \"value\": \"1024x1536\"\n                }\n        ];\n    }\n    if(f.value.model.includes('banana')){ //auto\n     return [{ \n                    \"label\": \"auto\",\n                    \"value\": \"auto\"\n                }, { \n                    \"label\": \"4:3\",\n                    \"value\": \"4x3\"\n                },{\n                    \"label\": \"3:4\",\n                    \"value\": \"3x4\"\n                }, {\n                    \"label\": \"16:9\",\n                    \"value\": \"16x9\"\n                }, {\n                    \"label\": \"9:16\",\n                    \"value\": \"9x16\"\n                }, {\n                    \"label\": \"2:3\",\n                    \"value\": \"2x3\"\n                }, {\n                    \"label\": \"3:2\",\n                    \"value\": \"3x2\"\n                }\n                , {\n                    \"label\": \"1:1\",\n                    \"value\": \"1024x1024\"\n                }\n        ];\n    }\n    return [{ \n                \"label\": \"1024px*1024px\",\n                \"value\": \"1024x1024\"\n            }, {\n                \"label\": \"1792px*1024px\",\n                \"value\": \"1792x1024\"\n            }, {\n                \"label\": \"1024px*1792px\",\n                \"value\": \"1024x1792\"\n            }\n     ]\n     \n})\nwatch(()=>f.value.model,(n)=>{\n    f.value.size='1024x1024';\n})\nconst isCanImageEdit= computed(()=>{\n    if(f.value.model=='dall-e-2') return true;\n    if(f.value.model=='gpt-image-1') return true;\n    if(f.value.model.indexOf('kontext')>-1) return true;\n    if(f.value.model.indexOf('banana')>-1) return true;\n    return false;\n})\n\nconst selectFile=(input:any)=>{\n    const ff=input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        fsRef.value.value='';\n        const index = base64Array.value.findIndex(item => item.base64 == d);\n        if(index>-1){\n            ms.error(t('mjchat.no2add') )\n            return ;\n        }\n        base64Array.value.push({file: ff ,base64:d});\n        //if(base64Array.value.length>1) st.value.isGo=true;\n        //if(st)\n    }).catch(e=>ms.error(e));\n}\n\n</script>\n<template>\n<section class=\"mb-4 flex justify-between items-center\"  >\n     <div>{{ $t('mjchat.version') }} </div>\n    <n-select v-model:value=\"f.model\" :options=\"config.model\" filterable tag size=\"small\"  class=\"!w-[70%]\" :clearable=\"false\" />\n</section>\n<section class=\"mb-4 flex justify-between items-center\"  >\n     <div>{{ $t('mjchat.size') }}</div>\n    <n-select v-model:value=\"f.size\" :options=\"dimensionsList\"  filterable tag size=\"small\"  class=\"!w-[70%]\" :clearable=\"false\" />\n</section>\n<section class=\"mb-4 flex justify-between items-center\" v-if=\"isCanImageEdit\" >\n     <div>Quality</div>\n    <n-select v-model:value=\"st.quality\" :options=\"qualityOption\"  filterable tag size=\"small\"  class=\"!w-[70%]\" :clearable=\"false\" />\n</section>\n\n<div class=\"mb-1\">\n     <n-input    type=\"textarea\"  v-model:value=\"f.prompt\"   :placeholder=\"$t('mjchat.prompt')\" round clearable maxlength=\"500\" show-count \n      :autosize=\"{   minRows:3, maxRows:10 }\" />\n</div>\n<div class=\"mb-1\" v-if=\"isCanImageEdit\"> \n    <div class=\"flex justify-start items-center flex-wrap myblend\">\n\n    <div class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mr-2 mt-2 bg-[#ddd] overflow-hidden rounded-sm relative group \" v-for=\"item in base64Array\">\n        <NImage :src=\"item.base64\" object-fit=\"cover\"></NImage>\n        <SvgIcon icon=\"fluent:delete-12-filled\"\n        class=\"absolute top-0 right-0 text-red-600 text-[20px] cursor-pointer hidden group-hover:block \"\n        @click=\"base64Array.splice(base64Array.indexOf(item),1)\"></SvgIcon>\n    </div>\n\n        <div   @click=\"fsRef.click()\" v-if=\"base64Array.length<3\"\n         class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mt-2 bg-[#999] overflow-hidden rounded-sm flex justify-center items-center cursor-pointer\">\n            <SvgIcon icon=\"mdi:add-bold\" class=\"text-[40px] text-[#fff]\"></SvgIcon>\n        </div>\n         \n    </div>   \n</div>\n\n<div class=\"mb-4 flex justify-end items-center\">\n    <div class=\"flex \">\n         <n-button type=\"primary\" :block=\"true\" :disabled=\"isDisabled\" @click=\"create()\"  >\n            <SvgIcon icon=\"mingcute:send-plane-fill\" />   \n             {{ $t('mjchat.imgcreate') }} \n        </n-button>\n    </div>\n</div>\n\n<ul class=\"pt-4\" v-html=\"$t('mjchat.dalleInfo')\">\n   \n</ul>\n\n<input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n\n</template>\n\n<style scoped>\n.myblend{\n    --my-blend-img-size:75px\n}\n</style>"
  },
  {
    "path": "src/views/mj/aiDrawInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { NTabs,NTabPane } from 'naive-ui';\nimport aiDrawInputItem from './aiDrawInputItem.vue'\nimport aiFace from './aiFace.vue'\nimport aiBlend from './aiBlend.vue'\nimport aiDall from './aiDall.vue'\nimport aiIdeoInput from './aiIdeoInput.vue'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { SvgIcon } from '@/components/common'\nimport { onMounted, ref, watch } from 'vue';\nimport { gptServerStore } from '@/store';\nimport { mlog } from '@/api';\nimport { useRoute } from 'vue-router'; \n\nconst route = useRoute(); // 获取当前路由对象\n\nconst $emit=defineEmits(['drawSent','close']);\nconst drawSent=(d:any )=> $emit('drawSent',d);\nconst {isMobile}= useBasicLayout()\n\nconst st= ref({drawType:'draw',tab:''});\n\nonMounted(()=>{\n  //st.value.drawType='draw'\n  if(gptServerStore.myData.DRAW_TYPE) st.value.drawType=gptServerStore.myData.DRAW_TYPE\n})\n\n// watch(()=>st.value.drawType, (n:string)=> {\n//   mlog('st.value.drawType',n)\n//   gptServerStore.setMyData({DRAW_TYPE:n})\n// } )\n\nconst handleUpdateValue=(v:string)=>{\n   //mlog(\"handleUpdateValue\",v)\n   gptServerStore.setMyData({DRAW_TYPE:v})\n}\nconst initLoad=()=>{\n    if(route.query.tab){\n        st.value.tab= 'midjourney'//route.query.tab as string;\n        let tt= (route.query.tab as string).toLocaleLowerCase();\n        if( ['dall.e','ideogram'].indexOf(tt)>-1 ){\n           st.value.tab=tt;\n        }\n        handleUpdateValue(   st.value.tab )\n    }\n    else st.value.tab=( gptServerStore.myData.DRAW_TYPE?gptServerStore.myData.DRAW_TYPE:'midjourney')\n}\ninitLoad();\n\n</script>\n<template>\n<div class=\"overflow-y-auto bg-[#fafbfc] pt-2 dark:bg-[#18181c] h-full \">\n \n<n-tabs type=\"line\" animated :default-value=\"st.tab\" @update:value=\"handleUpdateValue\"  >\n    <n-tab-pane name=\"start\" tab=\"\"> \n\n    </n-tab-pane>\n    <n-tab-pane name=\"midjourney\" tab=\"MidJourney\" >\n      <!--  -->\n    <n-tabs type=\"segment\" animated   default-value=\"draw23\" size=\"small\">\n        <n-tab-pane name=\"draw23\" :tab=\"$t('mjchat.draw')\">\n          <aiDrawInputItem @draw-sent=\"drawSent\" @close=\"$emit('close')\"></aiDrawInputItem>\n        </n-tab-pane>\n        <!-- <n-tab-pane name=\"chap2\" tab=\"第二章\">2</n-tab-pane>\n        <n-tab-pane name=\"chap3\" tab=\"第三章\">3</n-tab-pane> -->\n        <n-tab-pane name=\"face\" :tab=\"$t('mjchat.face')\">\n          <div class=\"p-4\"><aiFace  /></div>\n        </n-tab-pane>\n        <n-tab-pane name=\"blend\" :tab=\"$t('mjchat.blend')\">\n          <div class=\"p-4\"><aiBlend  /></div>\n        </n-tab-pane>\n    </n-tabs>\n\n    </n-tab-pane>\n    \n    <n-tab-pane name=\"dall.e\" tab=\"Dall.E\">\n     <div class=\"p-4\"><aiDall  /></div>\n    </n-tab-pane>\n\n    <n-tab-pane name=\"ideogram\" tab=\"IdeoGram\">\n     <div class=\"p-2\"> <aiIdeoInput/> </div>\n    </n-tab-pane>  \n    \n\n\n    <n-tab-pane name=\"Close\" v-if=\"isMobile\" >\n      <template #tab>\n      <div class=\" text-center flex justify-center items-center\"   @click=\"$emit('close')\"  ><SvgIcon icon=\"ri:close-circle-line\"></SvgIcon></div>\n      </template>\n      <div class=\"p-4\"> \n        <div   @click=\"$emit('close')\" class=\" justify-center items-center flex\">\n            <SvgIcon icon=\"ri:close-circle-line\"></SvgIcon> Close By Click me \n        </div>\n      </div>\n    </n-tab-pane>\n\n</n-tabs> \n</div>\n</template>"
  },
  {
    "path": "src/views/mj/aiDrawInputItem.vue",
    "content": "<script setup lang=\"ts\"> \nimport { ref,computed,watch,onMounted } from \"vue\"; \nimport config from \"./draw.json\";\nimport {  NSelect,NInput,NButton,NTag,NPopover, useMessage,NInputNumber,NCollapse,NCollapseItem,NDivider,NModal} from 'naive-ui';\nimport {  SvgIcon } from '@/components/common'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nconst { isMobile } = useBasicLayout()\nimport AiMsg from './aiMsg.vue'\n//import aiFace from './aiFace.vue'\nimport { mlog, train, upImg ,getMjAll, mjFetch } from '@/api'\n//import {copyText3} from \"@/utils/format\";\nimport { homeStore ,useChatStore} from \"@/store\";\nconst chatStore = useChatStore()\nimport {t} from \"@/locales\"\n//import { upImg } from \"./mj\";\nimport AiEditVidoe from './aiEditVidoe.vue'\nimport AiEditImage from './aiEditImage.vue'\nimport { key } from \"localforage\";\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1'}\n,{s:'width: 100%; height: 75%;',label:'4:3'}\n,{s:'width: 75%; height: 100%;',label:'3:4'}\n,{s:'width: 100%; height: 50%;',label:'16:9'}\n,{s:'width: 50%; height: 100%;',label:'9:16'}\n ];\n\nconst bsOption=[\n    {value:0,key:0,label:'未使用'}\n    ,{value:4,key:4,label:'4个'}\n    ,{value:2,key:2,label:'2个 单价1/2'}\n    ,{value:1,key:1,label:'1个 单价1/4'}\n];\nconst f=ref({bili:-1, quality:'',view:'',light:'',shot:'',style:'', styles:'',version:'--v 7.0'\n,sref:'',cref:'',cw:'',oref:'',vidoeImage:'',videoBs:0 });\nconst st =ref({text:'',isDisabled:false,isLoad:false\n    ,fileBase64:[],bot:'',showFace:false,upType:''\n});\nconst farr= [\n{ k:'style',v:t('mjchat.tStyle') }\n,{ k:'view',v: t('mjchat.tView') }\n,{ k:'shot',v: t('mjchat.tShot') }\n,{ k:'light',v: t('mjchat.tLight') }\n,{ k:'quality',v: t('mjchat.tQuality') }\n,{ k:'styles',v:t('mjchat.tStyles') }\n,{ k:'version',v:t('mjchat.tVersion') }\n ];\n\nconst drawlocalized = computed(() => {\n\tlet localizedConfig = {};\n\tObject.keys(config).forEach((key) => {\n\t\tlocalizedConfig[key] = config[key].map((option) => {\n\t\t\t// 假设 labelKey 如 \"draw.qualityList.general\"\n\t\t\tlet path = option.labelKey; // 直接使用 labelKey 作为路径\n\t\t\treturn {\n\t\t\t\t...option,\n\t\t\t\tlabel: t(path), // 从 i18n 中获取本地化的标签\n\t\t\t};\n\t\t});\n\t});\n\treturn localizedConfig;\n});\n\n\nconst msgRef = ref()\nconst fsRef= ref()\nconst fsRef2 = ref()\nconst fsRef3 = ref()\nconst $emit=defineEmits(['drawSent','close']);\nconst props = defineProps({buttonDisabled:Boolean});\n\nconst isDisabled = computed(() => {\n    return props.buttonDisabled || st.value.isLoad || st.value.text.trim()==''\n})\nconst ms=   useMessage();\nfunction create( ){\n\n\n    st.value.isLoad=true\n    train( st.value.text.trim()).then(ps=>{\n        const rz={ prompt: st.value.text.trim() , drawText: createPrompt( ps) }\n        if( ps  ) drawSent(rz)\n        //st.value.text=''\n        st.value.isLoad=false\n    }).catch(err=>{\n        msgRef.value.showError(err)\n        st.value.isLoad=false\n    })\n\n\n}\n\nconst shorten= ()=>{\n\n    if( st.value.text.trim()=='') {\n        mlog('empty');\n        msgRef.value.showError(t('mjchat.placeInput') );\n        return;\n    }\n\n    let obj={\n            action:'shorten',\n            data:{prompt: st.value.text.trim(),botType: st.value.bot=='NIJI_JOURNEY'? 'NIJI_JOURNEY': 'MID_JOURNEY'}\n        }\n    homeStore.setMyData({act:'draw',actData:obj});\n}\nfunction drawSent(rz:any){\n    let rz2= rz;\n    if(st.value.fileBase64) {\n        rz2.fileBase64=st.value.fileBase64\n    }\n    if( st.value.bot=='NIJI_JOURNEY' ){\n        rz2.bot='NIJI_JOURNEY';\n    }\n    $emit('drawSent', rz2 )\n    st.value.fileBase64= [];\n}\nfunction createPrompt(rz:string){\n    if( rz =='') {\n        msgRef.value.showError(t('mjchat.placeInput') );\n        return '';\n    }\n    const oloadRz=rz\n\n\n    // for(let v of farr){\n    //     if( ! f.value[v.k] || f.value[v.k]==null || f.value[v.k]=='' ) continue;\n    //      mlog('k ', rz,  f.value  );\n    //     if(v.k=='quality') rz +=`  --q ${f.value.quality}`;\n    //     else if(v.k=='styles') { if( f.value.styles ) rz +=` ${f.value.styles}`;}\n    //     else if(v.k=='version') {\n    //         st.value.bot= '';\n    //        if(['MID_JOURNEY','NIJI_JOURNEY'].indexOf(f.value.version)>-1 ){\n    //              st.value.bot= f.value.version ;\n    //        } else   rz +=` ${f.value.version}`;\n    //     }\n    //     else if( f.value[v.k] ) rz +=` , ${f.value[v.k]}`;\n    // }\n    // mlog('createPrompt ', rz,  f.value  );\n    // if(f.value.bili>-1) rz +=` --ar ${vf[f.value.bili].label}`;\n    let rzp='' //参数组合字符串\n    let rzk=''; //描述词组合字符串\n    for(let v of farr){\n        if( ! f.value[v.k] || f.value[v.k]==null || f.value[v.k]=='' ) continue;\n        mlog('k ', rz,  f.value  );\n        if(v.k=='quality') rzp +=`  --q ${f.value.quality}`;\n        else if(v.k=='styles') { if( f.value.styles ) rzp +=` ${f.value.styles} `;}\n        else if(v.k=='version') {\n            st.value.bot= '';\n        if(['MID_JOURNEY','NIJI_JOURNEY'].indexOf(f.value.version)>-1 ){\n                st.value.bot= f.value.version ;\n        } else   rzp +=` ${f.value.version}`;\n        }\n        else if( f.value[v.k] ) rzk +=`${f.value[v.k]},`;\n    }\n\n    mlog('createPrompt ', rz,  f.value  );\n    if( f.value.sref.trim() != '' ) rzp += ` --sref ${f.value.sref}`\n    if( f.value.cref.trim() != '' ) rzp += ` --cref ${f.value.cref}`\n    if(  f.value.oref &&  f.value.oref.trim() != '' ) rzp += ` --oref ${f.value.oref}`\n    if( f.value.cw && f.value.cw!='' ) rzp += ` --cw ${f.value.cw}`\n    if (f.value.bili > -1) rzp += ` --ar ${vf[f.value.bili].label}` \n    if(f.value.videoBs>0){\n        if (f.value.vidoeImage) rzk += ` ${f.value.vidoeImage} `\n        rz = ` ${oloadRz} --bs ${f.value.videoBs} `\n        rzp=` --video `\n       \n    }\n    rz = rzk + rz +rzp;\n\n    // mlog('createPrompt over ', rz  );\n    return rz ;\n}\n\n// const copy=()=>{\n//     copyText3( '哦们sd').then(()=>msgRef.value.showMsg('复制成功345！'));\n// }\n// const copy2= ()=>{\n//     copyRef.value.click();\n// }\nfunction selectFile(input:any){\n    if(st.value.fileBase64.length>=5 ) {\n        ms.error( t('mjchat.more5sb'));\n        return;\n    }\n    upImg(input.target.files[0]).then( (d:any )=>{\n        const index = st.value.fileBase64.findIndex(v=>v==d);\n        if(index>-1) {\n            ms.error( t('mjchat.no2add'));\n            return ;\n        }\n        st.value.fileBase64.push(d);\n        fsRef.value.value='';\n    }).catch(e=>msgRef.value.showError(e));\n\n}\n\n//图生文\nfunction selectFile2(input:any){\n\n    upImg(input.target.files[0]).then(d=>{\n        mlog('f2base64>> ',d );\n        let obj={\n            action:'img2txt',\n            data:{\n                \"base64\":d\n                ,\"botType\": \"MID_JOURNEY\"\n            }\n        }\n        homeStore.setMyData({act:'draw',actData:obj});\n        //input.value.value='';\n        fsRef2.value.value='';\n\n    })\n    .catch(e=>msgRef.value.showError(e))\n}\n\nconst same2=()=>{\n     st.value.text= homeStore.myData.actData.prompt;\n    f.value.version='';\n    f.value.quality='';\n}\nwatch(()=>homeStore.myData.act,(n)=>{\n   // n=='copy' && copy2();\n    n=='same2' && same2();\n});\nwatch(()=>f.value,(n)=>{\n    mlog(\"变化\", n )\n    localStorage.setItem(\"mjinput\",  JSON.stringify(n))\n},{deep:true} );\nonMounted(()=>{\n    homeStore.myData.act=='same2' && same2();\n\n    let minput=  localStorage.getItem('mjinput')\n    if(minput ){\n      try {\n        const a=JSON.parse(minput)\n        f.value=a\n      } catch (error) {\n        mlog(\"错误\", error )\n      }\n    }\n});\n\n\n\nconst exportToTxt= async ()=>{\n    let txtContent ='';\n    mlog('sss',txtContent,chatStore.$state.chat.length  );\n\n    let d = await getMjAll( chatStore.$state);\n    if(d.length==0) {\n        //ms.info('暂时没作品');\n        ms.info( t('mjchat.noproducet'));\n        return;\n    }\n    d.forEach((v:Chat.Chat,i:number)=>{\n        if( v.opt&& v.opt?.status=='SUCCESS' && v.opt?.imageUrl ) {\n                txtContent += v.opt?.imageUrl+ \"\\n\\n\";\n        }\n    })\n    if(txtContent=='') {\n         ms.info( t('mjchat.noproducet'));\n        return;\n    }\n    let blob = new Blob([txtContent], { type: \"text/plain\" });\n    let a = document.createElement(\"a\");\n    a.href = URL.createObjectURL(blob);\n    a.download = t('mjchat.downloadSave') ;\n    a.click();\n    ms.success( t('mjchat.exSuccess'));\n}\n\nconst clearAll=()=>{\n  st.value.fileBase64=[];\n  st.value.text='';\n  f.value.bili=-1;\n  f.value.version='';\n  f.value.quality='';\n  f.value.shot='';\n  f.value.light='';\n  f.value.style='';\n  f.value.styles='';\n  f.value.view='';\n  f.value.cref='';\n  f.value.cw='';\n  f.value.sref='';\n  f.value.oref='';\n  f.value.vidoeImage='';\n  f.value.videoBs=0;\n}\n\nconst uploader=(type:string)=>{\n    st.value.upType= type;\n    fsRef3.value.click();\n}\n\nconst mst= ref({isShow:false,type:'',base64:''});\nconst selectFile3=  (input:any)=>{\n    \n    const isEdit= 'editVideo'== st.value.upType ||'editImage'== st.value.upType\n    !isEdit &&  ms.loading('上传中...') \n    upImg(input.target.files[0]).then( async(d)=>{\n        //mlog('selectFile3>> ',d );\n        if( isEdit){\n            mst.value.isShow=true;\n            mst.value.type=st.value.upType;\n            mst.value.base64=d;\n            fsRef3.value.value='';\n            return \n        }\n        let data={\n            action:'img2txt',\n            data:{\n                \"base64Array\":[d]\n            }\n        }\n        //homeStore.setMyData({act:'draw',actData:obj});\n        //input.value.value='';\n        try{\n            d=  await mjFetch('/mj/submit/upload-discord-images' , data.data  );\n            mlog('selectFile3>> ',d );\n            fsRef3.value.value='';\n            if(d.code== 1){\n                if( st.value.upType=='cref'){\n                    f.value.cref= d.result[0];\n                }else if(st.value.upType=='vidoeImage' ){\n                   f.value.vidoeImage= d.result[0];\n                }else if(st.value.upType=='oref' ){\n                    f.value.oref= d.result[0];\n                }else{\n                    f.value.sref= d.result[0];\n                }\n                ms.success( t('mj.uploadSuccess'));\n            }\n        }catch(e ){\n            msgRef.value.showError(e)\n        }\n\n    })\n    .catch(e=>msgRef.value.showError(e))\n}\n</script>\n<template>\n<AiMsg ref=\"msgRef\" />\n<input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n<input type=\"file\"  @change=\"selectFile2\" ref=\"fsRef2\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n<input type=\"file\"  @change=\"selectFile3\" ref=\"fsRef3\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n\n<div class=\"overflow-y-auto bg-[#fafbfc] px-4 dark:bg-[#18181c] h-full \">\n\n    <section class=\"mb-4\">\n        <div class=\"mr-1  mb-2 flex justify-between items-center\">\n            <div class=\"text-sm\">{{ $t('mjchat.imgBili') }}</div>\n            <div>\n            <NPopover trigger=\"hover\">\n                <template #trigger>\n                 <SvgIcon icon=\"iconoir:database-export\" class=\"text-lg cursor-pointer\" @click=\"exportToTxt\"></SvgIcon>\n                </template>\n                <div>{{ $t('mjchat.imagEx') }}</div>\n            </NPopover>\n            </div>\n        </div>\n        <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':index==f.bili}\"  @click=\"f.bili=index\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n\n        </div>\n    </section>\n    <n-collapse class=\"mb-4\">\n      <n-collapse-item :title=\"$t('mj.moreset')\" name=\"1\">\n     \n        <section class=\"mb-4 flex justify-between items-center\" v-for=\" v in farr\">\n            <div>{{ v.v }}</div>\n            <n-select v-model:value=\"f[v.k]\" :options=\"drawlocalized[v.k+'List']\" size=\"small\"  class=\"!w-[60%]\" :clearable=\"true\" />\n        </section>\n     \n        <section class=\"mb-4 flex justify-between items-center\"  >\n        <div  >cw(0-100)</div>\n        <NInputNumber :min=\"0\" :max=\"100\" v-model:value=\"f.cw\" class=\"!w-[60%]\" size=\"small\" clearable placeholder=\"0-100 角色参考程度\" />\n        </section >\n    \n        <section class=\"mb-4 flex justify-between items-center\"  >\n        <div class=\"w-[45px]\">sref</div>\n            <NInput v-model:value=\"f.sref\" size=\"small\" placeholder=\"图片url 生成风格一致的图像\" clearable >\n                 <template #suffix>\n                    <SvgIcon icon=\"ri:upload-line\"  class=\"cursor-pointer\" @click=\"uploader('sref')\"></SvgIcon>\n                </template>\n            </NInput>\n        </section>\n\n        <section class=\"mb-4 flex justify-between items-center\"  >\n        <div class=\"w-[45px]\">cref</div>\n            <NInput  v-model:value=\"f.cref\" size=\"small\" placeholder=\"图片url 生成角色一致的图像\" clearable>\n                <template #suffix>\n                    <SvgIcon icon=\"ri:upload-line\" class=\"cursor-pointer\"  @click=\"uploader('cref')\"></SvgIcon>\n                </template>\n            </NInput>\n        </section>\n\n\n        <section class=\"mb-4 flex justify-between items-center\"  >\n        <div class=\"w-[45px]\">oref</div>\n            <NInput  v-model:value=\"f.oref\" size=\"small\" placeholder=\"图片url 全向参考的图像\" clearable>\n                <template #suffix>\n                    <SvgIcon icon=\"ri:upload-line\" class=\"cursor-pointer\"  @click=\"uploader('oref')\"></SvgIcon>\n                </template>\n            </NInput>\n        </section>\n\n        <section class=\"mb-4 flex justify-between items-center\"  >\n          <div >视频</div>\n          <n-select v-model:value=\"f.videoBs\" :options=\"bsOption\" size=\"small\"  class=\"!w-[60%]\" :clearable=\"true\" />\n        </section>\n        <section class=\"mb-4 flex justify-between items-center\" v-if=\"f.videoBs>0\" >\n        <div class=\"w-[45px]\">Video</div>\n            <NInput  v-model:value=\"f.vidoeImage\" size=\"small\" placeholder=\"视频参考 url\" clearable>\n                <template #suffix>\n                    <SvgIcon icon=\"ri:upload-line\" class=\"cursor-pointer\"  @click=\"uploader('vidoeImage')\"></SvgIcon>\n                </template>\n            </NInput>\n        </section>\n\n            \n      </n-collapse-item>\n    </n-collapse>\n   \n    \n    <div class=\"mb-1\">\n     <n-input    type=\"textarea\"  v-model:value=\"st.text\"   :placeholder=\"$t('mjchat.prompt')\" round clearable maxlength=\"2000\" show-count\n      :autosize=\"{   minRows:2, maxRows:5 }\" />\n    </div>\n    <div class=\"mb-4 flex justify-between items-center\">\n        <div class=\"flex justify-start items-center flex-wrap\">\n             <div class=\"pt-1 pr-1 \">\n             <NPopover trigger=\"hover\">\n                <template #trigger>\n                <n-tag type=\"error\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"fsRef.click()\"   v-if=\"st.fileBase64.length\">\n                <div style=\"display: flex;\">  <SvgIcon icon=\"mdi:file-chart-check-outline\" /> {{ $t('mjchat.imgCYes') }} </div>\n                </n-tag>\n                <n-tag type=\"warning\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"fsRef.click()\"   v-else=\"st.fileBase64\">\n                <div style=\"display: flex;\">  <SvgIcon icon=\"mdi:file-document-plus-outline\" />  {{ $t('mjchat.imgCUpload') }} </div>\n                </n-tag>\n                </template>\n                <div  style=\"max-width: 240px;\">\n                <p v-html=\"$t('mjchat.imgCInfo')\"></p>\n\n                3.<a class=\"text-green-500 cursor-pointer\"  @click=\"fsRef.click()\" v-html=\"$t('mjchat.imgCadd')\"></a><br/>\n                <div  v-if=\"st.fileBase64.length>0\" class=\"flex justify-start items-baseline\">\n                    <div class=\"p-1\" v-for=\"(v ) in st.fileBase64\">\n                        <img  class=\"w-[60px]\" :src=\"v\">\n                        <br/>\n                        <NButton size=\"small\" @click=\"st.fileBase64= st.fileBase64.filter((item)=>item!=v) \" type=\"warning\" >{{$t('mjchat.del')}}</NButton>\n                    </div>\n\n                </div>\n                </div>\n             </NPopover>\n             </div>\n\n             <div class=\"pr-1 pt-1\">\n               <NPopover trigger=\"hover\">\n                    <template #trigger>\n                        <n-tag type=\"warning\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"fsRef2.click()\"    >\n                            <div style=\"display: flex;\">  <SvgIcon icon=\"fluent:image-edit-16-regular\" />  {{$t('mjchat.img2text')}} </div>\n                        </n-tag>\n                    </template>\n                     <div  style=\"max-width: 240px;\" v-html=\"$t('mjchat.img2textinfo')\">\n                     </div>\n                </NPopover>\n            </div>\n            <div class=\"pt-1\" >\n                <n-tag type=\"success\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"shorten()\"   >\n                     <div style=\"display: flex;\">  <SvgIcon icon=\"game-icons:bouncing-spring\" /> Shorten </div>\n                </n-tag>\n            </div>\n\n        </div>\n\n\n        <!-- <div class=\"flex \"  v-if=\"$t('mjchat.imgcreate').indexOf('生成图片')!==-1\">\n         <n-button type=\"primary\" :block=\"true\" :disabled=\"isDisabled\"  @click=\"create()\">\n            <SvgIcon icon=\"mingcute:send-plane-fill\" />\n\n            <template v-if=\"st.isLoad\">{{$t('mjchat.traning')}} </template>\n            <template v-else> {{$t('mjchat.imgcreate')}}</template>\n\n        </n-button>\n        </div> -->\n\n\n    </div>\n\n\n\n        <div class=\"flex\">\n            <n-button type=\"primary\" :block=\"true\" :disabled=\"isDisabled\"  @click=\"create()\">\n            <SvgIcon icon=\"mingcute:send-plane-fill\" />\n\n            <template v-if=\"st.isLoad\">{{$t('mjchat.traning')}} </template>\n            <template v-else> {{$t('mjchat.imgcreate')}}</template>\n            </n-button>\n        </div>\n        <div class=\"flex justify-start items-center py-1\">\n\n            <div >\n                <n-tag type=\"success\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"clearAll()\"   >\n                     <div style=\"display: flex;\">  <SvgIcon icon=\"ant-design:clear-outlined\" />{{   $t('mj.clearAll')  }}  </div>\n                </n-tag>\n            </div>\n        </div>\n\n    <!-- <div>\n    <NDivider dashed>\n        <NTag type=\"success\" round ><div class=\"cursor-pointer\" @click=\"st.showFace= !st.showFace\">换脸服务</div></NTag>\n    </NDivider>\n    <aiFace v-if=\"st.showFace\" />\n    </div> -->\n    <!-- <div class=\"mb-4 flex justify-between items-center\">\n        <div @click=\"copy()\" ref=\"copyRef\">复制</div>\n        <div @click=\"copy2()\"  >复制2</div>\n    </div> -->\n\n  <n-divider dashed title-placement=\"right\">Other</n-divider>\n  <div class=\"flex justify-start items-center space-x-2\">\n        <n-tag type=\"primary\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"uploader('editVideo')\"   >\n            <div  class=\"flex\">  <SvgIcon icon=\"ri:video-add-line\" /> {{ $t('mj.editVideo') }} </div>\n        </n-tag>\n        <n-tag type=\"primary\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" @click=\"uploader('editImage')\"   >\n            <div  class=\"flex\">  <SvgIcon icon=\"mdi:file-chart-check-outline\" /> {{ $t('mj.editImage') }} </div>\n        </n-tag>\n  </div>\n\n   <ul class=\"pt-4\"  v-if=\"!isMobile\" v-html=\"$t('mjchat.imginfo')\"></ul>\n\n\n</div>\n\n<NModal v-model:show=\"mst.isShow\"   preset=\"card\"  :title=\" mst.type=='editVideo'?$t('mj.editVideo'):$t('mj.editImage')\" style=\"max-width: 800px;\" @close=\"mst.isShow=false\">\n        <AiEditVidoe :img=\"mst.base64\" @success=\"mst.isShow=false\"  v-if=\"mst.isShow && mst.type=='editVideo'\"   />\n        <AiEditImage :img=\"mst.base64\" @success=\"mst.isShow=false\"  v-if=\"mst.isShow && mst.type=='editImage'\"   />\n</NModal>\n\n</template>\n<style>\n    .aspect-item.active, .aspect-item.active .aspect-box{\n        border-color:#86dfba ;\n\n    }\n</style>\n"
  },
  {
    "path": "src/views/mj/aiEditImage.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref,onMounted,onUnmounted } from \"vue\";\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { NImage,NButton,useMessage,NInput,NSelect } from 'naive-ui'\nimport { mlog } from \"@/api\";\nimport { homeStore } from \"@/store\";\n\nconst pp= defineProps<{chat?:Chat.Chat,img:string}>() \nconst { isMobile } = useBasicLayout()\nconst f= ref({motion:'low',prompt:'','image':pp.img,\"base64\":pp.img,mode:'FAST'});\nconst st= ref({'isLoading':false,q:''});\nconst emits = defineEmits(['success']);\nconst ifdiv =ref<HTMLIFrameElement>();\n\nonMounted( ()=>{ \n    // iframe.contentWindow && iframe.contentWindow.postMessage( JSON.stringify({act:'del',obj }), '*');\n    const data = {\n      instance_id: `1`,//固定值\n      custom_id: `2`,//固定值\n      channel_id: `3`,//固定值\n      guild_id: `4`,//固定值\n      frame_id: '5', //固定值\n      platform: 'desktop', //固定值\n      prompt: \"\" , // 按实际传入\n      img_type: 'png'// 按实际传入\n     // ,img_info:''\n      ,img_info: JSON.stringify({\"image_url\":  '' ,\"prompt\":\"\"})  // 按实际传入\n      }\n    st.value.q=  Object.keys(data).map(key =>key + '=' + encodeURIComponent(data[key])).join('&')\n    window.addEventListener('message', messageFun )\n})\nonUnmounted(()=>{\n   window.removeEventListener('message', messageFun )\n})\n//收到iframe的消息\nconst messageFun=(e:MessageEvent)=>{\n   //console.log('我收到消息了', e.data );\n   if( !e?.data) return ;\n   const obj= JSON.parse( e.data ); \n   //console.log('success',  obj  );\n\n    let obj2={\n        action:'mj.edit.image',\n        version:1, \n        data:{\n            prompt:obj.prompt,\n            maskBase64:obj.mask,\n            image:pp.img,\n        },\n        \n    }\n    mlog('mj.edit.image', obj2 );\n    homeStore.setMyData({act:'draw',actData:obj2});\n   \n    emits('success'  );\n\n}\n\nconst loadOk= (e:Event)=>{\n    //console.log('loadOk','good news' );\n    const iframe= e.target as HTMLIFrameElement;\n    iframe.contentWindow && iframe.contentWindow.postMessage( JSON.stringify({act:'go',img_info: {\"image_url\":pp.img ,\"prompt\":'' }  }), '*');// pp.chat?.text\n}\n\n</script>\n<template> \n    \n    <iframe @load=\"loadOk\" ref=\"ifdiv\" :src=\"`https://cdn.aidutu.cn/res/mitf/index.html?${st.q}`\"  class=\" h-[80vh] w-full\" style=\"border-width: 0px; border-style: none; overflow: hidden;\" v-if=\"st.q\"></iframe>\n\n</template> "
  },
  {
    "path": "src/views/mj/aiEditVidoe.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref,onMounted,onUnmounted } from \"vue\";\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { NImage,NButton,useMessage,NInput,NSelect } from 'naive-ui'\nimport { mlog } from \"@/api\";\nimport { homeStore } from \"@/store\";\n\nconst pp= defineProps<{chat?:Chat.Chat,img:string}>() \nconst { isMobile } = useBasicLayout()\n\nconst f= ref({motion:'low',prompt:'','image':pp.img,\"base64\":pp.img,mode:'FAST'});\nconst st= ref({'isLoading':false});\nconst emits = defineEmits(['success']);\n\nconst modeOption=[{label:'Mode: Fast',value: 'FAST'},{label:'Mode: Relax',value: 'RELAX'} ,{label:'Mode: Turbo',value: 'TURBO'} ]\nconst motionOpt=[{label:'Motion: Low',value: 'low'},{label:'Motion: High',value: 'high'}]\n\nconst generate=()=>{\n    st.value.isLoading=true\n     let obj={\n        action:'mj.edit.video',\n        version:1, \n        data:f.value,\n        \n    }\n    mlog('mj.edit.video', obj );\n    homeStore.setMyData({act:'draw',actData:obj});\n    st.value.isLoading=false\n    emits('success'  );\n    \n}\n</script>\n<template>\n    <div :class=\"!isMobile?['flex', 'flex-row','justify-between']:''  \">\n        <section> \n            <NImage  :src=\"pp.img\" class=\" rounded-sm \" :class=\"[isMobile?'':'!max-w-[450px]']\"  /> \n        </section>\n        <section class=\"min-w-[270px]\">\n            <div class=\"pt-1\" >\n                <n-input v-model:value=\"f.prompt\" \n                            :placeholder=\"$t('video.descpls')\"  type=\"textarea\"  size=\"small\"   \n                            :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n            </div>\n            <div  class=\"pt-1\">\n                <n-select v-model:value=\"f.mode\" :options=\"modeOption\" size=\"small\" />\n            </div>\n             <div  class=\"pt-1\">\n                <n-select v-model:value=\"f.motion\" :options=\"motionOpt\" size=\"small\" />\n            </div>\n            <div class=\"pt-4 text-right\">\n                <NButton type=\"primary\" @click=\"generate()\" :disabled=\"f.prompt=='' \"  :loading=\"st.isLoading\">{{ $t('video.generate') }}</NButton>\n            </div>\n        </section>\n    </div>\n</template>"
  },
  {
    "path": "src/views/mj/aiFace.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport {useMessage, NButton} from 'naive-ui';\nimport {upImg} from '@/api'\nimport { homeStore } from '@/store';\nconst ms = useMessage();\nconst fsRef= ref() ;\nconst st= ref({status:'',isGo:false})\nconst f= ref({sourceBase64:'',targetBase64:''});\nfunction selectFile(input:any){\n     \n    upImg(input.target.files[0]).then(d=>{\n        if(st.value.status=='target') f.value.targetBase64=d;\n        else f.value.sourceBase64= d ; \n         st.value.isGo=true;\n        //if(st)\n    }).catch(e=>ms.error(e));\n    \n}\nconst send=()=>{\n    if( f.value.targetBase64 && f.value.sourceBase64){\n        let obj={\n            action:'face',\n            version:1, \n            data:f.value\n        }\n        homeStore.setMyData({act:'draw',actData:obj});\n        st.value.isGo=false;\n    }\n}\n</script>\n<template>\n<input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n\n<div class=\"flex justify-around items-center\">\n    <div class=\"h-[80px] w-[80px] rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\"(st.status='source') && fsRef.click()\">\n        <img :src=\"f.sourceBase64\" v-if=\"f.sourceBase64\" />\n        <div class=\"text-center\" v-else>{{ $t('mjchat.yourHead') }}</div> \n    </div>\n    <div>+</div>\n    <div class=\"h-[80px] w-[80px] rounded-sm border border-gray-400/20  flex justify-center items-center cursor-pointer\"  @click=\"(st.status='target') && fsRef.click()\">\n         <img :src=\"f.targetBase64\" v-if=\"f.targetBase64\"/>\n        <div class=\"text-center\" v-else>{{ $t('mjchat.your2Head') }}</div> \n    </div>\n</div>\n<div   class=\"flex justify-center pt-5\"><NButton @click=\"send\" type=\"primary\" :disabled=\"!st.isGo\">{{ $t('mjchat.submit') }}</NButton> </div>\n<ul class=\"pt-4\" v-html=\"$t('mjchat.tipInfo')\">\n    \n</ul>\n</template>"
  },
  {
    "path": "src/views/mj/aiFooter.vue",
    "content": "<script setup lang=\"ts\">\nimport aiGpts from \"./aiGpts.vue\"\nimport aiGallery from \"./aiGallery.vue\" \nimport realtimeLayout from \"@/views/wav/realtimeLayout.vue\" \n\n</script>\n<template>\n<aiGpts/>\n<aiGallery/>\n<!-- <aiOther/> -->\n<realtimeLayout/>\n</template>"
  },
  {
    "path": "src/views/mj/aiGallery.vue",
    "content": "<script lang=\"ts\" setup>\nimport { ref,watch,computed  } from \"vue\";\nimport gallery from './aiGalleryItem.vue'\nimport { homeStore } from \"@/store\";\nimport { useRoute } from 'vue-router';\nimport {NDrawerContent, NDrawer} from 'naive-ui'\nimport { useBasicLayout } from '@/hooks/useBasicLayout' \nimport { mlog } from \"@/api\";\n//import { copyText3 } from \"@/utils/format\";\nconst { isMobile } = useBasicLayout()\nconst route = useRoute();\nconst st= ref({'show':false,showImg:false})\nconst initLoad=()=>{\n    //gallery\n    mlog('toGallery', route.query  );\n    mlog('toGallery',  homeStore.myData.session  );\n    if( homeStore.myData.session.baiduId ) tjBaidu( homeStore.myData.session.baiduId );\n    if( homeStore.myData.session.googleId ) tjGoogle( homeStore.myData.session.googleId );\n    // if( _GET('to') =='gallery'){\n    //     homeStore.setMyData({act:'gallery'})\n    // }\n}\nwatch(() =>  homeStore.myData.act, (act) =>{\n  act=='gallery' && (st.value.showImg=true);\n  //act=='copy' &&   copyText3('addd890').then(dd=>console.log('ddd',dd ) );\n  })\n\nconst tjBaidu= (baiduID:string )=>{ \n   window._hmt=window._hmt || [];\n   let  hm = document.createElement(\"script\");\n   hm.src = \"https://hm.baidu.com/hm.js?\"+baiduID;\n   let s = document.getElementsByTagName(\"script\")[0] as HTMLScriptElement;\n   s.parentNode && s.parentNode.insertBefore(hm, s);\n   mlog('tjBaidu', hm.src  );\n  \n}\nconst tjGoogle= ( googleId:string )=>{\n  window.dataLayer = window.dataLayer || [];\n  let  hm = document.createElement(\"script\");\n  hm.src = \"https://www.googletagmanager.com/gtag/js?id=\"+googleId;\n  let s = document.getElementsByTagName(\"script\")[0] as HTMLScriptElement;\n  s.parentNode && s.parentNode.insertBefore(hm, s); \n  function gtag(...arg:any ){ window.dataLayer.push(arguments);}\n  gtag('js', new Date()); \n  gtag('config',  googleId );\n}\n\n//const baiduID= computed(()=>homeStore.myData.session.baiduID );\n \ninitLoad();\n</script>\n\n<template>\n<n-drawer v-model:show=\"st.showImg\" :placement=\"isMobile?'bottom':'right'\"  :class=\"isMobile?['!h-[80vh]']: ['!w-[80vw]']\" style=\"--n-body-padding:0\">\n    <n-drawer-content :title=\"$t('mjchat.myGallery')\" closable>\n      <gallery @close=\"st.showImg=false\" v-if=\"st.showImg\"/>\n    </n-drawer-content>\n</n-drawer>\n\n<!-- <template v-if=\"baiduID\">\n  <script>\n\t\t window._hmt=window._hmt || [];\n   var hm = document.createElement(\"script\");\n   hm.src = \"https://hm.baidu.com/hm.js?\"+baiduID;\n   var s = document.getElementsByTagName(\"script\")[0];\n   s.parentNode.insertBefore(hm, s);\n\t</script>\n</template> -->\n</template>"
  },
  {
    "path": "src/views/mj/aiGalleryItem.vue",
    "content": "<script setup lang=\"ts\">\nimport { LazyImg, Waterfall } from 'vue-waterfall-plugin-next'\nimport 'vue-waterfall-plugin-next/dist/style.css'\n//import { ajax } from '@/api' \nimport {ref,nextTick} from \"vue\"\nimport {NSpin ,NEmpty,NImage, NTag } from 'naive-ui' \n//import {copyText3} from \"@/utils/format\";\n//import { copyText } from 'vue3-clipboard'\n//import { copyToClip } from \"@/utils/copy\";\n//import AiMsg from \"@/views/aidutu/aiMsg.vue\";\nimport { homeStore ,useChatStore} from \"@/store\"\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\n//import { ViewCard } from 'vue-waterfall-plugin-next/dist/types/types/waterfall'\nimport { getMjAll, localGet, mlog ,loadGallery, url2base64 } from '@/api'\n \nconst chatStore = useChatStore()\n\nconst { isMobile } = useBasicLayout()\n\nconst emit = defineEmits(['close']);\n//import {hom}\n\nconst st =ref({show:true ,showImg:'' ,isLoad:false });\n\nconst showImg= ref<typeof NImage>();\n \n\nconst list = ref<any[]>([])\n\nconst breakpoints= {\n  2000: { //当屏幕宽度小于等于1200\n    rowPerView: 6,\n  },\n  1600: { //当屏幕宽度小于等于1200\n    rowPerView: 5,\n  },\n  1200: { //当屏幕宽度小于等于1200\n    rowPerView: 4,\n  },\n  800: { //当屏幕宽度小于等于800\n    rowPerView: 3,\n  },\n  500: { //当屏幕宽度小于等于500\n    rowPerView: 2,\n  }\n}\n\nconst loadImg= ()=>{\n    //mlog('local',homeStore.myData.session.isApiGallery );  \n    if( homeStore.myData.session.isApiGallery )  loadApiGallery();\n    else  loadImagFormLocal();\n}\n\nconst loadApiGallery= async ()=>{\n    st.value.isLoad= true;\n   let d= await loadGallery();\n   mlog('loadApiGallery',d);\n    st.value.isLoad= false;\n   if( !d || d.length==0 ) return;\n   let rz = d.map((v:any)=>{\n       return {\n           mjID: v.id,\n            src: v.imageUrl,isLoad:0, prompt: v.prompt,\n            image_url: v.imageUrl,\n            action: v.action\n            ,time: v.startTime\n       }\n   });\n   for(let i in rz ){\n        let v = rz[i];\n        try {\n            if( v.image_url){\n                //await loadImg(chat.value.opt?.imageUrl);\n                let key= 'img:'+v.mjID;\n                let base64 = await localGet(key );  \n                if(!base64) {\n                   url2base64( v.image_url ,key ).then((v:any)=>{\n                         mlog('图片已保存>>', key )\n                    }); \n                }else {\n                     rz[i].image_url =  rz[i].src =base64;\n                }\n                \n            }\n        } catch (error) {\n            mlog('图片保存失败',error);\n        }\n   }\n   \n\n   list.value= rz.sort((a:any,b:any)=> ( b.time - a.time) ) ;\n}\n\nconst loadImagFormLocal= async ( )=>{\n    let d = await getMjAll( chatStore.$state);\n    if( !d || d.length==0 ) return;\n   //mlog('loadImg', d );\n    \n    let rz = d.filter((v:any)=>  v.opt && v.opt.imageUrl ).map((v:any)=>{\n        //mlog('vv', v.opt.imageUrl); \n        // let key= 'img:'+v.mjID;\n        //  let base64 = await loca(key );  \n        return {\n            mjID: v.mjID,\n            src: v.opt.imageUrl,isLoad:0, prompt: v.opt.promptEn,\n            image_url: v.opt.imageUrl \n            ,action: v.opt.action\n            ,time: v.opt.startTime\n        }\n    });\n    list.value=[];\n    for(let v of rz ){\n        let key= 'img:'+v.mjID;\n        try{\n            let base64 = await localGet(key ); \n            if( base64 ) v.image_url =base64;\n        }catch(e){  }\n        list.value.push(v );\n    }\n\n   // list.value\n    \n    // ajax({  url: '/chatgpt/mj/gallery' })\n    //     .then((d) => {\n    //         // st.value.style= d.data.style\n    //         // st.value.example= d.data.example\n    //         console.log(d)\n    //         list.value= d.data.images.map((v:any)=>{ \n    //             v.isLoad=0\n    //             return  v;\n    //         })\n    //     } )\n\n}\nconst goShow=( item:any)=>{\n    //console.log('goShow', isMobile );\n    if( isMobile.value)   return ; \n    st.value.show= true;\n    st.value.showImg= item.image_url;\n    //console.log('goShow', item);\n    nextTick(() => showImg.value?.click());\n}\n// function copy( item:any){ \n//   //console.log('copy', item.prompt );\n// \t//copyText3(  item.prompt ).then(()=>msgRef.value.showMsg('复制成功！'));\n//   homeStore.setMyData({act:'copy',actData: {text: item.prompt } });\n// \t//copyToClip(  item.prompt ).then(()=>msgRef.value.showMsg('复制成功！'));\n// }\n \n\n//画同款\nconst same=( item:any,act:string)=>{\n  //console.log('same',item);\n  homeStore.setMyData({act,actData: JSON.parse(JSON.stringify(item) ) }); //:'same'\n  emit('close');\n}\nloadImg();\n\n</script>\n<template>\n \n <Waterfall :list=\"list\" :breakpoints=\"breakpoints\"  class=\" !bg-transparent\" v-if=\"list.length\">\n  <template #item=\"{ item, url, index }\">\n    <div class=\"bg-white dark:bg-[#24272e] rounded-md   overflow-hidden cursor-pointer group/item relative\">\n      <LazyImg :url=\"item.image_url\"  @success=\"item.isLoad=1\" @click=\"goShow(item )\" />\n      <!-- <LazyImg :url=\"item.image_hd_url\"  @success=\"item.isLoad=1\" /> -->\n      <div class=\"absolute top-0 left-0 right-0 bottom-0\" v-if=\"item.isLoad==0\">\n        <div class=\"flex justify-center items-center w-full h-full\">\n            <n-spin size=\"large\" />\n        </div>\n      </div>\n      <div class=\"absolute w-full bottom-0   backdrop-blur-sm text-white/70 invisible group-hover/item:visible \">\n        <div class=\"p-3\">\n            <div class=\"line-clamp-2 text-[13px]\"> \n                <template v-if=\"item.prompt\">{{ item.prompt }}</template>\n                <NTag v-else-if=\"item.action=='SWAP_FACE'\" type=\"success\" size=\"small\" round v-html=\"$t('mjchat.face')\"></NTag>\n                <NTag v-else-if=\"item.action=='BLEND'\" type=\"success\" size=\"small\" round  v-html=\"$t('mjchat.blend')\" ></NTag>\n                <NTag v-else type=\"success\" size=\"small\" round >{{ item.action }}</NTag>\n            </div>\n            <div class=\"line-clamp-1 text-[12px] text-right\">{{ new Date( item.time).toLocaleString() }}</div>\n            <div class=\"space-x-2\">\n                \n                <!-- <NButton type=\"primary\" size=\"small\" @click=\"copy(item )\" >复制</NButton> -->\n\n                <!-- <NButton type=\"primary\" size=\"small\" @click=\"same(item,'same2' )\" >引用</NButton>\n                <NButton type=\"primary\" size=\"small\"  @click=\"same(item,'same' )\">画同款</NButton> -->\n                 \n            </div>\n        </div>\n      </div>\n      <!-- <p class=\"text\">这是具体内容</p> -->\n    </div>\n  </template>\n</Waterfall>\n<div v-else-if=\"st.isLoad\" class=\"w-full h-full flex justify-center items-center\">\n    <n-spin size=\"large\" />\n    <div>Loading....</div>\n</div>\n<div v-else class=\"w-full h-full flex justify-center items-center\">\n    <n-empty :description=\"$t('mjchat.noproduct')\" />\n</div>\n\n\n<NImage   :src=\"st.showImg\"  ref=\"showImg\" v-if=\"st.showImg\" :width=\"1\" />\n <!-- <NButton type=\"primary\" size=\"small\" @click=\"copy2('abdd' )\" >复制</NButton> -->\n\n<!-- <div @click=\"copy2('abdd' )\">复制测试</div> -->\n</template>\n\n<style>\n.lazy__img[lazy=loading] {\n  padding: 5em 0;\n  width: 48px;\n}\n\n.lazy__img[lazy=loaded] {\n  width: 100%;\n}\n\n.lazy__img[lazy=error] {\n  padding: 5em 0;\n  width: 48px;\n}\n</style>"
  },
  {
    "path": "src/views/mj/aiGpt.vue",
    "content": "<script setup lang='ts'> \nimport { computed,   ref,watch  } from 'vue' \nimport { useRoute } from 'vue-router'\nimport { useChat } from '../chat/hooks/useChat' \nimport {  homeStore, useChatStore } from '@/store'\nimport { getInitChat, mlog, subModel,getSystemMessage , localSaveAny, canVisionModel\n    ,isTTS, subTTS, file2blob, whisperUpload, getHistoryMessage, checkDisableGpt4, chatSetting, \n    canBase64Model,\n    isCanBase64Model,\n    isNewModel} from '@/api'\n//import { isNumber } from '@/utils/is'\nimport { useMessage  } from \"naive-ui\";\nimport { t } from \"@/locales\";\n\nconst emit = defineEmits(['finished']);\nconst { addChat , updateChatSome } = useChat() \nconst chatStore = useChatStore()\nconst st=ref({uuid:'1002', index:-1 });\nconst controller = ref<AbortController>( );;// new AbortController();\nconst dataSources = computed(() => chatStore.getChatByUuid(+st.value.uuid))\nconst ms= useMessage();\nconst textRz= ref<string[]>([]);\nconst goFinish= (  )=>{\n    //let dindex = st.value.index>=0? st.value.index : dataSources.value.length - 1;\n    //return ;\n    updateChatSome( +st.value.uuid,  st.value.index , { dateTime: new Date().toLocaleString(),loading: false })\n    //scrollToBottom();\n    emit('finished');\n  \n    homeStore.setMyData({act:'scrollToBottomIfAtBottom'});\n    mlog('🐞 goFinish2',st.value.uuid);\n    // setTimeout(() => {\n        \n    //    if(textRz.value.length>0 )  textRz.value = [];\n    // }, 200 ); \n}\n\nconst getMessage= async (start=1000,loadingCnt=3)=>{\n    return getHistoryMessage(dataSources.value,loadingCnt,start);\n}\n\n\nwatch( ()=>textRz.value, (n)=>{\n    //mlog('🐞 textRz',n);\n    if(n.length==0) return ;\n    updateChatSome( +st.value.uuid, st.value.index , { dateTime: new Date().toLocaleString(),text: n.join('') })\n    //scrollToBottom();\n    homeStore.setMyData({act:'scrollToBottomIfAtBottom'})\n    //homeStore.setMyData({act:'scrollToBottom'})\n},{deep:true}) \nconst { uuid } = useRoute().params as { uuid: string }\nwatch(()=>homeStore.myData.act, async (n)=>{\n\n   \n    \n    if(n=='gpt.submit' ||  n=='gpt.whisper'  ){\n        \n        const dd:any = homeStore.myData.actData;\n       \n        let  uuid2 =  dd.uuid?? uuid;\n        st.value.uuid =  uuid2 ;\n        const chatSet = new chatSetting(   +st.value.uuid  );\n        const nGptStore =   chatSet.getGptConfig()  ; \n         mlog('gpt.submit', dd , dd.uuid,  nGptStore ) ;\n        let model = nGptStore.model ;//gptConfigStore.myData.model\n\n        if(checkDisableGpt4( model )){\n            ms.error( t('mj.disableGpt4') );\n            return false;\n        }\n        \n        let promptMsg = getInitChat(dd.prompt );\n        if( dd.fileBase64 && dd.fileBase64.length>0 ){ \n            if( !canVisionModel(model)  )  model= canBase64Model(model)//model='gpt-4-vision-preview';\n        \n            try{\n                    let images= await localSaveAny( JSON.stringify({fileName: dd.fileName, fileBase64: dd.fileBase64 }) ) ;\n                    mlog('key', images );\n                    promptMsg.opt= {images:[images]}\n            }catch(e){\n                mlog('localSaveAny error',e);\n            }\n        }\n        if( n=='gpt.whisper'){\n            //model='whisper-1';\n            try{\n                let bb= await file2blob( dd.file );\n                // bb.blob\n                let lkey = await localSaveAny( bb   ) ;\n                mlog('key', lkey );\n                promptMsg.opt= { lkey  }\n                promptMsg.text='Loading...'\n                promptMsg.model='whisper-1';\n                if(dd.duration && dd.duration>0 ){\n                     promptMsg.text=`${t('mj.lang')} ${dd.duration.toFixed(2)}s`;\n                }\n                addChat(  +uuid2, promptMsg );\n                homeStore.setMyData({act:'scrollToBottom'});\n            }catch(e){\n                mlog('localSaveAny error',e);\n                ms.error( t('mj.noSupperChrom') );\n                return ;\n            }\n            \n            try{\n                const formData = new FormData( ); \n                formData.append('file',dd.file );\n                formData.append('model', 'whisper-1'); \n                const whisper=  await whisperUpload( formData);\n                mlog('whisper 内容>> ', whisper );\n                let opt={duration:0,...promptMsg.opt };\n                opt.duration= dd.duration??0;\n                updateChatSome(  +uuid2, dataSources.value.length-1, {text:whisper.text,opt } );\n                dd.prompt= whisper.text;\n                //return ;\n            }catch(e){\n                updateChatSome(  +uuid2, dataSources.value.length-1, {text:`${t('mj.fail')}：${e}` } );\n                return ;\n            }\n            \n        }else{\n        \n            addChat(  +uuid2, promptMsg );\n            homeStore.setMyData({act:'scrollToBottom'});\n        }\n       \n\n\n       \n        let outMsg: Chat.Chat={\n            dateTime: new Date().toLocaleString(),\n            text: t('mj.thinking') ,//'思考中...',\n            loading: true,\n            inversion: false,\n            error: false,\n            conversationOptions: null,\n            requestOptions: { prompt: dd.prompt, options: {  } },\n            uuid:+uuid2,\n            model ,\n            myid: `${Date.now()}` \n        }\n        // if(gptConfigStore.myData.gpts){\n        //     outMsg.logo= gptConfigStore.myData.gpts.logo ;\n        // }\n        //  const chatSet = new chatSetting(   +st.value.uuid  );\n        // const nGptStore =   chatSet.getGptConfig()  ;\n        //chatSet\n        if( nGptStore.gpts ){\n            outMsg.logo= nGptStore.gpts.logo ;\n        }\n        addChat(  +uuid2, outMsg  )\n        st.value.index= dataSources.value.length - 1;\n        if(textRz.value.length>=0) textRz.value = [ ];\n\n        homeStore.setMyData({act:'scrollToBottom'})\n        let historyMesg=  await getMessage();\n        mlog('historyMesg', historyMesg );\n        //return ;\n        let message= [ {  \"role\": \"system\", \"content\": getSystemMessage(  +uuid2) },\n                ...historyMesg ];\n\n        if ( isNewModel( model ) ) {\n            message= [  ...historyMesg ];\n        }\n        if( dd.fileBase64 && dd.fileBase64.length>0 ){\n             let arr = dd.fileBase64.filter( (ff:string)=>ff.indexOf('http')>-1);\n            //if(  model=='gpt-4-vision-preview' || model=='gemini-pro-1.5'){\n            if( isCanBase64Model(model) &&arr.length==0 ){ \n                let obj={\n                        \"role\": \"user\",\n                        \"content\": [] as any\n                }\n                // //\"Generate code for a web page that looks exactly like this.\"\n                obj.content.push({ \"type\": \"text\",      \"text\": dd.prompt  });\n                dd.fileBase64.forEach((f:any)=>{\n                    obj.content.push({ \"type\": \"image_url\",  \"image_url\": {url:f }   });\n                });\n                message.push(obj); \n            }else{\n                let cc= dd.prompt;\n                //附件需要时远程的图片链接 或者文件 链接 \n                if(arr.length>0) cc = arr.join(' ')+' '+ cc ;\n                message.push({  \"role\": \"user\",  \"content\": cc })\n            }\n        }else{\n            message.push({  \"role\": \"user\",  \"content\": dd.prompt })\n        }\n        let opt={};\n        if( n=='gpt.whisper'){\n            opt= {\n                file: dd.file\n            }\n        }\n        submit(model , message,opt );\n \n    }else if(n=='abort'){\n       controller.value && controller.value.abort();\n    }else if(n=='gpt.resubmit'){\n        //  if(checkDisableGpt4(gptConfigStore.myData.model)){\n        //     ms.error( t('mj.disableGpt4') );\n        //     return false;\n        // }\n        const dd:any = homeStore.myData.actData;\n        let  uuid2 =  dd.uuid?? uuid;\n        st.value.uuid =  uuid2 ;\n        st.value.index = +dd.index;\n        \n         \n        \n\n        mlog('gpt.resubmit', dd  ) ;\n        let historyMesg= await  getMessage( (+dd.index)-1,1  ); //\n        mlog('gpt.resubmit historyMesg', historyMesg );\n        let nobj = dataSources.value[ dd.index ];\n        //mlog('gpt.resubmit model', nobj.model  );\n        let model = nobj.model\n        if(!model) model= 'gpt-3.5-turbo';\n        if(checkDisableGpt4(  model )){\n            ms.error( t('mj.disableGpt4') );\n            return false;\n        }\n        //return ;\n        if(['whisper-1','midjourney'].indexOf(model)>-1){\n            ms.error( t('mj.noSuppertModel') );\n            return; \n        }\n\n        controller.value = new AbortController();\n        let message= [ {  \"role\": \"system\", \"content\": getSystemMessage(+st.value.uuid ) },\n                ...historyMesg ]; \n        if ( isNewModel( model ) ) {\n            message= [  ...historyMesg ];\n        }\n        textRz.value=[];\n        submit(model, message );\n\n    }else if(n=='gpt.ttsv2'){ \n        const actData:any = homeStore.myData.actData;\n        mlog('gpt.ttsv2',actData );\n        st.value.index= actData.index;\n        st.value.uuid= actData.uuid;\n        ms.info( t('mj.ttsLoading'));\n        const chatSet = new chatSetting(   +st.value.uuid  );\n        const nGptStore =   chatSet.getGptConfig()  ; \n\n        subTTS({model:'tts-1',input: actData.text , voice:nGptStore.tts_voice }).then(d=>{\n                ms.success( t('mj.ttsSuccess'));\n                mlog('subTTS',d );\n                //d.player.play(); \n                //textRz.value.push('ok');\n                updateChatSome( +st.value.uuid,  st.value.index \n                , { \n                dateTime: new Date().toLocaleString(),loading: false \n                \n                ,opt:{duration:d.duration,lkey:d.saveID }\n                });\n               // goFinish();\n                setTimeout(() => { \n                    homeStore.setMyData({act:'playtts',actData:{ saveID:d.saveID} });\n                }, 100);\n            }).catch(e=>{\n                let  emsg =   (JSON.stringify(  e.reason? JSON.parse( e.reason ):e,null,2)); \n                if(e.message!='canceled' && emsg.indexOf('aborted')==-1 ) textRz.value.push(\"\\n\"+t('mjchat.failReason')+\" \\n```\\n\"+emsg+\"\\n```\\n\");\n                //goFinish();\n            });\n\n    }  \n    \n})\n\nconst submit= (model:string, message:any[] ,  opt?:any )=>{\n    mlog('提交Model', model  );\n    const chatSet = new chatSetting(   +st.value.uuid  );\n    const nGptStore =   chatSet.getGptConfig()  ; \n    controller.value = new AbortController();\n        if(model=='whisper-1'){\n            \n            //mlog('whisper-12323',opt  ); \n            const formData = new FormData( ); \n            formData.append('file', opt.file );\n            formData.append('model', 'whisper-1'); \n\n            //GptUploader('/v1/audio/transcriptions',formData).then(r=>{\n            whisperUpload( formData).then(r=>{\n                //mlog('语音识别成功', r ); \n                textRz.value.push(r.text);\n                goFinish();\n            }).catch(e=>{\n                let emsg =( ( e.message?? JSON.stringify(e)) );\n                textRz.value.push(\"\\n\"+t('mj.failOcr')+\":\\n```\\n\"+emsg+\"\\n```\\n\");\n                goFinish();\n            });\n            return ;\n        }\n        else if( isTTS(model)){\n            let text  = message[message.length-1].content;\n            mlog('whisper-tts',  message[message.length-1] , text  ); \n            subTTS({model,input: text, voice:nGptStore.tts_voice }).then(d=>{\n                mlog('subTTS',d );\n                //d.player.play(); \n                //textRz.value.push('ok');\n                updateChatSome( +st.value.uuid,  st.value.index \n                , { \n                dateTime: new Date().toLocaleString(),loading: false \n                ,text:'ok'\n                ,opt:{duration:d.duration,lkey:d.saveID }\n                });\n                goFinish();\n                setTimeout(() => { \n                    homeStore.setMyData({act:'playtts',actData:{ saveID:d.saveID} });\n                }, 100);\n            }).catch(e=>{\n                let  emsg =   (JSON.stringify(  e.reason? JSON.parse( e.reason ):e,null,2)); \n                if(e.message!='canceled' && emsg.indexOf('aborted')==-1 ) textRz.value.push(\"\\n\"+t('mjchat.failReason')+\" \\n```\\n\"+emsg+\"\\n```\\n\");\n                goFinish();\n            });\n\n        }else{\n        //controller.signal\n            subModel( {message,model\n            ,uuid:st.value.uuid //当前会话\n            ,onMessage:(d)=>{\n                mlog('🐞消息',d);\n                \n                if(d.isAll){\n                    textRz.value= [d.text];\n                }else{\n                    textRz.value.push(d.text);\n                }\n            }\n            ,onError:(e:any)=>{\n                mlog('onError',e)\n                let  emsg =   (JSON.stringify(  e.reason? JSON.parse( e.reason ):e,null,2));\n                //if(emsg=='{}' ) emsg= JSON.stringify(e );\n\n                if(e.message!='canceled' && emsg.indexOf('aborted')==-1 ) textRz.value.push(\"\\n\"+t('mjchat.failReason')+\"\\n```\\n\"+emsg+\"\\n```\\n\");\n                goFinish();\n            }\n            ,signal:controller.value.signal,\n            }).then(()=>goFinish() ).catch(e=>{\n                if(e.message!='canceled')  textRz.value.push(\"\\n\"+t('mj.fail')+\":\\n```\\n\"+(e.reason??JSON.stringify(e,null,2)) +\"\\n```\\n\")\n                goFinish();\n            });\n        }\n}\n\nhomeStore.setMyData({isLoader:false});\n</script>\n<template>\n \n</template>"
  },
  {
    "path": "src/views/mj/aiGptInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref ,computed,watch, onMounted } from 'vue';\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { t } from '@/locales'\nimport { NInput ,NButton,useMessage,NImage,NTooltip, NAutoComplete,NTag\n,NPopover,NModal, NDropdown  } from 'naive-ui'\nimport { SvgIcon } from '@/components/common';\nimport { canVisionModel, GptUploader, mlog, upImg,getFileFromClipboard,isFileMp3\n    ,countTokens, checkDisableGpt4, Recognition, regCookie,isCanBase64Model } from '@/api';\nimport { gptConfigStore, homeStore,useChatStore } from '@/store';\nimport { AutoCompleteOptions } from 'naive-ui/es/auto-complete/src/interface';\nimport { RenderLabel } from 'naive-ui/es/_internal/select-menu/src/interface';\nimport { useRoute } from 'vue-router' \nimport aiModel from \"@/views/mj/aiModel.vue\"\nimport AiMic from './aiMic.vue';\nimport { useIconRender } from '@/hooks/useIconRender'\nimport VueTurnstile from 'vue-turnstile';\n\nconst { iconRender } = useIconRender()\n//import FormData from 'form-data'\nconst route = useRoute() \nconst chatStore = useChatStore()\n\nconst emit = defineEmits(['update:modelValue'])\nconst props = defineProps<{ modelValue:string,disabled?:boolean,searchOptions?:AutoCompleteOptions,renderOption?: RenderLabel }>();\nconst fsRef = ref()\nconst st = ref<{fileBase64:string[],fileName:string[],isLoad:number,isShow:boolean,showMic:boolean,micStart:boolean}>({fileBase64:[],fileName:[],isLoad:0\n    ,isShow:false,showMic:false , micStart:false})\nconst { isMobile } = useBasicLayout()\nconst placeholder = computed(() => {\n  if (isMobile.value)\n    return t('chat.placeholderMobile')\n  return t('chat.placeholder');//可输入说点什么，也可贴截图或拖拽文件\n})\n\n\n\nconst { uuid } = route.params as { uuid: string }\n\nconst dataSources = computed(() => chatStore.getChatByUuid(+uuid))\n\nconst handleSubmit = ( ) => {\n    if( mvalue.value==''  ) return ;\n    if(checkDisableGpt4(gptConfigStore.myData.model)){\n        ms.error( t('mj.disableGpt4') );\n        return false;\n    }\n    if( homeStore.myData.isLoader  ) { \n        return ;\n    }\n    let obj={\n        prompt: mvalue.value,\n        fileBase64:st.value.fileBase64,\n        fileName:st.value.fileName\n    }\n    homeStore.setMyData({act:'gpt.submit', actData:obj });\n    mvalue.value='';\n    st.value.fileBase64=[];\n    st.value.fileName=[];\n    return false;\n}\nconst ms= useMessage();\nconst mvalue = computed({\n  get() { return props.modelValue  },\n  set(value) {  emit('update:modelValue', value) }\n})\nfunction selectFile(input:any){\n\n   const file = input.target.files[0];\n   upFile( file );  \n}\n\nconst myToken =ref({remain:0,modelTokens:'4k'});\nconst funt = async ()=>{\n    const d = await countTokens( dataSources.value, mvalue.value ,chatStore.active??1002 ) \n    myToken.value=d ;\n    return d ;\n} \nwatch(()=>mvalue.value,   funt  )\nwatch(()=> dataSources.value ,  funt )\nwatch(()=> gptConfigStore.myData ,  funt,{deep:true} )\nwatch(()=> homeStore.myData.isLoader ,  funt,{deep:true} )\nfunt(); \n \n const upFile= (file:any )=>{\n    if(  !canVisionModel(gptConfigStore.myData.model )  ) {\n        if( isFileMp3(  file.name ) ){\n            mlog('mp3' , file); \n            //  const formData = new FormData( ); \n            // formData.append('file', file);\n            // formData.append('model', 'whisper-1'); \n\n            // GptUploader('/v1/audio/transcriptions',formData).then(r=>{\n            //     mlog('语音识别成功', r ); \n            // }).catch(e=>ms.error('上传失败:'+ ( e.message?? JSON.stringify(e)) ));\n            homeStore.setMyData({act:'gpt.whisper', actData:{ file , prompt:'whisper' } });\n            return ;\n\n        }else{ \n            upImg( file).then(d=>{\n                fsRef.value.value='';\n                if(st.value.fileBase64.findIndex(v=>v==d)>-1) {\n                    ms.error(t('mj.noReUpload')) ;//'不能重复上传'\n                    return ;\n                }\n                st.value.fileBase64.push(d)  \n                st.value.fileName.push(file.name)\n            } ).catch(e=>ms.error(e));\n        }\n    }else{\n        const formData = new FormData( );\n        //const file = input.target.files[0];\n        formData.append('file', file); \n        ms.info( t('mj.uploading') );\n        st.value.isLoad=1;\n        GptUploader('/v1/upload',formData).then(r=>{\n            //mlog('上传成功', r);\n             st.value.isLoad= 0 ;\n            if(r.url ){\n                ms.info(t('mj.uploadSuccess'));\n                if(r.url.indexOf('http')>-1) {\n                    st.value.fileBase64.push(r.url)\n                    st.value.fileName.push(file.name)\n                }else{\n                    st.value.fileBase64.push(location.origin +r.url)\n                    st.value.fileName.push(file.name)\n                }\n            }else if(r.error) ms.error(r.error);\n        }).catch(e=>{\n            st.value.isLoad= 0 ;\n            ms.error( t('mj.uploadFail')+ ( e.message?? JSON.stringify(e)) )\n        });\n    }\n }\n \n\nfunction handleEnter(event: KeyboardEvent) {\n  if (!isMobile.value) {\n    if (event.key === 'Enter' && !event.shiftKey) {\n      event.preventDefault()\n      handleSubmit()\n    }\n  }\n  else {\n    if (event.key === 'Enter' && event.ctrlKey) {\n      event.preventDefault()\n      handleSubmit()\n    }\n  }\n}\n\nconst acceptData = computed(() => {\n  if(  canVisionModel(gptConfigStore.myData.model) ) return \"*/*\";\n  return  \"image/jpeg, image/jpg, image/png, image/gif, .mp3, .mp4, .mpeg, .mpga, .m4a, .wav, .webm\"\n})\n\nconst drop = (e: DragEvent) => {\n  e.preventDefault();\n  e.stopPropagation();\n  if( !e.dataTransfer || e.dataTransfer.files.length==0 ) return;\n  const files =    e.dataTransfer.files;\n  upFile(files[0]);\n  //mlog('drop', files);\n}\nconst paste=   (e: ClipboardEvent)=>{\n    let rz =   getFileFromClipboard(e); \n    if(rz.length>0 ) upFile(rz[0]);\n}\n \n\nconst sendMic= (e:any )=>{\n    mlog('sendMic', e );\n    st.value.showMic=false;\n    let du = 'whisper.wav';// (e.stat && e.stat.duration)?(e.stat.duration.toFixed(2)+'s'):'whisper.wav';\n    const file = new File([e.blob], du, { type: 'audio/wav' });\n    homeStore.setMyData({act:'gpt.whisper', actData:{ file , prompt:'whisper',duration : e.stat?.duration } });\n}\n\n//语音识别ASR\nconst goASR=()=>{\n    const olod = mvalue.value;\n    const rec= new Recognition();\n    let rz= '';\n    rec.setListener( (r:string)=>{\n        //mlog('result ', r  );\n        rz= r ; \n        mvalue.value= r;\n        st.value.micStart= true \n    }).setOnEnd( ( )=>{\n        //mlog('rec end');\n        mvalue.value= olod+rz;\n        ms.info( t('mj.micRecEnd'));\n        st.value.micStart= false \n    }).setOpt({\n        timeOut:2000,\n        onStart:()=>{ ms.info( t('mj.micRec')); st.value.micStart= true },\n    }).start();\n}\n\nconst drOption=[\n    {\n        label:  t('mj.micWhisper'),\n        key: \"whisper\",\n        icon:iconRender({ icon: 'ri:openai-fill' }),\n    },{\n        label:  t('mj.micAsr'),\n        icon:iconRender({ icon: 'ri:chrome-line' }),\n        key: \"asr\"\n    }\n]\nconst handleSelectASR = ( key: string | number )=>{ \n    if(key=='asr')    goASR(); \n    if(key=='whisper')   st.value.showMic=true; \n}\n\n\nconst appearance = computed(() => {\n   return homeStore.myData.vtoken?'interaction-only':'always'\n})\nconst tRef= ref();\n//const vt= ref<{thandel?:any}>({ });\nonMounted( ()=> { \n   if(homeStore.myData.session.turnstile) {\n       setTimeout( tRef.value.render  ,4000 )\n       //vt.value.thandel= setInterval( tRef.value.reset , 8300)\n   }\n});\n// onUnmounted( ()=>{\n//     if(vt.value.thandel) clearInterval( vt.value.thandel)\n// });\nwatch(()=> homeStore.myData.vtoken ,  regCookie  )\n\n</script>\n<template>\n<vue-turnstile ref=\"tRef\"  :site-key=\"homeStore.myData.session.turnstile\" :appearance=\"appearance\"    v-model=\"homeStore.myData.vtoken\" v-if=\"homeStore.myData.session.turnstile\" />\n<!-- <div>{{ homeStore.myData.vtoken }}</div> -->\n<div v-if=\"st.showMic\" class=\"  myinputs flex justify-center items-center\" >\n    <AiMic @cancel=\"st.showMic=false\" @send=\"sendMic\" />\n</div>\n<div class=\"  myinputs\"  @drop=\"drop\" @paste=\"paste\" v-else>\n\n    <input type=\"file\" id=\"fileInput\"  @change=\"selectFile\"  class=\"hidden\" ref=\"fsRef\"   :accept=\"acceptData\"/>\n    <div class=\"w-full relative\">\n        <div class=\"flex items-base justify-start pb-1 flex-wrap-reverse\" v-if=\"st.fileBase64.length>0 \"> \n            <div class=\"w-[60px] h-[60px] rounded-sm bg-slate-50 mr-1 mt-1 text-red-300 relative group\" v-for=\"(v,ii) in st.fileBase64\">\n            <NImage :src=\"v\" object-fit=\"cover\" class=\"w-full h-full\" >\n                <template #placeholder>\n                    <a class=\"w-full h-full flex items-center justify-center  text-neutral-500\" :href=\"v\" target=\"_blank\" >\n                        <SvgIcon icon=\"mdi:download\" />{{ $t('mj.attr1') }} {{ ii+1 }}\n                    </a>\n                </template>\n            </NImage> \n            <SvgIcon icon=\"mdi:close\" class=\"hidden group-hover:block absolute top-[-5px] right-[-5px] rounded-full bg-red-300 text-white cursor-pointer\" @click=\"st.fileBase64.splice(st.fileBase64.indexOf(v),1)\"></SvgIcon>\n            </div>\n        </div>\n        <div class=\"absolute bottom-0 right-0 z-1\">\n            <NPopover trigger=\"hover\">\n                <template #trigger>\n                    <NTag type=\"info\" round size=\"small\" style=\"cursor: pointer; \" :bordered=\"false\" >\n                        <div class=\"opacity-60 flex\"  >  \n                        <SvgIcon icon=\"material-symbols:token-outline\"  /> {{ $t('mj.remain') }}{{ myToken.remain }}/{{ myToken.modelTokens }}\n                        </div>\n                    </NTag>\n                </template>\n                <div class=\"w-[300px]\">\n                {{ $t('mj.tokenInfo1') }}\n                <p class=\"py-1\" v-text=\"$t('mj.tokenInfo2')\"> </p>\n                <p class=\" text-right\">\n                <NButton @click=\"st.isShow=true\" type=\"info\" size=\"small\">{{ $t('setting.setting') }}</NButton>\n                </p>\n                </div>\n                  \n            </NPopover>\n          \n        </div>\n    </div>\n    <NAutoComplete v-model:value=\"mvalue\" :options=\"searchOptions\" :render-label=\"renderOption\" >\n        <template #default=\"{ handleInput, handleBlur, handleFocus }\">\n        <NInput ref=\"inputRef\"  v-model:value=\"mvalue\"    type=\"textarea\"\n            :placeholder=\"placeholder\"  :autosize=\"{ minRows: 1, maxRows: isMobile ? 4 : 8 }\"\n            @input=\"handleInput\"\n            @focus=\"handleFocus\"\n            @blur=\"handleBlur\" \n            @keypress=\"handleEnter\"    >\n            <template #prefix>\n                <div  class=\" relative; w-[22px]\">\n                    <n-tooltip trigger=\"hover\">\n                    <template #trigger>\n                    <SvgIcon icon=\"line-md:uploading-loop\" class=\"absolute bottom-[10px] left-[8px] cursor-pointer\" v-if=\"st.isLoad==1\"></SvgIcon>\n                    <SvgIcon icon=\"ri:attachment-line\" class=\"absolute bottom-[10px] left-[8px] cursor-pointer\" @click=\"fsRef.click()\" v-else></SvgIcon>\n                    </template>\n                    <div v-if=\"canVisionModel(gptConfigStore.myData.model)\" v-html=\"$t('mj.upPdf')\" >\n                        \n                    </div>\n                    <div v-else-if=\"isCanBase64Model(gptConfigStore.myData.model)\" v-html=\"$t('mj.upImg2')\"></div>\n                    <div v-else v-html=\"$t('mj.upImg')\"> </div>\n                    </n-tooltip>\n                </div>\n                <!-- <div  class=\" relative; w-[22px]\">\n                    <SvgIcon icon=\"bi:mic\"  class=\"absolute bottom-[10px] left-[30px] cursor-pointer\" @click=\"st.showMic=true\"></SvgIcon>\n                </div> -->\n                <n-dropdown trigger=\"hover\" :options=\"drOption\" @select=\"handleSelectASR\">\n                    <div  class=\" relative; w-[22px]\">\n                        <div class=\"absolute bottom-[14px] left-[31px]\" v-if=\"st.micStart\">\n                            <span class=\"relative flex h-3 w-3\" >\n                                <span class=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-red-500 opacity-75\"></span>\n                                <span class=\"relative inline-flex rounded-full h-3 w-3 bg-red-400\"></span>\n                            </span>\n                        </div>\n                        <!-- <SvgIcon icon=\"bi:mic\"  class=\"absolute bottom-[10px] left-[55px] cursor-pointer\" @click=\"goASR()\"></SvgIcon> -->\n                        <SvgIcon icon=\"bi:mic\"  class=\"absolute bottom-[10px] left-[30px] cursor-pointer\"></SvgIcon>\n                    </div>\n                </n-dropdown>\n                \n            </template>\n            <template #suffix>\n                <div  class=\" relative; w-[40px] \">\n                    <div class=\"absolute bottom-[-3px] right-[0px] \">\n                        <NButton type=\"primary\" :disabled=\"disabled || homeStore.myData.isLoader \"     @click=\"handleSubmit\" >\n                         \n                            <template #icon>\n                            <span class=\"dark:text-black\">\n                                <SvgIcon icon=\"ri:stop-circle-line\" v-if=\"homeStore.myData.isLoader\" /> \n                                <SvgIcon icon=\"ri:send-plane-fill\"   v-else/> \n                            </span>\n                            </template>\n                            \n                        </NButton>\n                    </div>\n                </div>\n            </template>\n        </NInput>\n        </template>\n    </NAutoComplete>\n         <!-- translate-y-[-8px]       -->\n</div>\n\n<NModal v-model:show=\"st.isShow\"   preset=\"card\"  :title=\"$t('mjchat.modelChange')\" class=\"!max-w-[620px]\" @close=\"st.isShow=false\" >  \n        <aiModel @close=\"st.isShow=false\"/>\n</NModal>\n\n<!-- <n-drawer v-model:show=\"st.showMic\" :width=\"420\" :on-update:show=\"onShowFun\">\n    <n-drawer-content title=\"录音\" closable>\n        <AiMic />\n    </n-drawer-content>\n</n-drawer> -->\n\n</template>\n<style    >\n.myinputs .n-input .n-input-wrapper{\n     @apply items-stretch; \n    \n}\n</style>"
  },
  {
    "path": "src/views/mj/aiGpts.vue",
    "content": "<script setup lang=\"ts\">\nimport { NDrawer,NDrawerContent,NInput } from \"naive-ui\";\nimport { ref, watch } from \"vue\";\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { homeStore } from \"@/store\";\nimport AiGptsCom from \"./aiGptsCom.vue\";\nimport { SvgIcon } from \"@/components/common\";\nconst { isMobile } = useBasicLayout()\nconst qref= ref();\nconst st =ref({showImg:false,q:''});\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='showgpts')   st.value.showImg=true;\n})\nconst search=()=>{\n    if(!st.value.q ) return ;\n    qref.value.searchQ(st.value.q);\n }\nconst toq=( d:any )=>{\n    st.value.q= d.q;\n}\n</script>\n<template>\n <n-drawer v-model:show=\"st.showImg\"   :placement=\"isMobile?'bottom':'right'\"  :class=\"isMobile?['!h-[90vh]']: ['!w-[80vw]']\" style=\"--n-body-padding:0\">\n    <n-drawer-content  class=\"mydrawer\" :closable=\"isMobile\">\n      <template #header>\n        <div class=\"flex justify-between items-center w-full\">\n        <!-- <SvgIcon icon=\"uil:search\" class=\"pr-2 text-[28px] cursor-pointer\"></SvgIcon> GPT store -->\n        <div class=\"pr-4\">GPT store</div>\n        <div class=\" max-w-[400px]\">\n            <n-input round :placeholder=\"$t('mjchat.searchPlaceholder')\" clearable v-model:value=\"st.q\" @keydown.enter=\"search()\" >\n                <template #prefix>\n                    <SvgIcon icon=\"uil:search\"/>\n                </template>\n                <template #suffix>\n                    <div class=\"cursor-pointer\" @click=\"search()\">{{ $t('mjchat.search')}}</div>\n                </template>\n            </n-input>\n        </div>\n        </div>\n      </template>\n      <AiGptsCom @close=\"st.showImg=false\" ref=\"qref\" :q=\"st.q\" @toq=\"toq\" />\n    </n-drawer-content>\n</n-drawer>\n</template>\n<style>\n.mydrawer .n-drawer-header__main{\n @apply flex-1;\n}\n</style>"
  },
  {
    "path": "src/views/mj/aiGptsAdd.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { SvgIcon } from \"@/components/common\";\nimport { NInput,useMessage } from 'naive-ui';\nimport { t } from '@/locales';\nimport { mlog, myFetch } from '@/api';\n\n\nconst ms = useMessage();\nconst st= ref({q:'',gid:''});\nconst doAdd=async ()=>{\n    mlog('q=',st.value.q,  st.value.gid );\n    if( !st.value.gid ){\n        ms.error( t('mjchat.gidError')); //\n        return \n    }\n    const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/add/${ st.value.gid }`; \n    const d = await myFetch(gptUrl );\n    if(d.error!=0) return ms.error( d.error_des);\n    //data.gpts\n    let msg= t('mjchat.success3') +' '+ d.data?.gpts?.name\n    ms.success( msg );\n    mlog('rz=',d);\n}\nfunction extractGStrings(input: string): string[] { \n    const pattern = /g-[^/]+/g; \n    const matches = input.match(pattern); \n    return matches ? matches : [];\n}\n\n// // 测试字符串\n// const inputString = \"00/g/g-hRCqiqVlM-tutor-me/abdsdsd\";\n\n// // 提取匹配的子字符串\n// const result = extractGStrings(inputString);\nwatch(()=>st.value.q, (n)=>{\n    st.value.gid='';\n    if(n) {\n        st.value.gid= extractGStrings(n)[0]??'';\n    }\n})\n</script>\n<template>\n\n \n    <n-input round :placeholder=\"$t('mjchat.addPlaceholder')\" clearable v-model:value=\"st.q\" @keydown.enter=\"doAdd()\" >\n        <template #prefix>\n            <SvgIcon icon=\"ri:function-add-line\"/>\n        </template>\n        <template #suffix>\n            <div class=\"cursor-pointer\" @click=\"doAdd()\">\n            {{ $t('mjchat.addGPTS') }}\n            </div>\n        </template>\n    </n-input>\n    <div v-if=\"st.gid\" class=\"px-4 text-white/25 text-[12px]\">gid:{{ st.gid }}</div>\n \n</template>"
  },
  {
    "path": "src/views/mj/aiGptsCom.vue",
    "content": "<script setup lang=\"ts\"> \nimport { myFetch, gptsType, mlog, chatSetting,my2Fetch } from '@/api';\nimport { homeStore,gptConfigStore,useChatStore, gptsUlistStore } from '@/store';\nimport { ref,computed ,watch  } from 'vue';\nimport { useMessage ,NButton,NImage,NTag,NPopover} from 'naive-ui';\nimport { SvgIcon } from '@/components/common';\nimport { useRouter } from 'vue-router';\nimport { t } from '@/locales'; \nimport aiGptsAdd  from \"./aiGptsAdd.vue\"\nimport { time } from 'console';\nimport { sleep } from '@/api/suno';\n\nconst router = useRouter()\nconst ms = useMessage();\nconst chatStore = useChatStore()\nconst emit = defineEmits(['close','toq']);\nconst pp= defineProps<{q:string}>( );\n//const gptsList= ref<gptsType[]>([]);\nconst gptsPageList = ref<gptsType[]>([]);\nconst gptsInitList = ref<gptsType[]>([]);\nconst gptsSearchList = ref<gptsType[]>([]);\nconst st= ref({loadPage:false,q:'',tab:'',search:false,showAdd:false});\nconst tag= ref(['画图','文件','发票']);\nconst load= async ()=>{\n    \n    // const gptUrl= homeStore.myData.session.gptUrl?  homeStore.myData.session.gptUrl :'';\n    // mlog('load',gptUrl );\n     let d;\n    if( homeStore.myData.session.gptUrl ){\n       d = await my2Fetch( homeStore.myData.session.gptUrl  );\n    }else {\n        d = await myFetch('https://gpts.ddaiai.com/open/gpts');\n    }\n    gptsInitList.value = d.gpts as gptsType[];\n    tag.value= d.tag as string[];\n}\nconst go= async ( item: gptsType)=>{\n    \n    let uuid=  chatStore.active\n    if( uuid ){\n       const chat= chatStore.getChatByUuid( uuid );\n       if( chat.length>0){\n            uuid=  Date.now()\n            chatStore.addHistory({ title: 'New Chat', uuid, isEdit: false })\n            await sleep(500);\n       }\n    }\n\n    const saveObj= {model:  `${ item.gid }`   ,gpts:item}\n    gptConfigStore.setMyData(saveObj); \n    if( uuid ){ //保存到对话框\n        const  chatSet = new chatSetting(uuid );\n        // if( chatSet.findIndex()>-1 ){\n        //    mlog('含有： ', chatSet.findIndex()  );\n          \n        // }\n        //全保存\n        chatSet.save( saveObj )\n    }\n    ms.success(t('mjchat.success2'));\n    const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/use`; \n    myFetch(gptUrl,item );\n    emit('close');\n    mlog('go local ', homeStore.myData.local );\n    if(homeStore.myData.local!=='Chat') router.replace({name:'Chat',params:{uuid: uuid }});\n\n    gptsUlistStore.setMyData( item );\n\n}\nconst pageLoad= async ()=>{\n    st.value.loadPage= true;\n    const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/list/${ gptsPageList.value.length}`; \n    let d = await myFetch(gptUrl);\n    st.value.loadPage= false;\n\n    let rz = d.data.list  as gptsType[];\n    gptsPageList.value = gptsPageList.value.concat(rz) //rz.concat( gptsPageList.value  )\n}\nconst gptsList = computed(()=>{\n    let rz:gptsType[]=[];\n    if(st.value.tab=='search'){\n        return gptsSearchList.value;\n        //mlog('search', st.value.tab );\n    }\n    return rz.concat( gptsInitList.value,gptsPageList.value );\n})\nconst searchQ= async (q:string)=>{\n    st.value.q= q;\n    st.value.tab= 'search';\n    st.value.search= true;\n    const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/search?q=${ st.value.q }`; \n    let d = await myFetch(gptUrl);\n      st.value.search= false;\n    gptsSearchList.value = d.data.list  as gptsType[];\n}\nconst goSearch =(q:string)=>{\n    emit('toq',{q});\n    searchQ(q);\n}\n\nconst badgo=(item:gptsType ,e:Event )=>{\n    e.stopPropagation();\n    mlog('badgo', item );\n    const gptUrl= `https://gpts.ddaiai.com/open/gptsapi/bad`; \n    myFetch(gptUrl,item );\n    item.bad= item.bad?(+item.bad+1):1;\n}\n\nwatch(()=>pp.q,(n)=>{\n    if(n=='') st.value.tab= '';\n})\nload();\ndefineExpose({ searchQ })\n</script>\n<template>\n\n<div class=\"w-full h-full p-4\">\n    <template v-if=\"gptsList.length>0\">\n        <div class=\"flex items-center justify-start line-clamp-1 pb-4\"  >\n            <div class=\"m-1 cursor-pointer\" v-for=\"v in tag\" @click=\"goSearch(v)\">\n            <n-button strong   round size=\"small\" type=\"success\" v-if=\"v==pp.q\">{{ v }}</n-button>\n            <n-button strong secondary round size=\"small\" type=\"success\" v-else>{{ v }}</n-button>\n            </div>\n            <div  class=\"m-1 cursor-pointer\">\n                 <n-button strong secondary round size=\"small\" type=\"success\" @click=\"st.showAdd=!st.showAdd\"> {{ $t('mjchat.addGPTS') }}</n-button>\n            </div>\n        </div>\n        <div class=\"pb-4\" v-if=\"st.showAdd\">\n            <div class=\"w-[400px]\"><aiGptsAdd/></div> \n        </div>\n\n        <div class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\"  >\n            \n            <div @click=\"go(v)\" v-for=\"v in gptsList\" class=\"group relative flex gap-3 rounded-2xl bg-[#e8eaf1] p-5 dark:bg-neutral-600 cursor-pointer \">\n            \n                <div class=\"min-w-0 flex-1 mt-[-10px]\">\n                    <div class=\"flex justify-between items-center\">\n                        <h3 class=\" transition   text-lg font-semibold line-clamp-1\"> {{ v.name }}</h3>\n                        \n                        \n                    </div>\n                    <div class=\"mt-0.5 text-zinc-400 text-md line-clamp-2\">{{ v.info }}</div>\n                     \n                </div>\n                <NImage :src=\"v.logo\" :preview-disabled=\"true\" lazy\n                class=\"group-hover:scale-[130%] duration-300 shrink-0 overflow-hidden bg-base object-cover rounded-full bc-avatar w-[80px] h-[80px]\">\n                    <template #placeholder>\n                      <div class=\"w-full h-full justify-center items-center flex\"  >\n                       <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[60px] text-green-300\"   ></SvgIcon>\n                      </div>\n                    </template>\n                </NImage>\n                <!-- <img  class=\"group-hover:scale-[130%] duration-300 shrink-0 overflow-hidden bg-base object-cover rounded-full bc-avatar w-[80px] h-[80px]\" :src=\"v.logo\"/> -->\n                <div class=\"space-x-1 flex absolute bottom-2 left-4\">\n                     <n-popover trigger=\"hover\">\n                        <template #trigger>\n                        <n-tag type=\"success\" size=\"small\" round>\n                        <div class=\"flex items-center\"><SvgIcon icon=\"mdi:hot\"  ></SvgIcon>{{ v.use_cnt }}</div>\n                        </n-tag>\n                        </template>\n                        <span>使用热度</span>\n                    </n-popover>\n                     <n-popover trigger=\"hover\" >\n                        <template #trigger>\n                        <n-tag type=\"success\" size=\"small\" round >\n                        <div class=\"flex items-center cursor-pointer\" @click=\"badgo(v, $event )\"><SvgIcon icon=\"icon-park-outline:bad-two\"  ></SvgIcon>\n                        <span class=\"ml-[2px]\" > {{ v.bad }}</span>\n                        </div>\n                        </n-tag>\n                        </template>\n                         <span>不好用或应用已不存在请点这个</span>\n                    </n-popover>\n                </div>\n            </div>\n            \n        </div>\n        <div class=\"flex items-center justify-center py-10\" v-if=\"st.tab=='' \">\n            <div @click=\"pageLoad()\" v-if=\"st.loadPage\">{{ $t('mjchat.loading2') }}</div>\n            <NButton @click=\"pageLoad()\" v-else>{{ $t('mjchat.loadmore') }}</NButton>\n        </div>\n    </template>\n    <div class=\"h-full flex items-center justify-center flex-col\"  v-else-if=\"st.tab=='search' && !st.search\">\n        <div>{{ $t('mjchat.nofind') }}<b class=\" text-green-400\">{{st.q}}</b> {{$t('mjchat.nofind2')}}</div>\n        <div class=\"flex items-center justify-center flex-wrap\">\n            <div class=\"m-1 cursor-pointer\" v-for=\"v in tag\" @click=\"goSearch(v)\"><n-button strong secondary round size=\"small\" type=\"success\" >{{ v }}</n-button></div>\n        </div>\n        <div class=\"p-10\" >\n            <div class=\"w-[400px]\"><aiGptsAdd/></div> \n        </div>\n    </div>\n    <div class=\"h-full flex items-center justify-center\"  v-else>\n        {{ $t('mjchat.loading2') }}\n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/mj/aiIdeoInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue';\nimport { NSelect,NInput, useMessage,NButton,NTag } from 'naive-ui';\nimport { IdeoImageData, ideoFetch, mlog, upImg } from '@/api';\nimport { homeStore } from '@/store';\n\nconst vf=[{s:'width: 100%; height: 100%;',label:'1:1',value:'ASPECT_1_1'}\n,{s:'width: 100%; height: 75%;',label:'4:3',value:'ASPECT_4_3'}\n,{s:'width: 75%; height: 100%;',label:'3:4',value:'ASPECT_3_4'}\n,{s:'width: 100%; height: 50%;',label:'16:9',value:'ASPECT_16_9'}\n,{s:'width: 50%; height: 100%;',label:'9:16',value:'ASPECT_9_16'}\n ];\n\n const f= ref({\n    \"model\": \"V_2_TURBO\",\n    \"magic_prompt_option\": \"AUTO\",\n    \"prompt\": \"\",\n    \"aspect_ratio\": \"ASPECT_9_16\",\n    \"seed\": 123456,\n    //\"style_type\": \"REALISTIC\",\n    \"negative_prompt\": \"\",\n    //\"resolution\": \"RESOLUTION_576_1408\"\n  });\nconst st=ref({bili:0,image_url:'' ,seed:''});\nconst fsRef= ref() ;\nconst fsFile= ref<any>();\nconst ms = useMessage();\nfunction selectFile(input:any){\n    fsFile.value= input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        st.value.image_url= d;\n        fsRef.value=''\n    }).catch(e=>ms.error(e));\n    \n}\nconst createImg= async ()=>{\n    if(st.value.seed && !isNaN(parseInt(st.value.seed))){\n        f.value.seed= parseInt(st.value.seed);\n    }\n    f.value.aspect_ratio= vf[st.value.bili].value\n    let data:any ={\n        image_request:f.value,\n        file:fsFile.value,\n        model:'ideogram_'+f.value.model.toLocaleLowerCase(),\n        prompt: f.value.prompt,\n      //  fileBase64:st.value.image_url\n    }\n    if(st.value.image_url){\n        data.fileBase64=   st.value.image_url\n    }\n    // const d:any = await ideoFetch('/generate ' ,data ) \n    // mlog('img', d ); \n    // const dimg:IdeoImageData= d.data.data  \n    let obj= {\n        action:'gpt.dall-e-3',\n        data:data\n    }\n    homeStore.setMyData({act:'draw', actData:obj});\n}\nonMounted(()=>{\n    homeStore.setMyData({ms:ms });\n})\n\nconst clearInput = ()=>{\n    st.value.image_url='';\n    f.value.prompt='';\n    f.value.seed=123456;\n    fsFile.value= null;\n}\n</script>\n<template>\n<div class=\"overflow-y-auto bg-[#fafbfc]   dark:bg-[#18181c] h-full \">\n    <section class=\"mb-4\">\n         <div class=\" flex items-center justify-between space-x-1\">\n            <template  v-for=\"(item,index) in vf\" >\n            <section class=\"aspect-item flex-1 rounded border-2 dark:border-neutral-700 cursor-pointer\"  :class=\"{'active':index==st.bili}\"  @click=\"st.bili=index\">\n                <div class=\"aspect-box-wrapper mx-auto my-2 flex h-5 w-5 items-center justify-center\">\n                    <div class=\"aspect-box rounded border-2 dark:border-neutral-700\" :style=\"item.s\"></div>\n                </div>\n                <p class=\"mb-1 text-center text-sm\">{{ item.label }}</p>\n            </section>\n            </template>\n\n        </div>\n    </section> \n\n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('dance.model') }}</div>\n          <n-select v-model:value=\"f.model\" :options=\"'V_2,V_2_TURBO,V_1,V_1_TURBO'.split(',').map(v=>({label:v,value:v}))\" size=\"small\"  class=\"!w-[70%]\" :clearable=\"true\" />\n    </section>\n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>Seed</div>\n          <NInput  v-model:value=\"st.seed\" size=\"small\"  class=\"!w-[70%]\"  clearable :placeholder=\"$t('mj.seed')\" />\n    </section>\n    <section class=\"mb-4 flex justify-between items-center\" >\n         <div>{{ $t('mj.nohead') }}</div>\n          <NInput v-model=\"f.negative_prompt\" size=\"small\"  class=\"!w-[70%]\"  clearable :placeholder=\"$t('mj.negative_prompt')\" />\n    </section>\n\n    <section class=\"mb-4 flex justify-between items-center\" >\n         \n          <n-input v-model:value=\"f.prompt\" \n                :placeholder=\"$t('mj.ideopls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n    </section>\n    \n    <section class=\"mb-4 flex justify-between items-end\" >\n        <div class=\"relative\"> \n            <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n            <div   class=\"h-[80px] w-[80px]   overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n                <img :src=\"st.image_url\" v-if=\"st.image_url\" />\n                <div class=\"text-center\" v-else>{{ $t('video.selectimg') }}</div> \n                \n            </div>\n        </div>\n        <div class=\"text-right\">\n            <div  class=\" cursor-pointer pb-2\" @click=\"clearInput\"  v-if=\"st.image_url|| f.prompt \"><NTag type=\"success\" size=\"small\" :bordered=\"false\" round  ><span class=\"cursor-pointer\">{{$t('video.clear')}}</span></NTag></div>\n\n            <NButton type=\"primary\" @click=\"createImg()\" :disabled=\"!f.prompt\"  >{{ $t('mjchat.imgcreate') }}</NButton>\n        </div>\n    </section>\n    \n    \n</div>\n</template>"
  },
  {
    "path": "src/views/mj/aiListText.vue",
    "content": "<script setup lang=\"ts\">\nimport { gptConfigType } from '@/store';\nimport { NPopover, NAvatar } from \"naive-ui\";\nimport { SvgIcon } from '@/components/common'\n\ndefineProps<{myItem:Chat.History,myObj?:gptConfigType}>()\n</script>\n<template>\n<span class=\"flex justify-start items-center\">\n\n    <SvgIcon icon=\"ri:message-3-line\"   v-if=\"!myObj  \"  />\n    <n-avatar v-else-if=\"myObj.gpts\" :src=\"myObj.gpts.logo\" fallback-src=\"../../assets/avatar.jpg\" :size=\"18\" round/> \n    <SvgIcon icon=\"bi:chat\"  v-else/>\n</span>\n<div class=\"relative flex-1 overflow-hidden break-all text-ellipsis whitespace-nowrap\">\n    <slot/> \n    <span v-if=\"!myObj\">{{ myItem.title }}</span>\n    <n-popover v-else   placement=\"right-start\" trigger=\"hover\">\n        <template #trigger>\n        {{ myItem.title }}\n        </template>\n        <ul  > \n        <template v-if=\"myObj.gpts\">\n            <li class=\"flex justify-start items-center space-x-2\">\n            <n-avatar :src=\"myObj.gpts.logo\" fallback-src=\"../../assets/avatar.jpg\" round/> \n            <span >{{ myObj.gpts.name }}</span>\n            </li>\n            <li >ID: {{myObj.model }}</li>\n        </template>\n            <li v-else> {{ $t('mjset.model') }}: {{ myObj.model }}</li>\n            <li> {{ $t('mjchat.historyCnt') }}: {{ myObj.talkCount }}</li>\n            <li> {{ $t('mjchat.historyTCnt') }}: {{ myObj.max_tokens }}</li>\n            <li v-if=\"myObj.systemMessage\">{{ $t('mjchat.role') }}: {{ myObj.systemMessage }}</li>\n        </ul>\n    </n-popover>\n    \n</div>\n\n\n \n</template>"
  },
  {
    "path": "src/views/mj/aiMic.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api';\nimport { SvgIcon } from '@/components/common';\nimport Recorder from 'js-audio-recorder';\nimport  { NButton,useMessage,NButtonGroup } from \"naive-ui\"\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { ref,watch,onUnmounted } from 'vue'\nimport { t } from '@/locales';\n\nconst emit = defineEmits(['process' ,'send','cancel']);\nlet recorder = new Recorder();\ninterface statType{\n    duration: number\n    fileSize: number\n    vol: number\n}\nconst stat = ref<statType>({duration:0,fileSize:0,vol:0});\nconst st =ref({start:0,isGo:false});\n\nconst ms = useMessage();\nconst { isMobile } = useBasicLayout()\n\nrecorder.onprogress =  (params) => {\n    stat.value = {duration: params.duration , fileSize: params.fileSize, vol: params.vol }\n    //emit('process', stat.value);\n}\nconst start = ()=>{\n    recorder.start().then(()=>{\n        st.value.start=1;\n        st.value.isGo=true;\n        ms.info( t('mj.micIng') );\n    }).catch(e=>{\n        mlog('录音错误', e );\n        ms.error( t('mj.fail')+':'+e );\n        emit('cancel');\n    });\n}\nconst pause=()=>{\n    recorder.pause() \n    st.value.start=2;\n\n}\nconst pauseGoon=()=>{\n    recorder.resume();\n    st.value.start=1;\n    recorder.stopPlay();\n}\nconst send=()=>{\n    stop();\n    emit('send',{blob: recorder.getWAVBlob() , stat:stat.value });\n    stat.value= {duration:0,fileSize:0,vol:0} ;\n}\nconst play=()=>{\n    //if(st.value.start==1) pause();\n    recorder.play();\n    stop();\n}\nconst stopAdnRecord= ()=>{\n    stop();\n    start();\n    st.value.start=1;\n}\nconst stop=()=>{\n    st.value.start=0;\n    recorder.stop();\n    recorder.stopPlay();\n}\nconst cancal=()=>{\n    stop();\n    emit('cancel');\n}\nonUnmounted(() => {\n    recorder.stop();\n    recorder.destroy();\n}),\nwatch(()=> stat.value , (n)=> emit('process', stat.value) ,{deep:true} );\n\nstart();\n</script>\n<template> \n<template v-if=\"!st.isGo\">\n    <NButton @click=\"start()\" type=\"primary\" block round> \n        <template #icon><SvgIcon icon=\"bi:mic\"/></template>{{ $t('mj.mStart') }}\n    </NButton>\n</template>\n<n-button-group v-else>\n    <NButton @click=\"start()\" type=\"primary\" v-if=\"st.start==0\" > \n        <template #icon><SvgIcon icon=\"bi:mic\"/></template>{{ $t('mj.mStart') }}\n    </NButton>\n    <NButton type=\"primary\" @click=\"pause()\" v-if=\"st.start==1\">\n        <template #icon><SvgIcon icon=\"bi:pause-circle\"/></template>{{ $t('mj.mPause') }}\n    </NButton>\n    <NButton type=\"primary\" @click=\"pauseGoon()\" v-if=\"st.start==2\">\n        <template #icon><SvgIcon icon=\"bi:mic\"/></template>{{ $t('mj.mGoon') }}\n    </NButton>\n \n    <template v-if=\"stat.duration>0 \">\n        <NButton type=\"info\" @click=\"stopAdnRecord()\"  v-if=\"!isMobile\" >\n        <template #icon><SvgIcon icon=\"bi:bootstrap-reboot\"/></template>{{ $t('mj.mRecord') }}</NButton>\n\n        <NButton @click=\"play()\" type=\"info\">\n        <template #icon><SvgIcon icon=\"bi:play-circle\"/></template>{{ $t('mj.mPlay') }}</NButton> \n        <NButton @click=\"cancal()\" type=\"info\">\n        <template #icon><SvgIcon icon=\"ri:close-circle-line\"/></template>{{ $t('mj.mCanel') }}</NButton> \n\n        <NButton type=\"primary\" @click=\"send()\">\n        <template #icon><SvgIcon icon=\"ri:send-plane-fill\"></SvgIcon></template>\n        {{ $t('mj.mSent') }}\n        <span class=\"w-[30px]\" v-if=\"stat.duration>0 \">{{ stat?.duration.toFixed(1) }}s</span>\n        </NButton> \n    </template>\n</n-button-group> \n</template>"
  },
  {
    "path": "src/views/mj/aiMobileMenu.vue",
    "content": "<script setup lang=\"ts\">\nimport { SvgIcon } from '@/components/common';\nimport { homeStore } from '@/store'\nimport { computed,watch ,ref  } from 'vue'\nimport { router } from '@/router'\nimport { useRouter } from 'vue-router';\n\nimport aiDrawInput from './aiDrawInput.vue'; \nimport {NDrawerContent,NDrawer} from \"naive-ui\";\nimport { isDisableMenu } from '@/api';\nconst st= ref({show:true})\n\nconst goHome =computed(  () => {\n  //router.push('/')\n  return router.currentRoute.value.name\n});\nfunction drawSent(e:any){\n  st.value.show=false;\n  //$emit('drawSent', e)\n  homeStore.setMyData({act:'draw',actData:e});\n}\n\nwatch(()=>homeStore.myData.act, (n:string)=>{\n    if('showChat'==n){\n        router.push('/chat')\n    }\n    if('showDraw'==n){\n        router.push('/draw')\n        st.value.show=true;\n    }\n    if(n=='draw'){\n       st.value.show=false;\n    }\n});\nconst urouter = useRouter() //\n</script>\n<template>\n  <div class=\" bg-gray-100 dark:bg-[#282832] h-[55px] flex  justify-around  items-center dark:text-white/70 \" >\n      <div class=\"flex items-center justify-center flex-col\"  @click=\"urouter.push('/chat') && homeStore.setMyData({act:'showChat'}) \"   :class=\"[ goHome =='Chat' ? 'active' : '']\" >\n        <SvgIcon icon=\"ri:wechat-line\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">{{$t('mjtab.chat')}}</div>\n      </div>\n      <div  v-if=\"!isDisableMenu ( 'gpts')\"  class=\"flex items-center justify-center flex-col \"  @click=\"homeStore.setMyData({act:'showgpts'}) \" >\n        <SvgIcon icon=\"ri:apps-fill\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">GPTs</div>\n      </div>\n\n      <div v-if=\"!isDisableMenu ( 'realtime')\"    class=\"flex items-center justify-center flex-col \"  @click=\"homeStore.setMyData({act:'openRealtime'}) \" >\n        <SvgIcon icon=\"ri:mic-fill\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">{{$t('mj.rttab')}}</div>\n      </div>\n\n\n      <div v-if=\"!isDisableMenu ( 'draws')\" class=\"flex items-center justify-center flex-col \"  @click=\"homeStore.setMyData({act:'showDraw'}) \" :class=\"[goHome=='draw' ? 'active' : '']\" >\n        <SvgIcon icon=\"ic:outline-palette\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">{{$t('mjtab.draw')}}</div>\n      </div>\n\n      <div v-if=\"!isDisableMenu ( 'music')\"    class=\"flex items-center justify-center flex-col \"   @click=\"  urouter.push('/music')\"  :class=\"[ goHome =='music' ? 'active' : '']\" >\n        <SvgIcon icon=\"arcticons:wynk-music\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">{{ $t('suno.menu') }}</div>\n      </div>\n\n\n      <!-- <div  v-if=\"!isDisableMenu ( 'gallery')\"  class=\"flex items-center justify-center flex-col \" @click=\"homeStore.setMyData({act:'gallery'})\" >\n        <SvgIcon icon=\"material-symbols:imagesmode-outline\" class=\"text-3xl\"></SvgIcon>\n        <div class=\"text-[13px]\">{{$t('mjtab.gallery')}}</div>\n      </div>  -->\n  </div>\n\n  <n-drawer v-model:show=\"st.show\"  class=\"!h-[90vh] !max-h-[660px]\"     placement=\"bottom\" v-if=\"goHome=='draw'\">\n    <n-drawer-content   style=\"--n-body-padding:0\" class=\"h-full\">\n      <aiDrawInput @draw-sent=\"drawSent\" @close=\"st.show=false\"  />\n    </n-drawer-content>\n  </n-drawer>\n</template>"
  },
  {
    "path": "src/views/mj/aiModel.vue",
    "content": "<script setup lang=\"ts\">\nimport {NSelect, NInput,NSlider, NButton, useMessage,NTag,NPopselect ,NAvatar, NText} from \"naive-ui\"\nimport type { SelectRenderLabel, SelectRenderTag } from 'naive-ui'\nimport { ref ,computed,watch, onMounted,h} from \"vue\";\nimport {gptConfigStore, homeStore,useChatStore} from '@/store'\nimport { mlog,chatSetting } from \"@/api\";\nimport { t } from \"@/locales\";\n\nimport AiModelServer from \"./aiModelServer.vue\";\n \n\nconst emit = defineEmits(['close']);\nconst chatStore = useChatStore();\nconst uuid = chatStore.active;\n//mlog('uuid', uuid );\nconst chatSet = new chatSetting( uuid==null?1002:uuid);\n\nconst nGptStore = ref(  chatSet.getGptConfig() );\n\nconst config = ref({\nmodel:[ 'gpt-5.1','gemini-3-pro-preview','grok-4.1','gpt-5','gpt-5-mini','gpt-5-nano','o1','o1-2024-12-17', 'gpt-4-turbo-2024-04-09','o1-preview','o1-mini','o1-preview-2024-09-12','o1-mini-2024-09-12','chatgpt-4o-latest','gpt-4o-2024-11-20','gpt-4o-2024-08-06','gpt-4o-2024-05-13','gpt-4o-mini-2024-07-18','gpt-4o-mini','gpt-4o','gpt-4-turbo','gpt-4-0125-preview','gpt-3.5-turbo',`gpt-4-1106-preview`,`gpt-3.5-turbo-16k`,'gpt-4','gpt-4-0613','gpt-4-32k-0613' ,'gpt-4-32k','gpt-4-32k-0314',`gpt-3.5-turbo-16k-0613`\n,`gpt-4-vision-preview`,`gpt-3.5-turbo-1106` ,'gpt-3.5-turbo-0125'\n,'gpt-3.5-turbo-0301','gpt-3.5-turbo-0613','gpt-4-all','gpt-3.5-net'\n,'gemini-pro',\"gemini-pro-vision\",'gemini-pro-1.5',\"gemini-1.5-pro-exp-0801\"\n,'claude-3-7-sonnet-20250219'\n,'claude-3-5-sonnet-20241022','claude-3-sonnet-20240229','claude-3-opus-20240229','claude-3-haiku-20240307','claude-3-5-sonnet-20240620','suno-v3'\n,'deepseek-r1','deepseek-v3'\n,'grok-3','grok-3-reasoner','grok-3-deepsearch'\n,'gpt-4.5-preview-2025-02-27','gpt-4.5-preview'\n]\n,maxToken:16384\n}); \nconst st= ref({openMore:false,isShow:false ,server:'' });\nconst voiceList= computed(()=>{\n    let rz=[];\n    for(let o of \"alloy,echo,fable,onyx,nova,shimmer\".split(/[ ,]+/ig))rz.push({label:o,value:o}) \n    return rz;\n});\nconst modellist = computed(() => { //\n    let rz =[ ];\n    for(let o of config.value.model){\n        rz.push({label:o,value:o})\n    }\n    if(gptConfigStore.myData.userModel){\n        let arr = gptConfigStore.myData.userModel.split(/[ ,]+/ig);\n        //  let uniqueArray  = arr.filter((value, index, self) => {\n        //     return self.indexOf(value) === index;\n        // });\n        for(let o of arr ){\n            o && rz.push({label:o,value:o})\n        }\n    }\n    //服务端的 CUSTOM_MODELS 设置\n    if( homeStore.myData.session.cmodels ){\n        let delModel:string[] = [];\n        let addModel:string[]=[];\n        let isDelAll= false\n        homeStore.myData.session.cmodels.split(/[ ,]+/ig).map( (v:string)=>{\n            if(v.indexOf('-')==0){\n                delModel.push(v.substring(1))\n                if( v=='-all') isDelAll=true;\n            }else{\n                addModel.push(v);\n            }\n        });\n        mlog('cmodels',delModel,addModel);\n        if( isDelAll  )rz=[];\n        rz= rz.filter(v=> delModel.indexOf(v.value)==-1 );\n        addModel.map(o=>rz.push({label:o,value:o}) )\n        if (rz.length==0){\n            rz.push({label:'gpt-3.5-turbo',value:'gpt-3.5-turbo'}) \n        }\n    }\n\n    let uniqueArray: { label: string, value: string }[] = Array.from(\n        new Map(rz.map(item => [JSON.stringify(item), item]))\n        .values()\n    );\n    return uniqueArray ;\n});\nconst ms= useMessage();\n// const save = ()=>{ \n//     gptConfigStore.setMyData( nGptStore.value );\n//     ms.success( t('common.saveSuccess')); //'保存成功'\n//     emit('close');\n// }\nconst saveChat=(type:string)=>{\n     chatSet.save(  nGptStore.value );\n     gptConfigStore.setMyData( nGptStore.value );\n     homeStore.setMyData({act:'saveChat'}); \n     if(type!='hide')ms.success( t('common.saveSuccess'));\n     emit('close');\n}\n \nwatch(()=>nGptStore.value.model,(n)=>{\n    nGptStore.value.gpts=undefined;\n    let max=16384 *2;\n    if( n.indexOf('gpt-3.5')>-1){\n        max=4096*2;\n    }else if(  n.indexOf('o1-mini')>-1){  \n        max=65536 *2;\n    }else if(  n.indexOf('o1-')>-1 || n=='o1' ){  \n        max=65536 ;\n    }else if( n=='gpt-4o-2024-08-06' || n=='chatgpt-4o-latest' || n.indexOf('gpt-4o')>-1 || n.indexOf('gpt-4.5')>-1){  \n        max=16384 *2;\n    }else if( n.indexOf('gpt-4')>-1 ||  n.indexOf('16k')>-1 ||  n.indexOf('o1-')>-1 ){ //['16k','8k','32k','gpt-4'].indexOf(n)>-1\n        max=4096*2;\n    }else if( n.toLowerCase().includes('claude-3-5')|| n.toLowerCase().includes('sonnet') \n        ||n.toLowerCase().includes('grok-3')\n     ||  n.toLowerCase().includes('deepseek') ){ //deepseek\n        max=4096*2*2;\n    }else if( n.toLowerCase().includes('claude-3') ){\n         max=4096*2;\n    }\n\n    config.value.maxToken=max/2;\n    if(nGptStore.value.max_tokens> config.value.maxToken ) nGptStore.value.max_tokens= config.value.maxToken;\n})\n\nconst reSet=()=>{\n    gptConfigStore.setInit();\n    nGptStore.value= gptConfigStore.myData;\n}\n\nonMounted(() => {\n    //gptConfigStore.myData= chatSet.getGptConfig();\n});\n\nconst serverSuccess=(s:any)=>{\n    mlog('serverSuccess ', s  )\n    nGptStore.value.model= s.model\n}\n//\n//const f= ref({model:gptConfigStore.myData.model});\n</script>\n<template>\n<section class=\"mb-4 flex justify-between items-center\"  >\n    <div class=\" flex space-x-2 justify-between items-center\">\n     <div class=\"flex justify-start items-center\">\n        <span class=\"text-red-500\">*</span>  \n        {{ $t('mjset.model') }}\n        \n     </div>\n     \n    </div>\n    <div  class=\"!w-[70%] flex justify-end items-center \" >\n       <div> \n        <n-select v-model:value=\"nGptStore.model\" :options=\"modellist\" size=\"small\"  filterable   />\n       </div>\n       <div class=\" pl-2\" > \n        <!-- <NButton type=\"primary\" @click=\"saveChat('no')\" size=\"small\" >{{ $t('mj.server_load') }}</NButton> -->\n        <AiModelServer @success=\"serverSuccess\"/>\n        <!-- <n-popselect\n                v-model:value=\"st.server\"\n                :options=\"serverOptions\"\n                :render-label=\"renderLabel\"\n                size=\"medium\"\n                scrollable\n            >\n            <NTag  type=\"primary\" round size=\"small\" :bordered=\"false\" class=\"!cursor-pointer\">\n            {{ $t('mj.server_load') }}\n            \n            </NTag>\n        </n-popselect> -->\n            \n\n       </div>\n    </div>\n</section>\n<section class=\"mb-4 flex justify-between items-center\"  >\n    <n-input   :placeholder=\"$t('mjchat.modlePlaceholder')\" v-model:value=\"gptConfigStore.myData.userModel\">\n      <template #prefix>\n        {{ $t('mjchat.myModle') }}\n      </template>\n    </n-input>\n </section>\n <section class=\" flex justify-between items-center\"  >\n     <div> {{ $t('mjchat.historyCnt') }}\n     </div>\n     <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n        <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.talkCount\" :step=\"1\" :max=\"50\" /></div>\n        <div  class=\"w-[50px] text-right\">{{ nGptStore.talkCount }}</div>\n    </div>\n</section>\n<div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\">{{ $t('mjchat.historyToken') }}</div>\n\n <section class=\" flex justify-between items-center\"  >\n     <div> {{ $t('mjchat.historyTCnt') }} \n     </div>\n     <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n        <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.max_tokens\" :step=\"1\" :max=\"config.maxToken\" :min=\"1\" /></div>\n        <div  class=\"w-[50px] text-right\">{{ nGptStore.max_tokens }}</div>\n    </div>\n</section>\n<div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\">{{ $t('mjchat.historyTCntInfo') }}  </div>\n\n <section class=\"mb-4\"  >\n    <div>{{ $t('mjchat.role') }}</div>\n    <div>\n     <n-input  type=\"textarea\"  :placeholder=\" $t('mjchat.rolePlaceholder') \"   v-model:value=\"nGptStore.systemMessage\" :autosize=\"{ minRows: 3 }\"\n    />\n    </div>\n </section>\n\n<template v-if=\"st.openMore\">\n    <section class=\" flex justify-between items-center \"  >\n        <div>{{ $t('mj.temperature') }}</div>\n        <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n            <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.temperature\" :step=\"0.01\" :max=\"1\" /></div>\n            <div  class=\"w-[40px] text-right\">{{ nGptStore.temperature }}</div>\n        </div>\n    </section>\n    <div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\"> {{ $t('mj.temperatureInfo') }}</div>\n\n\n    <section class=\" flex justify-between items-center \"  >\n        <div> {{ $t('mj.top_p') }}</div>\n        <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n            <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.top_p\" :step=\"0.01\" :max=\"1\" /></div>\n            <div  class=\"w-[40px] text-right\">{{ nGptStore.top_p }}</div>\n        </div>\n    </section>\n    <div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\">{{ $t('mj.top_pInfo') }}</div>\n\n    <section class=\" flex justify-between items-center \"  >\n        <div> {{ $t('mj.presence_penalty') }}</div>\n        <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n            <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.presence_penalty\" :step=\"0.01\" :max=\"1\" /></div>\n            <div  class=\"w-[40px] text-right\">{{ nGptStore.presence_penalty }}</div>\n        </div>\n    </section>\n    <div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\">{{ $t('mj.presence_penaltyInfo') }} </div>\n\n\n    <section class=\" flex justify-between items-center \"  >\n        <div>{{ $t('mj.frequency_penalty') }}</div>\n        <div class=\" flex justify-end items-center w-[80%] max-w-[240px]\">\n            <div class=\" w-[200px]\"><n-slider v-model:value=\"nGptStore.frequency_penalty\" :step=\"0.01\" :max=\"1\" /></div>\n            <div  class=\"w-[40px] text-right\">{{ nGptStore.frequency_penalty }}</div>\n        </div>\n    </section>\n    <div class=\"mb-4 text-[12px] text-gray-300 dark:text-gray-300/20\">{{ $t('mj.frequency_penaltyInfo') }}</div>\n\n    <section class=\"mb-4 flex justify-between items-center\"  >\n        <div >{{ $t('mj.tts_voice') }}</div>\n        <n-select v-model:value=\"nGptStore.tts_voice\" :options=\"voiceList\" size=\"small\"  class=\"!w-[50%]\"   />\n    </section>\n\n\n</template>\n<div v-else class=\"text-right cursor-pointer mb-4\" @click=\"st.openMore=true\">\n    <NTag  type=\"primary\" round size=\"small\" :bordered=\"false\" class=\"!cursor-pointer\">More...</NTag>\n</div>\n\n <section class=\" text-right flex justify-end space-x-2\"  >\n    <NButton   @click=\"reSet()\">{{ $t('mj.setBtBack') }}</NButton>\n    <!-- <NButton type=\"primary\" @click=\"saveChat\">{{ $t('mj.setBtSaveChat') }}</NButton>\n    <NButton type=\"primary\" @click=\"save\">{{ $t('mj.setBtSaveSys') }}</NButton> -->\n    <NButton type=\"primary\" @click=\"saveChat('no')\">{{ $t('common.save') }}</NButton>\n </section>\n\n <!-- <NModal  v-model:show=\"st.isShow\"  preset=\"card\"  :title=\"$t('mjchat.modelChange')\" class=\"!max-w-[820px]\" @close=\"st.isShow=false\" >\n    Model内容\n </NModal> -->\n</template>"
  },
  {
    "path": "src/views/mj/aiModelServer.vue",
    "content": "<script setup lang=\"ts\">\n//NInfiniteScroll\nimport {NSelect, NInput,NSlider, NButton, useMessage,NTag,NEmpty,NModal,NDivider\n} from \"naive-ui\"\n//import type { SelectRenderLabel, SelectRenderTag } from 'naive-ui'\nimport { ref ,computed,watch, onMounted,h} from \"vue\";\nimport { SvgIcon } from '@/components/common'\nimport { gptFetch, mlog } from \"@/api\";\n\nconst st= ref({ server:'',isShow:false,isLoadData:0 ,\"search\":''});\nconst ms= useMessage();\n  \nconst emit= defineEmits(['success']);\ninterface modelType{\n    model:string\n    //maxToken:Number\n}\ninterface modelGroup{\n    name:string\n    key:string[]\n    data:modelType[]\n    class?:string[]\n    icon?:string\n    isClosed?:boolean\n}\n\nconst mGroup= ref<modelGroup[]>([])\n\nconst loadModel=async ()=>{\n    try {\n         const modelsData = await gptFetch('/v1/models');\n          mlog('asdsd>> ', modelsData )\n        modelsData.data.forEach((v:any) => {\n              mlog('vv>> ',v )\n              let is=false\n              for(let a of mGroup.value){\n                if(a.key.length==0 && !is){\n                    let model= v.id as string\n                    a.data.push({model})\n                    break;\n                }\n                for(let b of a.key){\n                    if(v.id && v.id.includes(b)){\n                        let model= v.id as string\n                        a.data.push({model})\n                        is=true\n                        break;\n                    }\n                }\n              }\n        });\n        st.value.isLoadData=1\n    } catch (error) {\n        st.value.isLoadData=-1\n        ms.error('Loading Models Error!')\n    } \n}\n\nconst initGroup=()=>{\n    // {name:'OpenAi',key:['gpt-'],data:[]}\n    // ,{name:'OpenAi O',key:['o1-','o3-'],data:[]}\n    // ,{name:'Deepseek',key:['deepseek'],data:[]}\n    mGroup.value.push( {name:'Deepseek',key:['deepseek'],data:[],icon:\"arcticons:deepseek\"} )\n    mGroup.value.push({name:'OpenAi',key:['gpt-'],data:[],'icon':'ri:openai-fill'})\n    mGroup.value.push( {name:'OpenAi O',key:['o1','o3'],data:[],'icon':'ri:openai-fill'} )\n    mGroup.value.push( {name:'Claude',key:['claude','c-3'],data:[],icon:\"ri:claude-fill\"} )\n    mGroup.value.push( {name:'Gemini',key:['gemini'],data:[],icon:\"cbi:gemini\"} )\n    mGroup.value.push( {name:'Grok',key:['grok'],data:[],icon:\"token:xai\"} )\n    mGroup.value.push( {name:'Other',key:[],data:[],isClosed:true } )\n}\n\nonMounted(()=>{\n initGroup();\n loadModel()\n})\n\nconst successClick=(md:any)=> {\n    emit('success', md)\n    st.value.isShow=false\n}\n\n//const usageData = await gptFetch(urlUsage);\nconst modellist = computed(() => {\n    let rz: any[]=[];\n    for(let o of mGroup.value){\n        if(o.data.length<=0) continue\n        for(let v of o.data){\n         rz.push({label:v.model,value:v.model})\n        }\n    }\n    return rz;\n});\nconst abc=()=>{\n    //console.log('abc>> ',st.value.search)\n    if(st.value.search=='') return;\n    for(let o of mGroup.value){\n        if(o.data.length<=0) continue\n        for(let v of o.data){\n         //rz.push({label:v.model,value:v.model})\n         if(v.model==st.value.search) successClick( v)\n        }\n    }\n}\n</script>\n<template>\n<div @click=\"st.isShow=true\">\n<NTag  type=\"primary\" round size=\"small\" :bordered=\"false\" class=\"!cursor-pointer\">\n            {{ $t('mj.server_load') }}  </NTag>\n \n</div>\n<NModal  v-model:show=\"st.isShow\"  preset=\"card\"  :title=\"$t('mj.model_select')\" class=\"!max-w-[620px]\" @close=\"st.isShow=false\" >\n     <NEmpty v-if=\"st.isLoadData==0\">Loading....</NEmpty>\n     <NEmpty v-else-if=\"st.isLoadData==-1\">Loaded Fail ....</NEmpty>\n     <div   class=\" overflow-y-auto max-h-[400px]\" v-else >\n        <div>\n            \n            <n-select v-model:value=\"st.search\" @update:value=\"abc\" clearable :options=\"modellist\" size=\"small\" placeholder=\"search and select your model\"  filterable   />\n       \n        </div>\n        <div v-for=\"mg in mGroup\">\n            <template v-if=\"mg.data.length>0\">\n            <div class=\"  relative\"  >\n                <n-divider title-placement=\"left\">\n                    <div class=\"flex justify-start items-center space-x-2\" @click=\"mg.isClosed=!mg.isClosed\">\n                        <SvgIcon :icon=\"mg.icon\" v-if=\"mg.icon\"/>\n                        <span>{{ mg.name }} </span>\n                    </div>\n                </n-divider>\n                <div class=\"absolute right-3 top-[5px] rounded-full bg-white/10 cursor-pointer \" @click=\"mg.isClosed=!mg.isClosed\" :class=\"{'rotate-180':mg.isClosed}\">\n                   <SvgIcon icon=\"ri:arrow-up-s-line\" />\n                </div>\n                <div class=\"absolute right-10 top-[2px]\"  @click=\"mg.isClosed=!mg.isClosed\">\n                    <NTag  size=\"small\" round   :bordered=\"false\">\n                        <span class=\" cursor-pointer\">{{ mg.data.length }}</span>\n                    </NTag>\n                </div>\n            </div>\n            <div v-if=\"mg.data.length>0 && !mg.isClosed\" class=\"grid   gap-2 grid-cols-2\">\n                <div v-for=\"md in mg.data\" >\n                    <!-- <template v-if=\"st.search=='' || md.model.includes(st.search)\"></template> -->\n                   <NTag type=\"info\" size=\"small\" round>\n                     <span class=\"cursor-pointer\" @click=\"successClick(md)\" >{{ md.model }}</span>\n                   </NTag>\n                   \n                </div>\n            </div>\n            </template>\n        </div>\n     </div>\n </NModal>\n</template>"
  },
  {
    "path": "src/views/mj/aiMsg.vue",
    "content": "<template>\n\n</template>\n<script lang=\"ts\" setup>\nimport {  ref ,h} from 'vue';\nimport {useNotification} from \"naive-ui\";\nimport { t } from '@/locales'\nconst notification = useNotification();\nconst count = ref(0);\n\nfunction increment() {\n\tcount.value++;\n}\nfunction showMsg(str:string){\n\tnotification.success({\n\t\ttitle:  t('mjchat.successTitle'),//\"成功\",\n\t\t//description: \"From the Beach Boys\",\n\t\tcontent: () => h('div',{innerHTML:str,class:'ddmsg'  } ),\n\t\tduration: 2500,\n\t\tkeepAliveOnHover: true\n\t});\n}\n\nfunction showError(str:string){\n\tnotification.info({\n\t\t//title: \"错误\",\n\t\tcontent:() => h('div',{innerHTML:str ,class:'ddmsg' } ),\n\t\tduration: 3000,\n\t\tkeepAliveOnHover: true\n\t});\n}\n\ndefineExpose({ count, increment,showMsg,showError });\n\n</script>\n\n<style>\n html.dark .ddmsg{ background-color: rgb(72, 72, 78)}\n</style>\n"
  },
  {
    "path": "src/views/mj/aiOther.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api';\nimport { homeStore ,useChatStore} from '@/store';\nimport { watch } from 'vue'; \n\nconst chatStore = useChatStore() //const chatStore = useChatStore()\n//const dataSources = computed(() => chatStore.getChatByUuid(+uuid))\nwatch( ()=>homeStore.myData.local,n=>{\n    if(! chatStore.active) return ;\n    const dataSources =    chatStore.getChatByUuid(+chatStore.active) ;\n    if( dataSources.length> 0 ){\n        chatStore.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false })\n    }\n    \n})\n \n</script>\n\n<template></template>"
  },
  {
    "path": "src/views/mj/aiSetAuth.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { NTag } from 'naive-ui'\nimport Permission from '../chat/layout/Permission.vue';\nconst st = ref({show:false});\n</script>\n<template>\n \n<span class=\" text-red-300 mr-2\">{{ $t('mj.authErro') }}</span>  \n<NTag type=\"primary\"  effect=\"dark\" \n@click=\"st.show=true\" size=\"small\" round style=\"cursor: pointer; \">{{ $t('mj.authBt') }}</NTag>\n \n <Permission :visible=\"st.show\" @close=\"st.show=false\" />\n</template>"
  },
  {
    "path": "src/views/mj/aiSetServer.vue",
    "content": "<script setup lang=\"ts\">\nimport { NInput, NButton, useMessage,NSwitch } from \"naive-ui\" //NInfiniteScroll\n \nimport {gptServerStore} from '@/store'\nimport { mlog, myTrim,blurClean} from \"@/api\";\nimport { t } from '@/locales'\nimport {  watch } from \"vue\";\n\nconst emit= defineEmits(['close']);\nconst ms= useMessage();\nconst save = ()=>{\n    gptServerStore.setMyData( gptServerStore.myData );\n    ms.success( t('mjchat.success'));\n    emit('close');\n}\n// const blurClean= ()=>{\n//   mlog('blurClean');\n//   gptServerStore.myData.OPENAI_API_BASE_URL =myTrim( myTrim(gptServerStore.myData.OPENAI_API_BASE_URL.trim(),'/'), '\\\\' );\n//   gptServerStore.myData.OPENAI_API_KEY = gptServerStore.myData.OPENAI_API_KEY.trim();\n//   gptServerStore.myData.MJ_SERVER =myTrim( myTrim( gptServerStore.myData.MJ_SERVER.trim(),'/'),'\\\\');\n//   gptServerStore.myData.MJ_API_SECRET = gptServerStore.myData.MJ_API_SECRET.trim();\n//   gptServerStore.myData.UPLOADER_URL=  myTrim( myTrim( gptServerStore.myData.UPLOADER_URL.trim(),'/'),'\\\\');\n// }\n\n//const isSync= computed(()=>gptServerStore.myData.IS_SET_SYNC )\nwatch(() => gptServerStore.myData.OPENAI_API_BASE_URL , (n)=>{\n   if(!gptServerStore.myData.IS_SET_SYNC) return  ;\n    gptServerStore.myData.MJ_SERVER= n\n    gptServerStore.myData.SUNO_SERVER=n;\n    gptServerStore.myData.LUMA_SERVER=n;\n    gptServerStore.myData.VIGGLE_SERVER=n;\n    gptServerStore.myData.RUNWAY_SERVER=n;\n    gptServerStore.myData.IDEO_SERVER=n;\n    gptServerStore.myData.KLING_SERVER=n;\n    gptServerStore.myData.PIKA_SERVER=n;\n    gptServerStore.myData.PIXVERSE_SERVER=n;\n    gptServerStore.myData.UDIO_SERVER=n;\n    gptServerStore.myData.RIFF_SERVER=n;\n});\nwatch(() => gptServerStore.myData.OPENAI_API_KEY , (n)=>{\n    if(!gptServerStore.myData.IS_SET_SYNC) return  ;\n    gptServerStore.myData.MJ_API_SECRET= n\n    gptServerStore.myData.SUNO_KEY=n;\n    gptServerStore.myData.LUMA_KEY=n;\n    gptServerStore.myData.VIGGLE_KEY=n;\n    gptServerStore.myData.RUNWAY_KEY=n;\n    gptServerStore.myData.IDEO_KEY=n;\n    gptServerStore.myData.KLING_KEY=n;\n    gptServerStore.myData.PIKA_KEY=n;\n    gptServerStore.myData.PIXVERSE_KEY=n;\n    gptServerStore.myData.UDIO_KEY=n;\n    gptServerStore.myData.RIFF_KEY=n;\n});\n</script>\n<template>\n<div id=\"setserver\"> \n\n  <div  class=\"w-full h-[540px] overflow-y-auto overflow-x-hidden\">\n    <div class=\"p-2\">\n      <div class=\"flex justify-between items-baseline \">\n        <div class=\"pb-1\">\n        <n-switch v-model:value=\"gptServerStore.myData.IS_SET_SYNC\" size=\"small\" >\n            <template #checked>{{ $t('mjchat.setSync') }}</template>\n            <template #unchecked> {{ $t('mjchat.setSync') }} </template>\n          </n-switch>\n        </div>\n        <div class=\"text-right\">{{ $t('mj.setOpen') }}</div>\n\n        </div>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.OPENAI_API_BASE_URL\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{ $t('mj.setOpenUrl') }}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.setOpenKeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.OPENAI_API_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">OpenAI Api Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"flex justify-between items-baseline \">\n        <section class=\"mb-4 flex justify-start items-center\">\n          <n-switch v-model:value=\"gptServerStore.myData.GPTS_GX\" >\n              <template #checked>{{ $t('mj.gpt_gx') }}</template>\n              <template #unchecked>{{ $t('mj.gpt_gx') }}</template>\n            </n-switch>\n        </section>\n        <section class=\"mb-4 flex justify-start items-center\">\n          <n-switch v-model:value=\"gptServerStore.myData.MJ_CDN_WSRV\" >\n              <template #checked>  {{ $t('mj.wsrvClose') }} </template>\n              <template #unchecked> {{ $t('mj.wsrvOpen') }} </template>\n            </n-switch>\n        </section>\n      </div>\n\n\n      <div  class=\"text-right\" >{{$t('mj.setMj')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input    :placeholder=\"$t('mj.setOpenPlaceholder') \"  v-model:value=\"gptServerStore.myData.MJ_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.setMjUrl')}}</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input type=\"password\"  :placeholder=\"$t('mj.setMjKeyPlaceholder') \" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.MJ_API_SECRET\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Midjourney Api Secret:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n\n      <div class=\"text-right\">{{$t('suno.serverabout')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.SUNO_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('suno.server')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('suno.setOpenKeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.SUNO_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Suno Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"text-right\">{{$t('video.lumaabout')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.LUMA_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('video.lumaserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('video.setOpenKeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.LUMA_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Luma Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"text-right\">{{$t('dance.viggleabout')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.VIGGLE_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('dance.viggleserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('dance.setOpenKeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.VIGGLE_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Viggle Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"text-right\">{{$t('video.runwayabout')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.RUNWAY_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('video.runwayserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('video.setOpenKeyPlaceholder2')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.RUNWAY_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Runway Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <div class=\"text-right\">{{ $t('mj.ideoabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.IDEO_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.ideoserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.ideokeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.IDEO_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Ideogram Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"text-right\">{{ $t('mj.klingabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.KLING_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.klingserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.klingkeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.KLING_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.klingkey')}}:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <div class=\"text-right\">{{ $t('mj.pikaabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.PIKA_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.pikaserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.pikakeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.PIKA_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Pika Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n      <div class=\"text-right\">{{ $t('mj.udioabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.UDIO_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.udioserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.udiokeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.UDIO_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Udio Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n      <div class=\"text-right\">{{ $t('mj.pixabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.PIXVERSE_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.pixserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.pixkeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.PIXVERSE_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Pixverse Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n\n      <div class=\"text-right\">{{ $t('mj.riffabout')  }}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.RIFF_SERVER\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.riffserver')}}:</span>\n            </template>\n          </n-input>\n      </section>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.riffkeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.RIFF_KEY\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">Riffusion Key:</span>\n            </template>\n          </n-input>\n      </section>\n\n\n\n\n      <div  class=\"text-right\" > {{$t('mj.setUploader')}}</div>\n      <section class=\"mb-4 flex justify-between items-center\"  >\n          <n-input  :placeholder=\"$t('mj.setOpenPlaceholder')\"  v-model:value=\"gptServerStore.myData.UPLOADER_URL\" clearable>\n            <template #prefix>\n              <span class=\"text-[var(--n-tab-text-color-active)]\">{{$t('mj.setUploaderUrl')}}</span>\n            </template>\n          </n-input>\n      </section>\n    </div>\n  </div>\n\n  <section class=\" text-right flex justify-end space-x-2\"  >\n      <NButton   @click=\"gptServerStore.setInit()\">{{$t('mj.setBtBack')}}</NButton>\n      <NButton type=\"primary\" @click=\"save\">{{$t('mj.setBtSave')}}</NButton>\n  </section>\n</div>\n</template>\n<style>\n#setserver .n-input .n-input__input-el{\n    text-align: right;\n}\n</style>"
  },
  {
    "path": "src/views/mj/aiSider.vue",
    "content": "<script setup lang=\"ts\">\nimport { computed,defineAsyncComponent ,ref} from \"vue\";\nimport { SvgIcon ,HoverButton} from '@/components/common'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nconst { isMobile } = useBasicLayout()\nimport { NAvatar,NTooltip } from 'naive-ui'\nimport { homeStore, useUserStore,useChatStore } from '@/store'\nimport defaultAvatar from '@/assets/avatar.jpg'\nimport { router } from '@/router'\nimport { isDisableMenu } from \"@/api\";\nimport { useRouter } from \"vue-router\";\n\n//import gallery from '@/views/gallery/index.vue'\n\nconst chatStore = useChatStore()\nconst Setting = defineAsyncComponent(() => import('@/components/common/Setting/index.vue'))\nconst userStore = useUserStore()\n\nconst st= ref({'show':false,showImg:false, menu:[],active:'chat'})\n\n\nconst userInfo = computed(() => userStore.userInfo)\n\nconst urouter = useRouter() //\n \nconst goHome =computed(  () => {\n  //router.push('/')\n  return router.currentRoute.value.name\n});\n// const go=(n:string)=>{\n//   if('chat'==n){\n//         router.push('/chat/'+ chatStore.active??'1002')\n//     }\n//     if('draw'==n){\n//         router.push('/draw/'+ chatStore.active??'1002')\n//         st.value.show=true;\n//     }\n// }\n//mlog('g', goHome() );\nconst chatId= computed(()=>chatStore.active??'1002' );\n</script>\n<template>\n<div class=\"flex-shrink-0 w-[60px] z-[1000]  h-full\" v-if=\"!isMobile\" data-tauri-drag-region>\n    <div class=\"flex h-full select-none flex-col items-center justify-between bg-[#e8eaf1] px-2 pt-4 pb-8 dark:bg-[#25272d]\">\n        <div class=\"flex flex-col space-y-4 flex-1 \" :class=\"{ 'pt-5': homeStore.myData.isClient }\" data-tauri-drag-region>\n            <a      @click=\"st.active='chat'; urouter.push(`/chat`)\" class=\"router-link-active router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex h-full justify-center items-center py-1 flex-col \" :class=\"[ goHome =='Chat' ? 'active' : '']\">\n                    <SvgIcon icon=\"ri:wechat-line\" class=\"text-3xl  flex-1\"></SvgIcon>\n                     <span class=\"text-[10px]\">{{$t('mjtab.chat')}}</span>\n                    </div>\n                 </template>\n                AI Chat\n                </n-tooltip>\n            </a> \n\n\n            <a v-if=\"!isDisableMenu ( 'draws')\"  @click=\"st.active='draw'; urouter.push(`/draw`)\" class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex h-full justify-center items-center   py-1 flex-col\" :class=\"[goHome=='draw' ? 'active' : '']\">\n                    <SvgIcon icon=\"ic:outline-palette\" class=\"text-3xl flex-1\"></SvgIcon>\n                     <span class=\"text-[10px]\">{{$t('mjtab.draw')}}</span>\n                    </div> \n                  </template>\n                    {{$t('mjtab.drawinfo')}}\n                </n-tooltip>\n            </a>\n\n\n\n\n            <a v-if=\"!isDisableMenu ( 'music')\"      @click=\"st.active='music'; urouter.push('/music')\" class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\"\n             >\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex  h-full justify-center items-center py-1 flex-col \" :class=\"[ goHome =='music' ? 'active' : '']\">\n                      <SvgIcon icon=\"arcticons:wynk-music\" class=\"text-3xl flex-1\"></SvgIcon>\n                      <span class=\"text-[10px]\">{{ $t('suno.menu') }}</span>\n                    </div>  \n                  </template>\n                    {{ $t('suno.menuinfo') }}\n                </n-tooltip>                \n            </a>\n\n            <a v-if=\"!isDisableMenu ( 'video')\"      @click=\"st.active='video'; urouter.push('/video')\" \n                class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex  h-full justify-center items-center py-1 flex-col \" :class=\"[ goHome =='video' ? 'active' : '']\">\n                      <SvgIcon icon=\"ri:video-on-line\" class=\"text-3xl flex-1\"></SvgIcon>\n                      <span class=\"text-[10px]\">{{ $t('video.menu') }}</span>\n                    </div>  \n                  </template>\n                    {{ $t('video.menuinfo') }}\n                </n-tooltip>                \n            </a>\n\n\n            <a  v-if=\"!isDisableMenu ( 'gpts')\"   @click=\"homeStore.setMyData({act:'showgpts'}) \" class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex h-full justify-center items-center   py-1 flex-col\" >\n                    <SvgIcon icon=\"ri:apps-fill\" class=\"text-3xl flex-1\"></SvgIcon>\n                     <span class=\"text-[10px]\">GPTs</span>\n                    </div> \n                  </template>\n                    ChatGPT Store \n                </n-tooltip>\n            </a>\n\n             <a  v-if=\"!isDisableMenu ( 'gallery')\"  @click=\"homeStore.setMyData({act:'gallery'}) \" class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex h-full justify-center items-center   py-1 flex-col\" >\n                    <SvgIcon icon=\"material-symbols:imagesmode-outline\" class=\"text-3xl flex-1\"></SvgIcon>\n                     <span class=\"text-[10px]\">{{$t('mjtab.gallery')}}</span>\n                    </div> \n                  </template>\n                    {{ $t('mjtab.galleryInfo') }}\n                </n-tooltip>\n            </a>\n\n\n            <a v-if=\"!isDisableMenu ( 'dance')\"      @click=\"st.active='dance'; urouter.push('/dance')\" \n                class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex  h-full justify-center items-center py-1 flex-col \" :class=\"[ goHome =='dance' ? 'active' : '']\">\n                      <SvgIcon icon=\"mdi:dance-ballroom\" class=\"text-3xl flex-1\"></SvgIcon>\n                      <span class=\"text-[10px]\">{{ $t('dance.menu') }}</span>\n                    </div>  \n                  </template>\n                    {{ $t('dance.menuinfo') }}\n                </n-tooltip>                \n            </a>\n\n             <a v-if=\"!isDisableMenu ( 'realtime')\"   @click=\"homeStore.setMyData({act:'openRealtime'}) \"  \n                class=\" router-link-exact-active h-12 w-12 cursor-pointer rounded-xl bg-white duration-300 dark:bg-[#34373c] hover:bg-[#bbb] dark:hover:bg-[#555]\">\n                <n-tooltip placement=\"right\" trigger=\"hover\">\n                  <template #trigger> \n                    <div  class=\"flex  h-full justify-center items-center py-1 flex-col \" :class=\"[ goHome =='realtime' ? 'active' : '']\">\n                      <SvgIcon icon=\"ri:mic-fill\" class=\"text-3xl flex-1\"></SvgIcon>\n                      <span class=\"text-[10px]\">{{$t('mj.rttab')}}</span>\n                    </div>  \n                  </template>\n                    {{ $t('mj.rtinfo') }}\n                </n-tooltip>                \n            </a>\n\n            \n\n             \n\n        </div>\n        <div class=\"flex flex-col  space-y-2 \"> \n\n            \n            <NAvatar  size=\"large\"  round  :src=\"userInfo.avatar\"   v-if=\"userInfo.avatar\"  :fallback-src=\"defaultAvatar\"\n             class=\" cursor-pointer\"  />\n            \n            <HoverButton>\n                <div class=\"text-xl text-[#4f555e] dark:text-white flex h-full justify-center items-center \"  @click=\"st.show = true\">\n                    <SvgIcon icon=\"ri:settings-4-line\" />\n                </div>\n            </HoverButton>\n        </div>\n    </div>\n</div>\n <Setting v-if=\"st.show\" v-model:visible=\"st.show\" />\n\n <!-- <n-drawer v-model:show=\"st.showImg\" :placement=\"isMobile?'bottom':'right'\"  :class=\"isMobile?['!h-[90vh]']: ['!w-[80vw]']\" style=\"--n-body-padding:0\">\n    <n-drawer-content title=\"GPT store\" closable>\n      sdsd \n    </n-drawer-content>\n</n-drawer> -->\n</template>\n\n "
  },
  {
    "path": "src/views/mj/aiSiderInput.vue",
    "content": "<script setup lang=\"ts\">\n//import {  NLayoutSider } from 'naive-ui'; \nimport aiDrawInput from './aiDrawInput.vue';\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { NDrawerContent,NDrawer} from \"naive-ui\";\nimport { computed,ref  } from \"vue\";\n//import { SvgIcon } from '@/components/common';\nimport { homeStore } from '@/store';\n \n//import { homeStore } from '@/store';\nconst { isMobile } = useBasicLayout()\n\nconst pp =defineProps<{buttonDisabled:boolean}>()\nconst st= ref({show:false})\nconst handleUpdateCollapsed = (value: boolean) => {\n  console.log(value);\n}\nconst $emit=defineEmits(['drawSent','close']);\nconst isLoading= computed(() => {\n  return pp.buttonDisabled  \n})\nfunction drawSent(e:any){\n  st.value.show=false;\n  $emit('drawSent', e)\n  homeStore.setMyData({act:'draw',actData:e});\n}\n// watch( ()=>homeStore.myData.act, (act) => {\n//   act=='newtask' && (st.value.show=true);\n//   act=='same2' && (st.value.show=true);\n// });\n \n</script>\n<template>\n<div v-if=\"isMobile\" > \n    <!-- <div class=\"fixed right-[30px] bottom-[70px] z-10\">\n    <n-button  type=\"warning\" circle size=\"large\" @click=\"st.show=true\">\n      <template #icon>\n        <SvgIcon icon=\"ic:round-add\"></SvgIcon>\n      </template>\n    </n-button>\n    </div> -->\n    <n-drawer v-model:show=\"st.show\" :height=\"565\"  placement=\"bottom\">\n    <n-drawer-content   style=\"--n-body-padding:0\" class=\"h-full\">\n      <aiDrawInput @draw-sent=\"drawSent\" :button-disabled=\"isLoading\"/>\n    </n-drawer-content>\n  </n-drawer>\n</div>\n<section class=\"h-full overflow-auto w-[300px]\"  @update-collapsed=\"handleUpdateCollapsed\" v-else>\n   <!-- <div class=\"h-full w-full\">\n     <aiDrawInput class=\"p-4\"/>\n   </div> -->\n   <div class=\"h-full w-full\"> <aiDrawInput @draw-sent=\"drawSent\" :button-disabled=\"isLoading\"/></div>\n  </section>\n\n  \n</template>"
  },
  {
    "path": "src/views/mj/aiTextSetting.vue",
    "content": "<script setup lang=\"ts\">\n\nimport { homeStore } from '@/store';\nimport {  computed ,ref } from 'vue'\nimport aiSetServer from './aiSetServer.vue';\nimport { NTag,NModal,NButton } from 'naive-ui'\nconst isHideServer= computed( ()=>homeStore.myData.session.isHideServer )\nconst st= ref({show:false})\nconst pp = defineProps<{msgInfo?:string}>();\nconst emit =defineEmits(['close'])\nconst closeed=()=>{\n    emit('close')\n    st.value.show=false\n}\n</script>\n<template>\n<div class=\"whitespace-pre-wrap pb-10\" v-if=\"!isHideServer || pp.msgInfo\"> \n<div v-if=\"pp.msgInfo\">\n    <div v-html=\"pp.msgInfo\" class=\"p-5 text-center\"> </div>\n    <div class=\"text-center\">\n      <NButton type=\"primary\" @click=\"st.show=true\">{{ $t('setting.setting') }} </NButton> \n    </div>\n</div>\n<template v-else>\n    <span class=\" text-red-400\">{{ $t('mj.setTextInfo') }} </span> <NTag type=\"primary\"  effect=\"dark\" @click=\"st.show=true\" size=\"small\" round style=\"cursor: pointer; \">{{ $t('setting.setting') }}</NTag>\n</template>\n</div>\n<NModal v-model:show=\"st.show\" :title=\"$t('mjset.server')\" preset=\"card\"  style=\"width: 95%; max-width: 640px\">\n    <aiSetServer v-if=\"st.show\" @close=\"closeed\"/>\n</NModal>\n</template>"
  },
  {
    "path": "src/views/mj/dallText.vue",
    "content": "<script setup lang=\"ts\">\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { NImage,NButton,NModal,useMessage } from 'naive-ui'\nimport { computed , ref,watch } from 'vue'\nimport {  isDallImageModel, localGet,mlog, url2base64 } from '@/api'\nimport { homeStore } from '@/store'\nconst { isMobile } = useBasicLayout()\nconst st = ref({isLoadImg:false,uri_base64:''})\nconst props = defineProps<{chat:Chat.Chat}>();\nconst chat = computed(() =>props.chat);\n\nconst load = async ()=>{\n     mlog('load-dall', chat.value.myid, chat.value.opt?.imageUrl );\n    \n     if( !isDallImageModel(chat.value.model)  || !chat.value.myid || !chat.value.opt?.imageUrl ){\n         st.value.isLoadImg=true;\n         if( chat.value.model=='midjourney'){\n           st.value.isLoadImg=false;\n         }\n      return ;\n     }\n     let key= 'dall:'+chat.value.myid;\n    try {\n        if(chat.value.opt?.imageUrl){\n            //await loadImg(chat.value.opt?.imageUrl);\n            let base64 = await localGet(key );  \n            if(!base64) {\n                const ubase64=  await url2base64(`https://wsrv.nl/?url=${encodeURIComponent(chat.value.opt?.imageUrl)}`  ,key );\n                base64= ubase64.base64;\n                mlog('图片已保存>>', ubase64.key )\n            }\n            st.value.uri_base64=base64;\n        }\n    } catch (error) {\n        mlog('图片保存失败',error);\n    }\n    \n    st.value.isLoadImg=true;\n\n  \n}\n\n\n\n\nwatch(()=>homeStore.myData.act,(n)=>{\n    const actData :any= homeStore.myData.actData;\n    \n    if(n=='dallReload' &&  actData.myid== chat.value.myid  ){  //\n         mlog('dallReload', actData.myid , chat.value.opt?.imageUrl);\n         st.value.isLoadImg=false;\n         load();\n        // if( !actData.noShow ) ms.success('图片刷新成功！');\n    }\n})\n\nload();\n</script>\n<template>\n<div>\n    <div v-if=\"st.isLoadImg\">\n        <NImage   v-if=\"chat.opt?.imageUrl\" :src=\"st.uri_base64?st.uri_base64:chat.opt.imageUrl\" class=\" rounded-sm \" :class=\"[isMobile?'':'!max-w-[500px]']\"  /> \n    </div>\n    <div v-else-if=\"chat.opt?.imageUrl\" class=\"w-[200px] h-[150px] flex flex-col justify-center items-center\" >\n        <div class=\"p-4\">{{ $t('mjchat.loading') }}</div>\n        <NButton type=\"primary\"  ><a :href=\"chat.opt?.imageUrl\" target=\"_blank\">{{ $t('mjchat.openurl') }}</a></NButton> \n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/mj/draw.json",
    "content": "{\n\t\"qualityList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.qualityList.general\",\n\t\t\t\"value\": \"0.25\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.qualityList.clear\",\n\t\t\t\"value\": \"0.5\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.qualityList.hd\",\n\t\t\t\"value\": \"1\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.qualityList.ultraHd\",\n\t\t\t\"value\": \"2\"\n\t\t}\n\t],\n\t\"styleList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.cyberpunk\",\n\t\t\t\"value\": \"Cyberpunk\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.star\",\n\t\t\t\"value\": \"Warframe\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.anime\",\n\t\t\t\"value\": \"ACGN\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.japaneseComicsManga\",\n\t\t\t\"value\": \"Japanese comics/manga\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.inkWashPaintingStyle\",\n\t\t\t\"value\": \"Ink Wash Painting Style\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.original\",\n\t\t\t\"value\": \"Original\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.landscape\",\n\t\t\t\"value\": \"landscape\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.illustration\",\n\t\t\t\"value\": \"illustration\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.manga\",\n\t\t\t\"value\": \"Manga\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.modernOrganic\",\n\t\t\t\"value\": \"modern organic\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.genesis\",\n\t\t\t\"value\": \"Genesis\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.posterstyle\",\n\t\t\t\"value\": \"posterstyle\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.surrealism\",\n\t\t\t\"value\": \"surrealism\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.sketch\",\n\t\t\t\"value\": \"sketch\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.realism\",\n\t\t\t\"value\": \"realism\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.watercolorPainting\",\n\t\t\t\"value\": \"Watercolor painting\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.cubism\",\n\t\t\t\"value\": \"Cubism\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.blackAndWhite\",\n\t\t\t\"value\": \"black and white\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.fmPhotography\",\n\t\t\t\"value\": \"fm photography\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.cinematic\",\n\t\t\t\"value\": \"cinematic\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.styleList.clearFacialFeatures\",\n\t\t\t\"value\": \"dlear facial features\"\n\t\t}\n\t],\n\t\"viewList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.wideView\",\n\t\t\t\"value\": \"Wide view\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.birdView\",\n\t\t\t\"value\": \"Aerial view\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.topView\",\n\t\t\t\"value\": \"Top view\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.upview\",\n\t\t\t\"value\": \"Upview\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.frontView\",\n\t\t\t\"value\": \"Front view\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.headshot\",\n\t\t\t\"value\": \"Headshot\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.ultrawideshot\",\n\t\t\t\"value\": \"Ultrawideshot\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.mediumShot\",\n\t\t\t\"value\": \"Medium Shot(MS)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.longShot\",\n\t\t\t\"value\": \"Long Shot(LS)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.viewList.depthOfField\",\n\t\t\t\"value\": \"depth offield(dof)\"\n\t\t}\n\t],\n\t\"shotList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.faceShot\",\n\t\t\t\"value\": \"Face Shot (VCU)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.bigCloseUp\",\n\t\t\t\"value\": \"Big Close-Up(BCU)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.closeUp\",\n\t\t\t\"value\": \"Close-Up(CU)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.waistShot\",\n\t\t\t\"value\": \"Waist Shot(WS)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.kneeShot\",\n\t\t\t\"value\": \"KneeShot(KS)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.fullLengthShot\",\n\t\t\t\"value\": \"Full Length Shot(FLS)\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.shotList.extraLongShot\",\n\t\t\t\"value\": \"Extra Long Shot(ELS)\"\n\t\t}\n\t],\n\t\"stylesList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.stylesList.styleLow\",\n\t\t\t\"value\": \"--s 50\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.stylesList.styleMed\",\n\t\t\t\"value\": \"--s 100\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.stylesList.styleHigh\",\n\t\t\t\"value\": \"--s 250\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.stylesList.styleVeryHigh\",\n\t\t\t\"value\": \"--s 750\"\n\t\t}\n\t],\n\t\"lightList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.coldLight\",\n\t\t\t\"value\": \"Cold light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.warmLight\",\n\t\t\t\"value\": \"Warm light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.hardLighting\",\n\t\t\t\"value\": \"hard lighting\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.dramaticLight\",\n\t\t\t\"value\": \"Dramatic light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.reflectionLight\",\n\t\t\t\"value\": \"reflection light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.mistyFoggy\",\n\t\t\t\"value\": \"Misty foggy\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.naturalLight\",\n\t\t\t\"value\": \"Natural light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.sunLight\",\n\t\t\t\"value\": \"Sun light\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.lightList.moody\",\n\t\t\t\"value\": \"moody\"\n\t\t}\n\t],\n\t\"versionList\": [\n\t\t\n\t\t{\n\t\t\t\"labelKey\": \"MJ V7\",\n\t\t\t\"value\": \"--v 7.0\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.mjV61\",\n\t\t\t\"value\": \"--v 6.1\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.mjV6\",\n\t\t\t\"value\": \"--v 6.0\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.mjV52\",\n\t\t\t\"value\": \"--v 5.2\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.mjV51\",\n\t\t\t\"value\": \"--v 5.1\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"Niji V7\",\n\t\t\t\"value\": \"--niji 7\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.nijiV6\",\n\t\t\t\"value\": \"--niji 6\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.nijiV5\",\n\t\t\t\"value\": \"--niji 5\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.nijiV4\",\n\t\t\t\"value\": \"--niji 4\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.versionList.nijiJourney\",\n\t\t\t\"value\": \"NIJI_JOURNEY\"\n\t\t}\n\t],\n\t\"botList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.botList.midjourneyBot\",\n\t\t\t\"value\": \"MID_JOURNEY\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.botList.nijiJourney\",\n\t\t\t\"value\": \"NIJI_JOURNEY\"\n\t\t}\n\t],\n\t\"dimensionsList\": [\n\t\t{\n\t\t\t\"labelKey\": \"draw.dimensionsList.square\",\n\t\t\t\"value\": \"SQUARE\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.dimensionsList.portrait\",\n\t\t\t\"value\": \"PORTRAIT\"\n\t\t},\n\t\t{\n\t\t\t\"labelKey\": \"draw.dimensionsList.landscape\",\n\t\t\t\"value\": \"LANDSCAPE\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "src/views/mj/draw.vue",
    "content": "<script setup lang=\"ts\">\nimport aiSiderInput from './aiSiderInput.vue'; \n//import { useAppStore, useChatStore } from '@/store';\n\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { mlog } from '@/api';\nimport chatIndex from '@/views/chat/index.vue';\n\nconst { isMobile } = useBasicLayout()\n// const appStore = useAppStore()\n// const chatStore = useChatStore()\nconst drawSent=( obj:any )=>{\n    mlog('drawSent' , obj )\n}\nconst mjClose=()=>{\n}\n\n// function handleAdd() {\n//   chatStore.addHistory({ title: 'New Chat', uuid: Date.now(), isEdit: false })\n//   if (isMobile.value)\n//     appStore.setSiderCollapsed(true)\n// }\n\n//handleAdd();\n</script>\n<template>\n         <!-- <chatIndex></chatIndex> -->\n\n<div   class=\"flex h-full\">\n    <div class=\"h-full z-30\">\n    <aiSiderInput  @close=\"mjClose\" @drawSent=\"drawSent\" :button-disabled=\"false\"></aiSiderInput>\n    </div>\n     \n    <main class=\"flex-1 overflow-hidden h-full\">\n        <chatIndex></chatIndex>\n    </main>\n</div>\n</template>"
  },
  {
    "path": "src/views/mj/drawList.vue",
    "content": "<script setup lang='ts'> \nimport { computed, onMounted, onUnmounted, ref,watch } from 'vue'\nimport { useRoute } from 'vue-router' \nimport {   useDialog, useMessage } from 'naive-ui'\n \nimport { useScroll } from '../chat/hooks/useScroll'\nimport { useChat } from '../chat/hooks/useChat'\nimport { useUsingContext } from '../chat/hooks/useUsingContext' \nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { homeStore, useChatStore, usePromptStore } from '@/store'\nimport {   mlog,subTask,localSaveAny, subGPT, isDallImageModel } from '@/api'\nimport { t } from '@/locales'\n\nlet controller = new AbortController()\n\n//const openLongReply = import.meta.env.VITE_GLOB_OPEN_LONG_REPLY === 'true'\n\nconst route = useRoute()\nconst dialog = useDialog()\nconst ms = useMessage()\n\nconst chatStore = useChatStore()\n\nconst { isMobile } = useBasicLayout()\nconst { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } = useChat()\nconst { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll()\nconst { usingContext, toggleUsingContext } = useUsingContext()\n\nconst { uuid } = route.params as { uuid: string } // || chatStore.$state.active || '1003'\n//if(!uuid) uuid= chatStore.$state.active ;\nmlog('uuid', uuid, chatStore.$state.active) ;\nconst dataSources = computed(() => chatStore.getChatByUuid(+uuid))\nconst conversationList = computed(() => dataSources.value.filter(item => (!item.inversion && !!item.conversationOptions)))\n\nconst prompt = ref<any>(null)\nconst loading = ref<boolean>(false)\n \n// 未知原因刷新页面，loading 状态不会重置，手动重置\ndataSources.value.forEach((item, index) => {\n  if (item.loading)\n    updateChatSome(+uuid, index, { loading: false })\n})\n\nfunction handleSubmit() {\n  onConversation()\n}\nconst getInitChat = (txt:string)=>{\n    let promptMsg: Chat.Chat= {\n        dateTime: new Date().toLocaleString(),\n        text:  txt ,\n        inversion: true,\n        error: false,\n        conversationOptions: null,\n        requestOptions: { prompt:txt, options: null },\n        }\n        return promptMsg;\n}\nasync function onConversation() {\n  let message = prompt.value\n\n  if (loading.value)\n    return\n  if( !message.drawText && dataSources.value.length==0){\n      message.drawText=  t('mjset.sysname');//'AI绘图';\n  }\n//   if (!message || message.trim() === '')\n//     return\n\n  controller = new AbortController()\n  if( message.action && message.action=='face' ){\n    let promptMsg: Chat.Chat= getInitChat( t('mjchat.face')); //'换脸'\n    try{\n          let images= await localSaveAny( JSON.stringify( [message.data.sourceBase64,message.data.targetBase64 ] )  ) ;\n          mlog('key', images );\n          promptMsg.opt= {images:[images]}\n     }catch(e){\n         mlog('localSaveAny error',e);\n     }\n     addChat(  +uuid, promptMsg );\n     //return ;\n\n   \n  }else if( message.action && (message.action=='mj.edit.video'||  message.action=='mj.edit.image') ){ //'视频，图片编辑'\n   const  str=message.action=='mj.edit.image'?t('mj.editImage'):t('mj.editVideo')\n   let promptMsg: Chat.Chat= getInitChat(str+\":\\n\"+message.data.prompt+\"\\n\\n\" );\n   try{\n          //let images= await localSaveAny( JSON.stringify( message.data.image )  ) ;\n          let images= await localSaveAny( JSON.stringify( {fileName:[\"a.jpg\"], fileBase64:[ message.data.image ]} )  ) ;\n          mlog('mj.edit.video key', images );\n          promptMsg.opt= {images:[images]}\n     }catch(e){\n         mlog('mj.edit.video localSaveAny error ',e);\n     }\n     addChat(  +uuid, promptMsg );\n\n  }else if( message.action && message.action=='blend' ){\n     // promptMsg.opt={  images: message.fileBase64 }\n     let promptMsg: Chat.Chat= getInitChat(t('mjchat.blend') );//'混图'\n     try{\n          let images= await localSaveAny( JSON.stringify( message.data.base64Array )  ) ;\n          mlog('key', images );\n          promptMsg.opt= {images:[images]}\n     }catch(e){\n         mlog('localSaveAny error',e);\n     }\n     addChat(  +uuid, promptMsg );\n\n    \n  }else if( message.action && ['gpt.dall-e-3','shorten'].indexOf(message.action) >-1   ){ //gpt.dall-e-3 //subTas\n    let promptMsg: Chat.Chat= getInitChat( message.data.prompt ); \n    mlog( 'gpt.dall-e-3' ,  message.data.fileBase64 );\n    if(  message.data.fileBase64 &&  message.data.fileBase64.length>0 ){\n       // promptMsg.opt={  images: message.fileBase64 }\n       try{\n            let images= await localSaveAny( JSON.stringify(  {fileName:[\"a.jpg\"], fileBase64:[ message.data.fileBase64]} )  ) ;\n            mlog('key', images );\n            promptMsg.opt= {images:[images]}\n       }catch(e){\n           mlog('localSaveAny error',e);\n       }\n    }\n     addChat(  +uuid, promptMsg );\n  }else if( message.drawText){\n    let promptMsg: Chat.Chat= getInitChat(message.drawText)\n    \n    if( message.fileBase64 && message.fileBase64.length>0 ){\n       // promptMsg.opt={  images: message.fileBase64 }\n       try{\n            let images= await localSaveAny( JSON.stringify(  {fileName:[\"a.jpg\"], fileBase64:[ message.data.fileBase64]} )  ) ;\n            mlog('key', images );\n            promptMsg.opt= {images:[images]}\n       }catch(e){\n           mlog('localSaveAny error',e);\n       }\n    }\n    addChat(  +uuid, promptMsg ); \n  } \n  \n\n\n  scrollToBottom()\n\n  loading.value = true\n  //prompt.value = ''\n\n  let options: Chat.ConversationRequest = {}\n  const lastContext = conversationList.value[conversationList.value.length - 1]?.conversationOptions\n\n  if (lastContext && usingContext.value)\n    options = { ...lastContext }\n  let outMsg: Chat.Chat={\n      dateTime: new Date().toLocaleString(),\n      text: message.action=='gpt.dall-e-3'? t('mjchat.wait3'): t('mjchat.submiting'),\n      loading: true,\n      inversion: false,\n      error: false,\n      conversationOptions: null,\n      requestOptions: { prompt:  t('mjchat.submiting'), options: { ...options } },\n      uuid:+uuid,\n      myid: `${Date.now()}`\n      ,model:message.action=='gpt.dall-e-3'? message.data.model :'midjourney'\n     \n    }\n  //mlog('outMsg model',outMsg.model );\n  addChat(  +uuid, outMsg  )\n  outMsg.index=  dataSources.value.length - 1;\n  scrollToBottom()\n\n  try { \n     if( message.action && message.action.indexOf('gpt.')==0 ){ \n        await subGPT(message, outMsg );\n     }\n     else await subTask(message, outMsg );\n     return ;\n  }\n  catch (error: any) {\n    const errorMessage = error?.message ?? t('common.wrong')\n\n    if (error.message === 'canceled') {\n      updateChatSome(\n        +uuid,\n        dataSources.value.length - 1,\n        {\n          loading: false,\n        },\n      )\n      scrollToBottomIfAtBottom()\n      return\n    }\n\n    const currentChat = getChatByUuidAndIndex(+uuid, dataSources.value.length - 1)\n\n    if (currentChat?.text && currentChat.text !== '') {\n      updateChatSome(\n        +uuid,\n        dataSources.value.length - 1,\n        {\n          text: `${currentChat.text}\\n[${errorMessage}]`,\n          error: false,\n          loading: false,\n        },\n      )\n      return\n    }\n\n    updateChat(\n      +uuid,\n      dataSources.value.length - 1,\n      {\n        dateTime: new Date().toLocaleString(),\n        text: errorMessage,\n        inversion: false,\n        error: true,\n        loading: false,\n        conversationOptions: null,\n        requestOptions: { prompt: \"\", options: { ...options } },\n      },\n    )\n    scrollToBottomIfAtBottom()\n  }\n  finally {\n    loading.value = false\n  }\n}\n \nonUnmounted(() => {\n  if (loading.value)\n    controller.abort()\n})\n\nwatch(()=>homeStore.myData.act,(n)=>{\n    if(n=='draw') {\n        prompt.value=homeStore.myData.actData;\n        mlog('draw', homeStore.myData.actData.drawText );\n        handleSubmit();\n    }\n    if(n=='updateChat'){\n        let dchat= homeStore.myData.actData as Chat.Chat;\n        mlog(\"动作更新\",'updateChat' ,  dchat.uuid,dchat.index );\n        if(  dchat.uuid && dchat.index ) {\n            dchat.dateTime= new Date().toLocaleString();\n            updateChat( +dchat.uuid, +dchat.index, dchat );\n            mlog('updateChat 动作更新',dchat.model , dchat.opt?.progress, dchat.opt?.imageUrl  );\n            if( dchat.opt?.progress&& dchat.opt?.progress=='100%' && dchat.opt?.imageUrl ){\n               // url2base64(dchat.opt?.imageUrl ,'img:'+dchat.mjID ).then(()=>{}).catch((e)=>mlog('url2base64 error',e));\n               //homeStore.setMyData{{act}}\n               homeStore.setMyData({act:'mjReload', actData:{mjID:dchat.mjID,noShow:true} })\n               toBottom();\n            }else if(  dchat.model && ( isDallImageModel(dchat.model) )   && dchat.opt?.imageUrl ){\n                homeStore.setMyData({act:'dallReload', actData:{myid:dchat.myid,noShow:true} });\n                toBottom();\n            }\n\n        }\n    }\n    \n},{deep:true});\n\nconst toBottom= ()=>{\n  setTimeout(() => {\n    homeStore.setMyData({act:'scrollToBottom'});\n  }, 1800);\n}\n</script>\n\n<template>\n</template>\n"
  },
  {
    "path": "src/views/mj/index.ts",
    "content": "import aiSider from \"./aiSider.vue\"\nimport aiGpts from \"./aiGpts.vue\"\nimport aiGallery from \"./aiGallery.vue\"\nimport aiFooter from \"./aiFooter.vue\"\n\nexport {aiSider,aiGpts,aiGallery,aiFooter }"
  },
  {
    "path": "src/views/mj/layout.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport { NLayout, NLayoutContent } from 'naive-ui'\nimport { useRouter } from 'vue-router'\nimport Sider from '../chat/layout/sider/index.vue'\nimport Permission from '../chat/layout/Permission.vue'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { homeStore, useAppStore, useAuthStore, useChatStore } from '@/store'\nimport { aiSider ,aiFooter} from '@/views/mj'\nimport aiMobileMenu from '@/views/mj/aiMobileMenu.vue'; \n\nconst router = useRouter()\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\nconst authStore = useAuthStore()\n\nrouter.replace({ name: 'draw', params: { uuid: chatStore.active } })\nhomeStore.setMyData({local:'draw'});\nconst { isMobile } = useBasicLayout()\n\nconst collapsed = computed(() => appStore.siderCollapsed)\n\nconst needPermission = computed(() => !!authStore.session?.auth && !authStore.token)\n\nconst getMobileClass = computed(() => {\n  if (isMobile.value)\n    return ['rounded-none', 'shadow-none' ]\n  return [ 'shadow-md', 'dark:border-neutral-800' ] //'border', 'rounded-md',\n})\n\nconst getContainerClass = computed(() => {\n  return [\n    'h-full',\n    { 'abc': !isMobile.value && !collapsed.value },\n  ]\n}) \n</script>\n\n<template>\n  <div class=\"dark:bg-[#24272e] transition-all p-0\" :class=\"[isMobile ? 'h55' : 'h-full' ]\">\n    <div class=\"h-full overflow-hidden\" :class=\"getMobileClass\">\n      <NLayout class=\"z-40 transition\" :class=\"getContainerClass\" has-sider  :sider-placement=\"isMobile?'left': 'right'\">\n        <aiSider v-if=\"!isMobile\"/>\n       \n        <NLayoutContent class=\"h-full\">\n          <RouterView v-slot=\"{ Component, route }\">\n            <component :is=\"Component\" :key=\"route.fullPath\" />\n          </RouterView>\n        </NLayoutContent>\n         <Sider />\n      </NLayout>\n    </div>\n    <Permission :visible=\"needPermission\" />\n  </div>\n   <aiMobileMenu v-if=\"isMobile\"   /> \n  <aiFooter/>\n</template>\n<style  >\n.h55{\n  height: calc(100% - 55px);\n}\n</style>\n"
  },
  {
    "path": "src/views/mj/mjText.vue",
    "content": "<script setup lang=\"ts\">\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { NImage,NButton,NModal,useMessage,NInput } from 'naive-ui'\nimport { computed , ref,watch } from 'vue'\nimport {flechTask ,localGet,mlog, url2base64,mjImgUrl } from '@/api'\nimport { homeStore } from '@/store'\nimport aiCanvas from './aiCanvas.vue'\nimport MarkdownIt from 'markdown-it'\nimport {t} from \"@/locales\"\nimport { SvgIcon } from '@/components/common'\nimport AiEditVidoe from './aiEditVidoe.vue'\nimport AiEditImage from './aiEditImage.vue'\n\ninterface Props { \n  chat:Chat.Chat\n  ,mdi:MarkdownIt\n}\n const { isMobile } = useBasicLayout()\nconst ms = useMessage();\nconst props = defineProps<Props>();\nconst st = ref( { isLoadImg:false, uri_base64:'', bts:[],isShow:false, isCustom:false ,customText:'',ctrIndex:-1})\n\nconst mst= ref({isShow:false,type:''});\nconst reload= ()=>{\n    flechTask(chat.value);\n}\nconst sub= (type:string,index:number)=>{\n     \n    let text= chat.value.opt?.promptEn+` ${type} ${index}`;\n    let obj={\n        action:'change',\n        version:1,text,\n        data:{\n            \"action\": type,\n            \"index\": index, \n            \"taskId\":  chat.value.mjID\n            }\n    }\n    homeStore.setMyData({act:'draw',actData:obj});\n}\n//const st= ref({isLoad:false,});\n////实现本地保存图片\n// const saveImg= (myChat:Chat.Chat)=>{\n//     //homeStore.setMyData({act:'saveImg',actData:chat.value.opt?.promptEn});\n//     if(myChat.opt?.progress=='IMAGINE'){\n        \n//     }else{\n//         st.value.isLoad=true;\n//     }\n// }\nconst chat = computed(() =>props.chat);\n\nconst subV2= (b:{k:string,n:string})=>{\n    if(chat.value.opt?.buttons ==undefined ) return;\n    //mlog('subV2', b );\n    let i = getIndex( chat.value.opt?.buttons, b);\n    mlog('subV2', b,i ,  chat.value.opt?.buttons[i] );\n    if(b.k== ':Inpaint::1' ){\n        mlog('局部重绘！' , i );\n        st.value.isShow =true;\n        return ;\n    }\n    if(b.k=='CustomZoom::'){\n         mlog('自定义变焦' , i );\n         st.value.isCustom= true;\n        return ;\n    }\n     let obj={\n        action:'changeV2',\n        version:1, \n        data:{\n            \"customId\": chat.value.opt?.buttons[i].customId, \n            \"taskId\":  chat.value.mjID\n            }\n    }\n    homeStore.setMyData({act:'draw',actData:obj});\n\n}\n\nconst subCustom = ()=>{\n    if(chat.value.opt?.buttons ==undefined ) return;\n    let i = getIndex( chat.value.opt?.buttons, {k: 'CustomZoom::' ,n: t('mj.czoom') } );\n    let obj={\n        action:'CustomZoom',\n        version:1, \n        data:{\n            \"customId\": chat.value.opt?.buttons[i].customId, \n            \"taskId\":  chat.value.mjID\n            },\n        maskData:{  \n            \"prompt\": st.value.customText ,\n        }\n    }\n    mlog('subCustom', obj );\n    homeStore.setMyData({act:'draw',actData:obj});\n\n    st.value.isCustom= false;\n    \n}\n\nconst maskOk=(d:any)=>{\n    if(chat.value.opt?.buttons ==undefined ) return;\n   \n   mlog('maskOk',d  );\n    let i = getIndex( chat.value.opt?.buttons, {k:':Inpaint::1',n: t('mj.redraw') } );\n    let obj={\n        action:'mask',\n        version:1, \n        data:{\n            \"customId\": chat.value.opt?.buttons[i].customId, \n            \"taskId\":  chat.value.mjID\n            },\n        maskData:{ \n  \"maskBase64\": d.mask ,\n  \"prompt\": d.prompt ,\n   //\"taskId\": \"14001934816969359\" \n        }\n    }\n   homeStore.setMyData({act:'draw',actData:obj});\n   //imageSend({t:'V',v: 23,chat:props?.chat,  data:{ mask:d.mask,prompt:d.prompt} })\n   st.value.isShow= false;\n}\n//专业版本按钮\nconst bt= [ \n    [\n    {k:':upsample::1',n:'U1'}\n    ,{k:':upsample::2',n:'U2'}\n    ,{k:':upsample::3',n:'U3'}\n    ,{k:':upsample::4',n:'U4'} \n        ,{k:'high_variation',n: t('mj.high_variation')},\n        {k:'low_variation',n:t('mj.low_variation')},\n        {k:':Inpaint::1',n:t('mj.redraw')},\n        {k:'Outpaint::50',n: t('mj.p15')},\n        {k:'Outpaint::75',n: t('mj.p20')}\n        ,{k:'CustomZoom::',n: t('mj.czoom')},\n        {k:'Outpaint::100',n: t('mj.p100')}\n        //MJ::CustomZoom\n\n        ,{k:'Job::PicReader::1',n:'T1'}\n        ,{k:'Job::PicReader::2',n:'T2'}\n        ,{k:'Job::PicReader::3',n:'T3'}\n        ,{k:'Job::PicReader::4',n:'T4'}\n        ,{k:'Picread::Retry',n: t('mj.retry')}\n        \n        ,{k:'PromptAnalyzer::1',n:'T1'}\n        ,{k:'PromptAnalyzer::2',n:'T2'}\n        ,{k:'PromptAnalyzer::3',n:'T3'}\n        ,{k:'PromptAnalyzer::4',n:'T4'}\n        ,{k:'PromptAnalyzer::5',n:'T5'}\n\n        //PromptAnalyzer::1\n       // ,{k:'Job::PicReader::all',n:'全4张'}\n    ]\n    ,[\n    {k:':variation::1',n:'V1'}\n    ,{k:':variation::2',n:'V2'}\n    ,{k:':variation::3',n:'V3'}\n    ,{k:':variation::4',n:'V4'}\n    ,{k:'pan_left',n: t('mj.pan_left')}\n    ,{k:'pan_right',n:t('mj.pan_right') }\n    ,{k:'pan_up',n:t('mj.pan_up')}\n    ,{k:'pan_down',n:t('mj.pan_down')}\n    ,{k:'reroll::0',n: t('mjchat.reroll')}\n    ,{k:'upsample_v5_2x',n:t('mj.up2')}\n    ,{k:'upsample_v5_4x',n:t('mj.up4')} \n    ,{k:'upsample_v6_2x_subtle',n:t('mj.subtle')}//t('mj.up2') 'Subtle'\n    ,{k:'upsample_v6_2x_creative',n:t('mj.creative')}  //'Creative'\n    ,{k:'upsample_v6r1_2x_subtle',n:t('mj.subtle')} \n    ,{k:'upsample_v6r1_2x_creative',n:t('mj.creative')} \n    ,{k:'upsample_v7_2x_subtle',n:t('mj.subtle')} \n    ,{k:'upsample_v7_2x_creative',n:t('mj.creative')} \n    ]\n]\n\nconst getIndex = (arr:any[], ib:any )=> arr.findIndex( (v9:any)=>v9.customId.indexOf(ib.k)>-1 ) ;\nconst getIndexName=  (arr:any[], ib:any )=> {\n  const i= getIndex( arr,ib);\n  if(ib.k=='upsample_v5_2x') return ib.n; \n\n  if(ib.k=='upsample_v5_4x') return ib.n;\n  //if(ib.k=='upsample_v6_4x') return ib.n;\n  if(ib.k.indexOf('upsample_v6_2x')>-1 ) return ib.n;\n\n  return `${arr[i].emoji} ${ib.n}`;\n}\n\nconst load = async (isFlash=false )=>{\n     changCustom();\n     if(!chat.value.mjID) return ;\n     let key= 'img:'+chat.value.mjID;\n    try {\n        if(chat.value.opt?.videoUrls || chat.value.opt?.imageUrls){\n        } else if(chat.value.opt?.imageUrl){\n            //await loadImg(chat.value.opt?.imageUrl);\n            let base64 = await localGet(key );  \n            if(!base64 || isFlash ) {\n                const ubase64=  await url2base64( mjImgUrl(  chat.value.opt?.imageUrl ) ,key );\n                base64= ubase64.base64;\n                mlog('图片已保存>>', ubase64.key )\n            }\n            st.value.uri_base64=base64;\n        }\n    } catch (error) {\n        mlog('图片保存失败',error);\n    }\n    \n    st.value.isLoadImg=true;\n}\n\nwatch(()=>homeStore.myData.act,(n)=>{\n    const actData :any= homeStore.myData.actData;\n    if(n=='mjReload' &&  actData.mjID== chat.value.mjID ){ //&& actData.mjID==chat.value.mjID\n         mlog('mjReload', actData.mjID, chat.value.mjID , chat.value.opt?.imageUrl);\n         if( !st.value.isLoadImg){\n            ms.success( t('mj.fail1'));\n            return ;\n         }\n         st.value.isLoadImg=false;\n         load( true );\n         if( !actData.noShow ) ms.success( t('mj.success1'));\n    }\n})\nconst text = computed(() => {\n  let  value =   props.chat.opt?.properties?.finalZhPrompt \n  if(value==''){\n     value= props.chat.opt?.properties?.finalPrompt \n  }\n return props.mdi.render(value)\n   \n})\n\n\nconst changCustom = ()=>{\n    mlog('changCustom', chat.value.opt); //prompt\n    st.value.customText=chat.value.opt?.prompt??'';\n    \n    st.value.customText +=\"  --zoom 1.8\";\n}\n\n// const imageUrl= computed( ()=>{\n//     if(chat.value.opt?.imageUrl) return chat.value.opt?.imageUrl;\n//     return ''\n// });\n\nconst otherButton= computed(()=>{\n    //mlog('otherButton');\n    \n    if( chat.value.opt?.buttons && chat.value.opt?.buttons.length>0){\n     \n        let  rz= [...chat.value.opt?.buttons]\n        // mlog('otherButton222',rz.length );\n        for(let bts of bt ){\n            for(let ib of bts){\n                let i= getIndex(rz, ib)\n                if(i>-1) rz.splice(i,1)\n            }\n        }\n        let i= rz.findIndex(v=>v.customId.indexOf('BOOKMARK')>-1) //BOOKMARK\n        if(i>-1) rz.splice(i,1)\n        //mlog('otherButton2323',rz.length,rz );\n        return rz \n\n    }\n    return []\n})\n\nconst subV3=(type:string)=>{\n    mst.value.isShow= true\n    mst.value.type= type\n}\n\nload();\n</script>\n<template>\n<div v-if=\"st.isLoadImg\">\n    <div v-if=\"chat.opt?.status=='FAILURE'\"> \n        <div>{{ $t('mjchat.failReason') }}<p>{{ chat.opt?.failReason }}</p></div>\n    </div>\n    <template  v-else-if=\"chat.opt?.progress\">\n       \n        <div v-if=\"chat.opt?.action=='SHORTEN'\" class=\"markdown-body\" v-html=\"text \" > \n             \n        </div> \n        <div v-else-if=\"chat.opt?.action!='IMAGINE'\" class=\"py-2 text-[#666]  whitespace-pre-wrap\">{{ chat.opt?.promptEn }} (<span v-html=\"chat.opt?.action\"></span>)</div> \n        <div v-if=\"chat.opt.videoUrls\"  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-2\" >\n            <div v-for=\"(v,k) in chat.opt.videoUrls\" class=\"relative\"  @mouseover=\"st.ctrIndex=k\" >\n                <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[8px] overflow-hidden aspect-[16/8.85]\">\n                    <video  :src=\"v.url\" :controls=\"st.ctrIndex==k\"  loop playsinline class=\"w-full h-full object-cover\"></video>\n                </div>\n                <a class=\"absolute top-[8px] right-[8px] cursor-pointer\" target=\"_blank\" :href=\"v.url\" :download=\"(k+1)+'.mp4'\"><SvgIcon icon=\"mdi:download\" /></a>\n            </div>\n        </div>\n        <div v-else-if=\"chat.opt.imageUrls\" class=\"grid grid-cols-2 grid-rows-2 gap-0 max-w-[500px]\" >\n             <div v-for=\"(v,k) in chat.opt.imageUrls\" class=\"relative aspect-square overflow-hidden\"  @mouseover=\"st.ctrIndex=k\" >\n                 \n                 <NImage  :src=\"v.url\"     class=\"w-full h-full object-cover\"/>\n                 \n                <a class=\"absolute top-[8px] right-[8px] cursor-pointer\" target=\"_blank\" :href=\"v.url\" :download=\"(k+1)+'.mp4'\"><SvgIcon icon=\"mdi:download\" /></a>\n            </div>\n        </div>\n        <NImage v-else-if=\"chat.opt.imageUrl\" :src=\"st.uri_base64?st.uri_base64: mjImgUrl( chat.opt.imageUrl)\" class=\" rounded-sm \" :class=\"[isMobile?'':'!max-w-[500px]']\"  /> \n        <div v-if=\"chat.opt?.status=='SUCCESS' \" class=\" space-y-2\"  >\n            <template v-if=\"chat.opt?.buttons\">\n                <div v-for=\"(bts,ii) in bt\" class=\" flex justify-start items-center flex-wrap \"> \n                    <template v-for=\"ib in bts\" >\n                    <div class=\"p-1\" v-if=\"   getIndex(chat.opt?.buttons, ib) >-1\"> \n                        <NButton  @click=\"subV2(ib)\" size=\"small\" :type=\"ii==1?'warning':'primary'\" >{{  getIndexName(chat.opt?.buttons, ib)  }}  </NButton>\n                    </div>\n                    </template>\n                </div>\n                <div v-if=\"otherButton.length>0\" class=\" flex justify-start items-center flex-wrap \" >\n                    \n                     <div class=\"p-1\"  v-for=\"ib in otherButton\"> \n                        <NButton  @click=\"subV2(ib)\" size=\"small\" type=\"info\" >{{  ib.emoji??''  }}{{ ib.label??'' }}  </NButton>\n                    </div>\n                </div>\n\n                <div class=\" flex justify-start items-center flex-wrap \" v-if=\"chat.opt?.action==='UPSCALE' || 'DESCRIBE'===chat.opt?.action\">\n                    <div class=\"p-1\"><NButton  @click=\"subV3('video')\" size=\"small\" type=\"info\" > <SvgIcon icon=\"ri:video-add-line\"  />{{ $t('mj.editVideo') }}</NButton> </div>  \n                    <div class=\"p-1\"><NButton  @click=\"subV3('image')\" size=\"small\" type=\"info\" >{{ $t('mj.editImage') }}</NButton></div>\n                </div>\n\n                 \n            </template>\n            <template v-else-if=\"chat.opt?.action==='UPSCALE' || 'DESCRIBE'===chat.opt?.action\"></template>\n            <template v-else>\n                <div class=\"flex space-x-2\">\n                    <NButton type=\"primary\" @click=\"sub('UPSCALE',1)\" size=\"small\">U1</NButton>\n                    <NButton type=\"primary\" @click=\"sub('UPSCALE',2)\"  size=\"small\">U2</NButton>\n                    <NButton type=\"primary\" @click=\"sub('UPSCALE',3)\"  size=\"small\">U3</NButton>\n                    <NButton type=\"primary\" @click=\"sub('UPSCALE',4)\"  size=\"small\">U4</NButton>\n                </div>\n                <div class=\"flex space-x-2\">\n                    <NButton type=\"warning\" @click=\"sub('VARIATION',1)\"  size=\"small\">V1</NButton>\n                    <NButton type=\"warning\" @click=\"sub('VARIATION',2)\"  size=\"small\">V2</NButton>\n                    <NButton type=\"warning\" @click=\"sub('VARIATION',3)\"  size=\"small\">V3</NButton>\n                    <NButton type=\"warning\" @click=\"sub('VARIATION',4)\"  size=\"small\">V4</NButton>\n                    <NButton type=\"warning\" @click=\"sub('REROLL',1)\"  size=\"small\" v-if=\"chat.opt?.action==='IMAGINE'\">{{ $t('mjchat.reroll') }}</NButton>\n\n                </div>\n            </template>\n        </div>\n        <div v-else-if=\"!chat.loading\"> <NButton type=\"primary\" @click=\"reload()\">{{ $t('mjchat.reload') }}</NButton></div>\n        <div v-else-if=\"chat.opt.progress\" class=\"py-2 min-w-[200px]\"> {{$t('mjchat.progress')}}{{chat.opt.progress}}</div>\n        <div v-else class=\"py-2\"> {{ $t('mjchat.wait') }}</div>\n        <!-- <div v-html=\"chat.opt?.action\"></div> -->\n    </template>\n    <div v-else> \n     {{ $t('mjchat.wait2',{id:chat.mjID}) }}\n        <div v-if=\"!chat.loading\"> <NButton type=\"primary\" @click=\"reload()\">{{ $t('mjchat.reload') }}</NButton></div>\n\n    </div>\n    <div class=\" hidden\">{{ chat.dateTime }}</div>\n\n    <NModal v-model:show=\"st.isShow\"   preset=\"card\"  :title=\"$t('mjchat.redrawEditing')\" style=\"max-width: 800px;\" @close=\"st.isShow=false\" >\n        <aiCanvas :chat=\"chat\" :base64=\"st.uri_base64\" v-if=\"st.isShow\" @success=\"maskOk\" />\n    </NModal>\n    <NModal v-model:show=\"st.isCustom\"   preset=\"card\"  :title=\"$t('mj.customTitle')\" style=\"max-width: 600px;\" @close=\"st.isCustom=false\" >\n         <n-input    type=\"textarea\"  v-model:value=\"st.customText\"    round   maxlength=\"2000\" show-count \n      :autosize=\"{   minRows:3, maxRows:8 }\" />\n           <div class=\"pt-2 flex justify-between items-center\">  \n                <div class=\"text-neutral-500\">{{ $t('mj.zoominfo') }}</div>   \n                <NButton type=\"primary\"    size=\"small\" @click=\"subCustom\">{{ $t('mjchat.submit') }}</NButton> \n          </div>\n    </NModal>\n\n    <NModal v-model:show=\"mst.isShow\"   preset=\"card\"  :title=\" mst.type=='video'?$t('mj.editVideo'):$t('mj.editImage')\" style=\"max-width: 800px;\" @close=\"mst.isShow=false\">\n          <AiEditVidoe :chat=\"chat\" :img=\"st.uri_base64\" @success=\"mst.isShow=false\"  v-if=\"mst.isShow && mst.type=='video'\"   />\n          <AiEditImage :chat=\"chat\" :img=\"st.uri_base64\" @success=\"mst.isShow=false\"  v-if=\"mst.isShow && mst.type=='image'\"   />\n    </NModal>\n</div>\n<div v-else class=\"w-[200px] h-[150px] flex flex-col justify-center items-center\" >\n    <div class=\"p-4\">{{ $t('mjchat.loading') }}</div>\n    \n    <NButton type=\"primary\" v-if=\"chat.opt?.imageUrl\" ><a :href=\" mjImgUrl(chat.opt?.imageUrl)\" target=\"_blank\">{{ $t('mjchat.openurl') }}</a></NButton> \n</div>\n\n\n\n</template>\n\n<style>\n.markdown-body img.maxCss,img.maxCss ,.maxCss img  { max-width: 400px!important; max-height: 400px!important;}\n.mmWidth{ max-width: 600px;}\nhtml.dark .markdown-body pre code { color:#abb2bf; }\n</style>"
  },
  {
    "path": "src/views/mj/mjTextAttr.vue",
    "content": "<script lang=\"ts\" setup>\nimport { localGet, mlog } from \"@/api\";\nimport { ref } from \"vue\";\nimport { NImage } from \"naive-ui\";\nimport { SvgIcon } from \"@/components/common\";\n\nconst pp = defineProps<{ image: string }>();\nconst images = ref<{ fileName: string; fileBase64: string }[]>([]);\nconst files = ref<{ fileName: string; fileBase64: string }[]>([]);\n\nconst isImage = (url:string) => {\n  const extensions = [\".jpeg\", \".jpg\", \".png\", \".gif\", \".webp\"];\n  url = url.toLowerCase();\n  return extensions.some((ext) => url.endsWith(ext));\n};\n\nconst loadImages = async () => {\n  //mlog(\"loadImages\", pp.image);\n  try {\n    const response = await localGet(pp.image);\n    if (response) {\n      const parsedData = JSON.parse(response);\n      if (\n        Array.isArray(parsedData.fileName) &&\n        Array.isArray(parsedData.fileBase64)\n      ) {\n        const combinedData = parsedData.fileName.map(\n          (name: string, index: number) => ({\n            fileName: name,\n            fileBase64: parsedData.fileBase64[index],\n          })\n        );\n\n        images.value = combinedData.filter((file) => isImage(file.fileName));\n        files.value = combinedData.filter((file) => !isImage(file.fileName));\n      }\n    }\n  } catch (error) {\n    console.error(\"Failed to load images:\", error);\n  }\n};\n\nloadImages();\n</script>\n\n<template>\n  <div v-if=\"images.length\" class=\"flex flex-wrap justify-start items-baseline p-1\">\n    <div v-for=\"(img, k) of images\" :key=\"k\">\n      <NImage :src=\"img.fileBase64\" preview class=\"rounded\" :class=\"[images.length <= 1 ? 'w-[250px]' : 'w-[130px]']\">\n        <template #placeholder>\n          <a class=\"w-full h-full flex items-center justify-center text-neutral-500\" :href=\"img.fileBase64\"\n            target=\"_blank\">\n            <SvgIcon icon=\"mdi:download\" />{{ img.fileName }}\n          </a>\n        </template>\n      </NImage>\n    </div>\n  </div>\n  <div v-if=\"files.length\" class=\"block justify-start items-baseline p-1\">\n    <div v-for=\"(file, k) of files\" :key=\"k\" :class=\"[\n      'w-full h-full block items-center text-xs text-neutral-500',\n      { 'mb-1': k !== files.length - 1 },\n    ]\">\n      <a :href=\"file.fileBase64\" target=\"_blank\" class=\"flex items-center\">\n        <SvgIcon icon=\"mdi:download\" class=\"mr-2\" />\n        <n-ellipsis style=\"max-width: 280px\">\n          {{ file.fileName }}\n        </n-ellipsis>\n      </a>\n    </div>\n  </div>\n</template>"
  },
  {
    "path": "src/views/mj/myTest.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api'; \nimport { ref } from \"vue\";\nimport { NButton,NInput } from \"naive-ui\";\n\nconst f = ref({text:'Hi,google ! I am a good student!'});\nconst go = async () => {\n    \n  const apiKey = 'sdsd-121212';\n\nconst apiUrl = 'https://api.openai-sk.com/v1/audio/speech';\nconst ttsModel = 'tts-1';\nconst voice = 'alloy';\n//const inputText = 'I am a good student!';\n\n//const fetchData = async () => {\n  try {\n    const response = await fetch(apiUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Authorization': `Bearer ${apiKey}`,\n      },\n      body: JSON.stringify({\n        model: ttsModel,\n        input: f.value.text ,\n        voice: voice,\n      }),\n    });\n\n    if (!response.ok) {\n      throw new Error(`API request failed with status ${response.status}`);\n    }\n\n    const audioData = await response.arrayBuffer();\n    const blob = new Blob([audioData], { type: 'audio/mp3' });\n    mlog('blob', blob);\n\n    const player = new window.Audio(); \n    player.src = URL.createObjectURL(blob);\n    player.addEventListener('ended', () => {\n      mlog('音乐播放完毕');\n    });\n     player.addEventListener('loadedmetadata', () => {\n      mlog('时长', player.duration);\n    });\n    player.load(); \n    player.play();\n\n\n     const a = document.createElement('a');\n    a.href = URL.createObjectURL(blob);\n    a.download = 'speech.mp3';\n    document.body.appendChild(a);\n    a.click();\n    document.body.removeChild(a);\n  }catch (error) {\n    console.error('Error:', error);\n  }\n\n \n}\n//go();\n\n  const ccgo= (event:any )=> {\n    var file = event.target.files[0];\n\n    // 通过 FileReader 读取文件内容并创建 Blob 对象\n    var reader = new FileReader();\n    reader.onload = function(e:any ) {\n      var blob = new Blob([e.target.result], { type: 'audio/mp3' });\n      mlog('blob', blob);\n\n      // 创建 Howl 实例\n    //  let  sound = new Howl({\n    //     src: [blob],\n    //     format: ['mp3'],\n    //     volume: 0.5,\n    //     onend: function() {\n    //       console.log('音乐播放完毕');\n    //     }\n    //     ,onloaderror:(e:any )=>{\n    //          mlog('onloaderror' ,e  )\n    //     }\n    //   });\n    //   sound.play(); \n    const player = new window.Audio(); \n    player.src = URL.createObjectURL(blob);\n    player.addEventListener('ended', () => {\n      mlog('音乐播放完毕');\n    });\n     player.addEventListener('loadedmetadata', () => {\n      mlog('时长', player.duration);\n    });\n    player.load(); \n    player.play();\n \n    };\n\n    reader.readAsArrayBuffer(file);\n  } \n</script>\n<template>\n<!-- <div class=\"text-red-300\" >good</div>\n<div class=\"text-red-300\" @click=\"go\" >go</div>\n<div class=\"text-red-300\" @click=\"sound.stop() \" >eend</div> -->\n<div class=\"p-4 space-y-4\">\n<NInput v-model:value=\"f.text\" type=\"textarea\"></NInput>\n<NButton @click=\"go\" type=\"primary\">提交</NButton>\n<div>\n<input type=\"file\" id=\"audioFile\" accept=\"audio/*\" @change=\"ccgo\">\n</div>\n</div>\n\n\n</template>"
  },
  {
    "path": "src/views/mj/ttsText.vue",
    "content": "<script setup lang=\"ts\">\nimport { localGet, mlog } from '@/api';\nimport { SvgIcon } from '@/components/common';\nimport { homeStore } from '@/store';\nimport {   ref ,onUnmounted ,watch} from 'vue'\ninterface Props {   chat:Chat.Chat,isW?:boolean }\nconst st= ref({isLoad:0, bolb:''});\nconst props = defineProps<Props>();\nconst player = new window.Audio(); \nconst mybolb = ref<Blob>();\n\nconst load= async ()=>{\n    if( !props.chat.opt?.lkey ) return ;\n    let blob = await localGet( props.chat.opt?.lkey ) as Blob;\n    //st.value.bolb= blob;\n    mybolb.value =blob;\n    player.src = URL.createObjectURL(blob);\n    player.addEventListener('ended', () => {\n        st.value.isLoad=0;\n    });\n    player.addEventListener('play', () => {\n        st.value.isLoad=1;\n    }) \n    player.addEventListener('pause', function() {\n         st.value.isLoad=2;\n    });\n    player.addEventListener('timeupdate', function(e) {\n        // 音频播放位置变化时的操作\n        mlog('timeupdate'  ,player.currentTime ,player.duration );\n    });\n    player.load();\n}\nconst go= ()=>{\n    if(st.value.isLoad==1 ) player.pause();\n    else player.play();\n}\nconst getWidth= ()=>{\n    if(props.isW) return '100%';\n    let w=0.3;\n    if(props.chat.opt?.duration){\n        if(props.chat.opt?.duration>60) w=1;\n        else w=props.chat.opt?.duration/45;\n        w=0.3+w;\n        if(w>1) w=1;\n    }\n    return (w*280)+'px';\n}\nconst download = ()=>{\n    if(!mybolb.value || !props.chat.opt?.lkey ) return ;\n    const a = document.createElement('a');\n    a.href = URL.createObjectURL(mybolb.value);\n    a.download =props.chat.model+'_' + (props.chat.opt?.lkey?.replace(/\\:/ig,'-')) +'.mp3';\n    document.body.appendChild(a);\n    a.click();\n    document.body.removeChild(a);\n}\nwatch(()=>homeStore.myData.act, (n=>{\n    const data:any = homeStore.myData.actData ;\n    mlog('act',n,data); \n    if(n=='playtts' && props.chat.opt?.lkey==data.saveID  ){\n        player.play();\n    }\n}));\nonUnmounted(()=>player.pause())  \nload();\n</script>\n<template>\n<div  class=\"markdown-body\"  :class=\"[props.isW?'border-t border-neutral-400/25 ':'']\" style=\"padding-top: 5px; margin-top: 5px;\" >\n    <div class=\" flex justify-between items-center \" :style=\"{width:getWidth()}\">\n        <div class=\"flex justify-start items-center flex-1\" @click=\"go\">\n            <span v-html=\"chat.opt?.duration?.toFixed(2)\"  ></span>s \n            <div class=\" rotate-90  cursor-pointer\"   >\n                <SvgIcon icon=\"svg-spinners:wifi\" v-if=\"st.isLoad==1\" ></SvgIcon>\n                <SvgIcon icon=\"mdi:wifi\"  v-else></SvgIcon>\n            </div>\n        </div>\n        <div  class=\"text-blue-500 cursor-pointer\" @click=\"download\"> <SvgIcon icon=\"ri:download-2-fill\"></SvgIcon> </div>\n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/mj/whisperText.vue",
    "content": "<script setup lang=\"ts\">\nimport { localGet, mlog } from '@/api';\nimport { SvgIcon } from '@/components/common'; \nimport {   ref ,onUnmounted } from 'vue'\nconst st= ref({isLoad:0, bolb:'',fileName:'',duration:0});\nconst props = defineProps<{ chat:Chat.Chat,isW?:boolean}>();\nconst player = new window.Audio(); \nconst mybolb = ref<Blob>();\nconst load= async ()=>{\n    if( !props.chat.opt?.lkey ) return ;\n    let dd:any = await localGet( props.chat.opt?.lkey ) ;\n    let blob= dd.blob as Blob;\n    mlog('dd', dd.filename);\n    st.value.fileName = dd.filename;\n    //st.value.bolb= blob;\n    mybolb.value =blob;\n    player.src = URL.createObjectURL(blob);\n    player.addEventListener('ended', () => {\n        st.value.isLoad=0;\n    });\n    player.addEventListener('play', () => {\n        st.value.isLoad=1;\n    }) \n    player.addEventListener('pause', function() {\n         st.value.isLoad=2;\n    });\n    player.addEventListener('timeupdate', function(e) {\n        // 音频播放位置变化时的操作\n        //mlog('timeupdate'  ,player.currentTime ,player.duration );\n    });\n     player.addEventListener('loadedmetadata', function() {\n         st.value.duration= player.duration ;\n    });\n    player.load();\n}\nconst go= ()=>{\n    if(st.value.isLoad==1 ) player.pause();\n    else player.play();\n}\n// const getWidth= ()=>{\n//     let w=0.3;\n//     if(props.chat.opt?.duration){\n//         if(props.chat.opt?.duration>60) w=1;\n//         else w=props.chat.opt?.duration/45;\n//         w=0.3+w;\n//         if(w>1) w=1;\n//     }\n//     return (w*280)+'px';\n// }\nconst download = ()=>{\n    if(!mybolb.value || !props.chat.opt?.lkey ) return ;\n    const a = document.createElement('a');\n    a.href = URL.createObjectURL(mybolb.value);\n    a.download ='ddaiai_'+ st.value.fileName ;//props.chat.model+'_' + (props.chat.opt?.lkey?.replace(/\\:/ig,'-')) +'.mp3';\n    document.body.appendChild(a);\n    a.click();\n    document.body.removeChild(a);\n}\nonUnmounted(()=>player.pause())  \nload();\n\n</script>\n<template>\n<div   class=\"whitespace-pre-wrap \" :class=\"[props.isW?'border-t border-neutral-400/25':'']\"  >\n    <div class=\" flex justify-between items-center w-full\" >\n        <div  class=\"text-blue-500 cursor-pointer mr-8\" @click=\"download\"> <SvgIcon icon=\"ri:download-2-fill\"></SvgIcon> </div>\n\n        <div class=\"flex justify-end items-center flex-1\" @click=\"go\">\n            <span v-html=\"chat.opt?.duration.toFixed(2)+`s`\"  v-if=\"chat.opt && chat.opt?.duration \" ></span>\n            <span v-html=\"st.fileName\" v-else ></span>\n            <div class=\" rotate-90  cursor-pointer\"   >\n                <SvgIcon icon=\"svg-spinners:wifi\" v-if=\"st.isLoad==1\" ></SvgIcon>\n                <SvgIcon icon=\"mdi:wifi\"  v-else></SvgIcon>\n            </div>\n        </div>\n    </div>\n</div>\n</template> "
  },
  {
    "path": "src/views/suno/layout.vue",
    "content": "<script setup lang='ts'>\nimport { computed } from 'vue'\nimport { NLayout, NLayoutContent } from 'naive-ui'\nimport { useRouter } from 'vue-router'\nimport player from './player.vue';\nimport Permission from '../chat/layout/Permission.vue'\nimport { useBasicLayout } from '@/hooks/useBasicLayout'\nimport { homeStore, useAppStore, useAuthStore, useChatStore } from '@/store'\nimport { aiSider ,aiFooter} from '@/views/mj'\nimport aiMobileMenu from '@/views/mj/aiMobileMenu.vue'; \n\nconst router = useRouter()\nconst appStore = useAppStore()\nconst chatStore = useChatStore()\nconst authStore = useAuthStore()\n\nrouter.replace({ name: 'music', params: { uuid: chatStore.active } })\nhomeStore.setMyData({local:'music'});\nconst { isMobile } = useBasicLayout()\n\nconst collapsed = computed(() => appStore.siderCollapsed)\n\nconst needPermission = computed(() => !!authStore.session?.auth && !authStore.token)\n\nconst getMobileClass = computed(() => {\n  if (isMobile.value)\n    return ['rounded-none', 'shadow-none' ]\n  return [ 'shadow-md', 'dark:border-neutral-800' ] //'border', 'rounded-md',\n})\n\nconst getContainerClass = computed(() => {\n  return [\n    'h-full',\n    { 'abc': !isMobile.value && !collapsed.value },\n  ]\n}) \n</script>\n\n<template>\n  <div class=\"dark:bg-[#24272e] transition-all p-0\" :class=\"[isMobile ? 'h55' : 'h-full' ]\">\n    <div class=\"h-full overflow-hidden\" :class=\"getMobileClass\">\n      <NLayout class=\"z-40 transition\" :class=\"getContainerClass\" has-sider  :sider-placement=\"isMobile?'left': 'right'\">\n        <aiSider v-if=\"!isMobile\"/>\n       \n        <NLayoutContent class=\"h-full\">\n          <RouterView v-slot=\"{ Component, route }\">\n            <component :is=\"Component\" :key=\"route.fullPath\" />\n          </RouterView>\n        </NLayoutContent>\n         <!-- <Sider /> -->\n      </NLayout>\n    </div>\n    <Permission :visible=\"needPermission\" />\n  </div>\n   <aiMobileMenu v-if=\"isMobile\"   /> \n  <aiFooter/>\n  <player/>\n</template>\n<style  >\n.h55{\n  height: calc(100% - 55px);\n}\n</style>\n"
  },
  {
    "path": "src/views/suno/mcInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref,computed ,onMounted, watch} from 'vue';\nimport { NTabs ,NTabPane ,NInput,NSwitch ,NTooltip, NTag ,NButton, useMessage,NSelect, NImage, NSlider} from \"naive-ui\";\nimport { SvgIcon } from '@/components/common';\nimport { mlog } from '@/api';\nimport { sunoFetch ,lyricsFetch, randStyle, FeedTask} from '@/api/suno';\nimport { t } from '@/locales';\nimport { homeStore } from '@/store';\nimport { SunoMedia } from '@/api/sunoStore';\nimport mcUploaderMp3 from './mcUploadMp3.vue'\n\nconst st = ref({type:'custom',isLoading:false})\nconst exSuno= ref<SunoMedia>()\nconst des= ref( {\n  \"gpt_description_prompt\": \"\",\n  \"make_instrumental\": false,\n  \"mv\": \"chirp-crow\",\n  \"prompt\": \"\"\n});\nconst cs= ref({\n  \"prompt\": \"\",\n  \"mv\": \"chirp-crow\",\n  \"title\": \"\",\n  \"tags\": \"\",\n  \"continue_at\": 120,\n  \"continue_clip_id\": \"\",\n  \"task\":''\n\n});\n\nconst mvOption= [\n{label: 'verion: v3.5',value: 'chirp-v3-5'}\n,{label:'verion: v3',value: 'chirp-v3-0'}\n,{label:'verion: v4',value: 'chirp-v4'}\n,{label:'verion: v4.5-all',value: 'chirp-auk-turbo'}\n,{label:'verion: v4.5',value: 'chirp-auk'}\n,{label:'verion: v4.5+',value: 'chirp-bluejay'}\n,{label:'verion: v5',value: 'chirp-crow'}\n ]\n\nconst canPost = computed(() => {\n   // return true; \n    if( st.value.isLoading ) return false;\n    if( st.value.type=='custom'){\n        return cs.value.tags && cs.value.title\n    }\n    if( st.value.type=='description' ){\n        mlog('des: ', des.value.gpt_description_prompt , des.value.make_instrumental )\n        return cs.value.title &&( des.value.gpt_description_prompt || des.value.make_instrumental)\n    }\n    return true\n})\n\nconst ms = useMessage();\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n});\n//生成歌词\nconst generateLyrics= ()=>{\n    //generate/lyrics\n    let prompt = cs.value.prompt || cs.value.title;\n    if (!prompt){\n        ms.error(   t('suno.inputly') )\n        return \n    }\n    if(st.value.isLoading) {\n         ms.info( t('suno.doingly'));\n        return;\n    }\n    st.value.isLoading =true;\n    ms.info( t('suno.doingly2') );\n    sunoFetch(  '/generate/lyrics/' ,  {prompt}).then(async (r:any )=>{\n        mlog('lyrics', r);\n        let dz:any = await lyricsFetch( r.id );\n        \n         mlog('lyrics rz =>', dz );\n        if(dz!=null){  \n\n            cs.value.prompt= dz.text;\n            cs.value.title= dz.title;\n        }else{\n            ms.error( t('suno.lyricsFail') );\n           \n        }\n        st.value.isLoading =false;\n\n    }).catch(()=>  st.value.isLoading =false );\n    if( !cs.value.tags ) cs.value.tags= randStyle()\n}\n\nconst generate= async ()=>{\n    st.value.isLoading =false;\n    let ids:string[]=[];\n     \n\n    if(st.value.type=='custom'){ \n        if(des.value.make_instrumental) cs.value.prompt='';\n        if( cs.value.continue_clip_id!=''  ){\n            //chirp-v3-5-upload\n           // cs.value.mv='chirp-v3-5-upload'\n           if( exSuno.value?.metadata?.type=='upload') cs.value.task='upload_extend'\n           else cs.value.task='extend'\n        }\n       \n        let r:any= await sunoFetch(  '/generate' ,  cs.value ) \n        st.value.isLoading =false;\n\n       ids=r.clips.map((r:any)=>r.id);\n       mlog('ids ', ids );\n       if( cs.value.mv='chirp-v3-5-upload' ) cs.value.mv='chirp-v4'\n    }else{\n        des.value.prompt='';//cs.value.title;\n        // cs.value.prompt=''\n        let r:any= await sunoFetch(  '/generate/description-mode' ,  des.value )  \n        st.value.isLoading =false; \n        ids=r.clips.map((r:any)=>r.id);\n    }\n    cs.value.task='';\n    FeedTask(ids)\n}\n\n\n\n\n\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='suno.extend'){\n        mlog(\"suno.extend\", homeStore.myData.actData )\n        const s= homeStore.myData.actData as SunoMedia\n        exSuno.value= s \n        cs.value.continue_clip_id= s.id\n        cs.value.continue_at= Math.ceil(s.metadata.duration/2) \n    }\n});\n\n</script>\n<template>\n<div class=\"p-2\"> \n    <n-tabs type=\"segment\" animated  v-model:value=\"st.type\">\n        <!-- <n-tab-pane name=\"start\" tab=\"\"> \n\n        </n-tab-pane> -->\n        <!-- <NText depth=\"3\" class=\"text-center\">{{ $t('suno.mic') }}</NText> -->\n        <n-tab-pane name=\"description\" :tab=\"$t('suno.description')\">\n            <div class=\"pt-1\">\n                <n-input :placeholder=\"$t('suno.titlepls')\" v-model:value=\"cs.title\">\n                <template #prefix>\n                     <span>{{$t('suno.title')}}：</span>\n                </template>\n                </n-input>\n            </div>\n            <div  class=\"pt-4 flex justify-between\">\n                <div>{{$t('suno.desc')}}:</div>\n                <div> \n                    <n-switch v-model:value=\"des.make_instrumental\" size=\"small\">\n                        <template #checked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                        <template #unchecked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                    </n-switch>\n                </div>\n            </div>\n            <div  class=\"pt-1\"> \n            <n-input v-model:value=\"des.gpt_description_prompt\" :disabled=\"des.make_instrumental\"\n                :placeholder=\"$t('suno.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n            </div>\n            <div  class=\"pt-1\">\n                 <n-select v-model:value=\"des.mv\" :options=\"mvOption\" size=\"small\" />\n            </div>\n        </n-tab-pane>\n\n        <n-tab-pane name=\"custom\" :tab=\"$t('suno.custom')\">\n            <div class=\"pt-1\">\n                <n-input :placeholder=\"$t('suno.titlepls')\" v-model:value=\"cs.title\">\n                <template #prefix>\n                     <span>{{$t('suno.title')}}：</span>\n                </template>\n                </n-input>\n            </div>\n             <div class=\"pt-4\">\n                <n-input :placeholder=\"$t('suno.stylepls')\" v-model:value=\"cs.tags\">\n                    <template #prefix>\n                        <span>{{$t('suno.style')}}：</span>\n                    </template>\n                    <template #suffix>\n                        <n-tooltip placement=\"right\" trigger=\"hover\">\n                            <template #trigger>\n                                <div class=\"cursor-pointer\" @click=\"cs.tags= randStyle()\"><SvgIcon  icon=\"fa:random\" class=\"w-4 h-4\" /></div>\n                            </template>\n                            <div>{{$t('suno.rank')}}</div>\n                            \n                        </n-tooltip>\n                    </template>\n                </n-input>\n            </div>\n\n            <div  class=\"pt-4 flex justify-between\">\n                <div>{{$t('suno.ly')}} :</div>\n                <div> \n                    <n-switch v-model:value=\"des.make_instrumental\" size=\"small\">\n                        <template #checked>\n                        {{ $t('suno.noneedly') }}\n                        </template>\n                        <template #unchecked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                    </n-switch>\n                </div>\n            </div>\n            <div  class=\"pt-1\"> \n                <n-input v-model:value=\"cs.prompt\" :disabled=\"des.make_instrumental\"\n                :placeholder=\"$t('suno.lypls')\" type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n            </div>\n            <div  class=\"pt-1\">\n                <n-select v-model:value=\"cs.mv\" :options=\"mvOption\" size=\"small\" />\n            </div>\n            <template v-if=\"cs.continue_clip_id && exSuno\">\n                <div  class=\"pt-5\">\n                    <div class=\"flex justify-between pb-3\">\n                        <div class=\"text-[12px]\"> {{ $t('suno.extendAt') }} {{ cs.continue_at }}s</div>\n                        <NTag  type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"cs.continue_clip_id=''\" >清除</span></NTag>\n\n                    </div>\n                    <n-slider v-model:value=\"cs.continue_at\" :step=\"1\" :max=\"Math.ceil( exSuno.metadata.duration)\">\n                        <template #thumb>\n                            <div class=\"bg-[--n-fill-color] text-[9px]  border-[0px]  px-1 list-none rounded-md\">{{ cs.continue_at }}s</div>\n                        </template>\n                    </n-slider>\n                </div>\n                <div  class=\"pt-1\"  >\n                    <div class=\"flex relative  justify-between items-start p-2 hover:dark:bg-black hover:bg-gray-200 border-b-[1px] border-gray-500/10 \">\n                        <div class=\"w-[60px] h-[60px] relative  cursor-pointer\" >\n                            <n-image  lazy  width=\"100\"  :src=\"exSuno.image_url\" preview-disabled  >\n                                <template #placeholder>\n                                    <div class=\"w-full h-full justify-center items-center flex\"  >\n                                    <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                                    </div>\n                                </template>\n                            </n-image>\n                        </div>\n                        <div class=\"flex-1  pl-2\"> \n                            <div class=\"flex justify-between line-clamp-1 w-full cursor-pointer\"  >\n                                <h3>{{exSuno.title}}</h3>\n                                <!-- <div class=\"opacity-80\"  >{{exSuno.metadata.tags}}</div> -->\n                            </div>\n                            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"   v-if=\"exSuno.metadata && exSuno.metadata.prompt\">\n                            {{exSuno.metadata.prompt}}\n                            </div>\n                            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  v-else>\n                            {{$t('suno.noly')}}\n                            </div>\n                            <div class=\"text-right text-[14px] flex justify-end items-center space-x-2  \">\n                            \n                                <div v-if=\"exSuno.status=='error'\" class=\"text-[8px] flex items-center border-[1px] border-red-500/80 px-1 list-none rounded-md \">失败</div>\n                                <template v-if=\"exSuno.metadata && exSuno.metadata.duration\">\n                                    <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" > {{exSuno.metadata.duration.toFixed(1)}}s</div>\n                                </template>\n                                <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"exSuno.major_model_version\"> {{exSuno.major_model_version}}</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </template>\n        </n-tab-pane>\n    </n-tabs>\n\n    <div class=\"pt-4\">\n        <div class=\"flex justify-between items-start\">\n            <div class=\" space-x-1\">\n                  <NTag v-if=\"st.type=='custom'\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"generateLyrics()\" >{{ $t('suno.generately') }}</span></NTag>\n                  <!-- <NTag v-if=\"st.type=='custom'\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"generateLyrics()\" >上传音频</span></NTag> -->\n                  <mcUploaderMp3 v-if=\"st.type=='custom'\"/>\n            </div>\n            <NButton type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\"><SvgIcon icon=\"ri:music-fill\"  /> {{$t('suno.generate')}}</NButton> \n        </div>\n        \n       \n    </div>\n    <div v-if=\"st.type=='custom'\" class=\"pt-4 text-[12px]\" v-html=\"t('suno.info')\"> </div>\n\n</div>\n\n</template>"
  },
  {
    "path": "src/views/suno/mcList.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { SvgIcon } from '@/components/common';\n//import {   FeedTask} from '@/api/suno';\nimport {   sunoStore, SunoMedia} from '@/api/sunoStore';  \n\nimport playui from './playui.vue';\nimport { homeStore } from '@/store';\nimport { mlog } from '@/api';\nimport {NEmpty, NImage ,useMessage,NPopconfirm} from \"naive-ui\"\nimport { FeedTask } from '@/api/suno';\nimport { t } from '@/locales';\n\nconst list= ref<SunoMedia[]>([]);\nconst csuno= new sunoStore()\nconst st= ref({playid:''});\n\nconst ms = useMessage();\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\n\nconst getNowCls=(v:any)=>{\n    if(v.id==st.value.playid ){\n        return ['bg-gray-200','dark:bg-black']\n    }\n    return [];\n}\nconst goPlay=(v:SunoMedia)=>{\n    if(v.status=='error'){\n        ms.info( t('mj.ud_fail'))\n        return ;\n    }\n    st.value.playid=v.id\n    homeStore.setMyData({act:'goPlay',actData:v})\n    \n    if(v.status!='complete'){\n        FeedTask([v.id ])\n    }\n}\n\nconst extend=(v:SunoMedia)=>{\n    mlog(\"extend\", extend )\n    //homeStore.myData.actData\n    homeStore.setMyData({act:\"suno.extend\", actData: v  })\n}\n\nconst sp= ref({v:10, max:0 ,status:'',idDrop:false });\n \nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='FeedTask'){\n         initLoad()\n     }\n     if(n=='playEned'){\n        //\n        let  i= list.value.findIndex((v)=>v.id==st.value.playid)\n        i++;\n        mlog('playEned,',i, list.value.length )\n        if(i<list.value.length) setTimeout(()=>goPlay(list.value[i]),1000)  \n     }\n});\n\nconst getExSuno=(id:string)=>{\n    id= id.replace(\"m_\",'');\n    let index= list.value.findIndex(v=>v.id==id);\n     \n    if (index<0){\n      return null ;\n    }\n    return list.value[index];\n}\nconst update = (v:any )=>{\n     sp.value=v\n      \n}\nconst deleteGo=(v:SunoMedia)=>{\n    mlog('deleteGo', v)\n   \n    if(csuno.delete(v)) {\n        ms.success( t('common.deleteSuccess'))\n        initLoad();\n    }\n\n}\ninitLoad();\n</script>\n<template>\n<div v-if=\"list.length>0\">\n    <div  v-for=\"item in list\" :class=\"getNowCls( item )\" class=\"flex relative  justify-between items-start p-2 hover:dark:bg-black hover:bg-gray-200 border-b-[1px] border-gray-500/10 \">\n        \n        <playui @update=\"update\" v-if=\"st.playid==item.id\"  class=\"absolute top-[-4px] left-0 w-full  z-10\" ></playui>\n        <div class=\"w-[60px] h-[60px] relative  cursor-pointer\"  @click=\"goPlay( item )\">\n            \n           <template v-if=\"item.status=='complete'\">\n                <n-image  lazy  width=\"100\"  :src=\"item.image_url\" preview-disabled  >\n                    <template #placeholder>\n                        <div class=\"w-full h-full justify-center items-center flex\"  >\n                        <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                        </div>\n                    </template>\n                </n-image>\n                <div class=\"absolute top-0 right-0 w-full h-full flex justify-center items-center\" v-if=\"st.playid==item.id\">\n                    <SvgIcon icon=\"mdi:pause-circle-outline\" class=\"text-[40px] text-[#fff]\" v-if=\"sp.status=='pause'\"></SvgIcon>\n                    <SvgIcon icon=\"svg-spinners:bars-scale-middle\" class=\"text-[40px] text-[#fff]\" v-else></SvgIcon>\n                </div>\n            </template>\n            <template v-else>\n                <n-image  lazy  width=\"100\"  :src=\"item.image_url\" preview-disabled  />\n                <div class=\"absolute top-0 right-0  w-full h-full justify-center items-center flex\"  >\n                    <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                </div>\n            </template>\n             \n\n            \n        </div> \n        <div class=\"flex-1  pl-2\"> \n            <div class=\"flex justify-between line-clamp-1 w-full cursor-pointer\"  @click=\"goPlay( item )\">\n                <div class=\"flex justify-start items-center\"> \n                    <h3 >{{item.title}}</h3>\n                    <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 ml-1 list-none rounded-md\" v-if=\"item.metadata?.type=='upload'\" >Uploaded</div>\n                </div>\n                <div class=\"opacity-80 line-clamp-1 max-w-[320px]\"   >{{item.metadata.tags}}</div>\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-if=\"item.metadata && item.metadata.prompt\">\n             {{item.metadata.prompt}}\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-else>\n             {{$t('suno.noly')}}\n              </div>\n            <div class=\"text-right text-[14px] flex justify-end items-center space-x-2  \">\n                <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.metadata?.audio_prompt_id\">\n                    {{ $t('suno.extendFrom') }}:{{ getExSuno(item.metadata?.audio_prompt_id)?.title }}\n                </div>\n                <div v-if=\"item.status=='error'\" class=\"text-[8px] flex items-center border-[1px] border-red-500/80 px-1 list-none rounded-md \">{{ $t('suno.fail') }}</div>\n                <template v-if=\"item.metadata && item.metadata.duration\">\n                    <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" > {{item.metadata.duration.toFixed(1)}}s</div>\n                    <div @click=\"extend(item)\" class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md cursor-pointer\">{{ $t('suno.extend') }}</div>\n                </template>\n                <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.major_model_version\"> {{item.major_model_version}}</div>\n                <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                    <template #trigger><SvgIcon icon=\"mdi:delete\" class=\"cursor-pointer\"   /></template>\n                     {{ $t('mj.confirmDelete') }}\n                </n-popconfirm>\n                <SvgIcon icon=\"mdi:play-circle-outline\" class=\"cursor-pointer\"  @click=\"goPlay( item )\" />\n                <a :href=\"item.audio_url\" download  target=\"_blank\"><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a>\n            </div>\n           \n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('suno.nodata')\"></NEmpty>\n</div>\n\n</template>\n"
  },
  {
    "path": "src/views/suno/mcUploadMp3.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from \"@/api\";\nimport { FeedTask, sleep, sunoFetch } from \"@/api/suno\";\nimport {NTag} from   \"naive-ui\";\nimport { ref } from \"vue\";\n\nconst fsRef= ref()\nconst st = ref({process:'',id:'',isUpload:false});\n\nconst  uploadFetch= async ( lid:string)=>{\n    for(let i=0;i<50;i++){\n        let dt:any = await sunoFetch(`/uploads/audio/${lid}`);\n        mlog(\"ddd\",dt )\n        let time= (i+1)\n        if(time>20) time=20;\n        if( dt.status=='complete' || dt.status=='error' ) return dt ;\n        await sleep( time*1000 )\n        \n    }\n    return null;\n   \n}\nasync function  selectFile(input:any){\n    try{\n        st.value.isUpload= true\n        mlog(\"uploadFile\", input.target.files[0] )\n        let fileName = input.target.files[0].name\n        let extension = fileName.split('.').pop();\n \n        const d:any = await sunoFetch('/uploads/audio',{\"extension\": extension?extension:\"mp3\"})\n        mlog(\"init \", d )\n        st.value.id= d.id;\n        const formData = new FormData();\n        for(let p in d.fields){\n            formData.append( p,d.fields[p] )\n        }\n        formData.append('file', input.target.files[0])\n        const response = await fetch(d.url , { method: 'POST',   body: formData });\n        if (!response.ok) {\n        throw new Error('Network response was not ok');\n        }\n        mlog(\"uploaded \")\n        const f:any = await sunoFetch('/uploads/audio/'+ d.id+'/upload-finish',{\"upload_type\":\"file_upload\",\"upload_filename\": input.target.files[0].name })\n        mlog(\"finish \", f )\n\n        const fd:any= await uploadFetch(d.id )\n        mlog(\"uploadFetch \", fd  )\n        const ft:any = await sunoFetch('/uploads/audio/'+ d.id+'/initialize-clip',{ })\n        mlog(\"clip \", ft )\n\n        //到这里拿到 就可以结束了\n        FeedTask( [ ft.clip_id])\n    }catch(e ){\n\n    }\n    st.value.isUpload= false\n    fsRef.value.value='';\n\n}\n</script>\n<template>\n    <NTag   type=\"success\" size=\"small\" round  >\n        <span class=\"cursor-pointer\"   v-if=\"st.isUpload\">Upload...</span>\n        <span class=\"cursor-pointer\" @click=\"fsRef.click()\" v-else>{{ $t('suno.upMps') }}</span>\n    </NTag>\n    \n    <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\".mp3,audio/*,.m4a,.mp4\" />\n\n</template>"
  },
  {
    "path": "src/views/suno/mcplayer.vue",
    "content": "<script setup lang=\"ts\">\nimport {watch,ref  } from 'vue'\nimport {SunoMedia} from '@/api/sunoStore';\nimport { homeStore } from '@/store';\nimport { NImage,NEmpty } from 'naive-ui';\nimport {SvgIcon} from '@/components/common'\nimport { udioTask } from '@/api/udioStore';\nimport { riffTask } from '@/api/riffStore';\n\n//const pObj= ref<SunoMedia>()\nconst pObj= ref({image_large_url:'',title:'',tags:'',prompt:'' })\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='goPlay'){\n        let data = homeStore.myData.actData \n        const a = data as SunoMedia\n        pObj.value.image_large_url= a.image_large_url\n        pObj.value.tags= a.metadata.tags??''\n        pObj.value.prompt= a.metadata.prompt??''\n        pObj.value.title= a.title\n        \n    } \n    if( n==\"goPlayUdio\"){\n         let data = homeStore.myData.actData\n        //mlog('goPlayUdio' , data );\n        let a = data as udioTask\n        pObj.value.image_large_url= a.image_path\n        pObj.value.tags= a.tags?a.tags.join(','):''\n        pObj.value.prompt= a.lyrics || a.prompt\n        pObj.value.title= a.title\n    }\n    if(n=='goPlayRiff'){\n      let data = homeStore.myData.actData\n        //mlog('goPlayUdio' , data );\n        let a = data as riffTask\n        if(!a.riff) return\n        pObj.value.image_large_url= a.riff.image_url??''\n        pObj.value.tags= a.riff.sound??''\n        pObj.value.prompt= a.riff.lyrics??''\n        pObj.value.title= a.riff.title??'No title'\n    }\n})\n</script>\n<template>\n<div v-if=\"pObj.title||pObj.image_large_url\">\n    <div class=\"w-full  relative h-[300px]\">\n        <NImage :src=\"pObj.image_large_url\" class=\"w-full h-full\">\n             <template #placeholder>\n                      <div class=\"w-full h-full justify-center items-center flex\"  >\n                       <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[60px] text-green-300\"   ></SvgIcon>\n                      </div>\n                </template>\n        </NImage>\n        <div class=\"absolute bottom-0 right-0 p-2 text-white text-right\"> \n            <h2 class=\" text-xl\">{{ pObj.title }}</h2>\n            <div class=\"\">{{$t('suno.style')}}：{{ pObj.tags }}</div>\n        </div>\n    </div>\n   \n    <pre class=\" whitespace-pre-wrap p-2\">{{ pObj.prompt }}</pre>\n</div>\n<div class=\" flex w-full h-full justify-center items-center\" v-else >\n    <n-empty :description=\"$t('suno.emputy')\" ></n-empty>\n</div>\n\n</template>"
  },
  {
    "path": "src/views/suno/music.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport McInput from './mcInput.vue';\nimport mcList from './mcList.vue';\nimport mcplayer from './mcplayer.vue';\nimport { NTabs,NTabPane} from \"naive-ui\"\n\nimport RiffInput from './riffInput.vue';\nimport RiffList from './riffList.vue';\nimport udioInput from './udioInput.vue';\nimport udioList from './udioList.vue';\nimport { gptServerStore } from '@/store';\nimport { useRoute } from 'vue-router'; \n\nconst route = useRoute(); // 获取当前路由对象\nconst st= ref({menu:'suno',tab:''});\n\nconst handleUpdateValue=(v:string)=>{\n   //mlog(\"handleUpdateValue\",v)\n   gptServerStore.setMyData({TAB_MUSIC:v})\n}\n\nconst initLoad=()=>{\n    if(route.query.tab){ \n        st.value.tab= 'suno' \n        let tt= (route.query.tab as string).toLocaleLowerCase();\n        if( ['suno','udio','riff'].indexOf(tt)>-1 ){\n           st.value.tab=tt;\n        }\n\n        handleUpdateValue(  st.value.tab )\n    }\n    else st.value.tab=( gptServerStore.myData.TAB_MUSIC?gptServerStore.myData.TAB_MUSIC:'suno')\n}\ninitLoad();\n\n</script>\n\n<template>\n\n<div class=\"flex w-full h-full   \">\n    <div class=\"w-[300px] h-full  overflow-y-auto \">\n        <n-tabs type=\"line\" animated     :default-value=\"gptServerStore.myData.TAB_MUSIC??'suno'\"  @update:value=\"handleUpdateValue\"   >\n         <n-tab-pane name=\"start\" tab=\"\"> \n            <McInput /> \n         </n-tab-pane>\n\n         <n-tab-pane name=\"suno\" tab=\"Suno\"> \n            <McInput /> \n         </n-tab-pane>\n         <n-tab-pane name=\"riff\" tab=\"Riffusion\"> \n            <RiffInput/>\n         </n-tab-pane>\n         <n-tab-pane name=\"udio\" tab=\"Udio\"> \n            <udioInput/>\n         </n-tab-pane>\n           \n        </n-tabs>\n    </div>\n    <div class=\" flex-1  h-full bg-[#fafbfc] pt-2 dark:bg-[#18181c] overflow-y-auto \" >\n        <udioList  v-if=\"gptServerStore.myData.TAB_MUSIC=='udio'\"/>\n        <RiffList  v-else-if=\"gptServerStore.myData.TAB_MUSIC=='riff'\" />\n        <mcList  v-else />\n       \n    </div>\n    <div class=\"w-[300px]  h-full overflow-y-auto \">\n        <mcplayer/>\n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/suno/player.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api';\nimport { riffTask } from '@/api/riffStore';\nimport { SunoMedia } from '@/api/sunoStore';\nimport { udioTask } from '@/api/udioStore';\nimport { homeStore } from '@/store';\nimport { watch,ref  } from 'vue';\n\nconst st= ref({isLoad:0, url:''});\nconst pObj= ref({audio_url:''})\nconst player = new window.Audio(); \nconst loadPay=()=>{\n    if(  !pObj.value ) return \n    mlog('pObj', pObj.value.audio_url )\n    player.src = pObj.value.audio_url;\n    player.addEventListener('ended', () => {\n        st.value.isLoad=0;\n        homeStore.setMyData({act:'playEned',actData:{a:'ended'}})\n        mlog('ended')\n    });\n    player.addEventListener('play', () => {\n        mlog('play')\n        st.value.isLoad=1;\n        homeStore.setMyData({act:'playStatus',actData:{a:'play',d:{ currentTime: player.currentTime, duration: player.duration }}})\n    }) \n    player.addEventListener('pause', function() {\n         st.value.isLoad=2;\n          mlog('pause')\n         homeStore.setMyData({act:'playStatus',actData:{a:'pause'}})\n    });\n    player.addEventListener('timeupdate', function(e) {\n        // 音频播放位置变化时的操作\n        //mlog('timeupdate'  ,player.currentTime ,player.duration );\n        let a= 'timeupdate';\n        if(player.currentTime==player.duration){\n            st.value.isLoad=2;\n            a='pause'\n        }\n        homeStore.setMyData({act2:'playStatus' ,actData:{a ,d:{ currentTime: player.currentTime, duration: player.duration }}})\n    });\n    player.load();\n    player.play();\n    \n}\n\nconst goPlay=()=>{\n    if(player.src!=pObj.value?.audio_url){\n        if(st.value.isLoad==1 ) player.pause();\n        loadPay()\n    }else{\n        mlog('goPlay',  st.value.isLoad );\n         if(st.value.isLoad==1 ) player.pause();\n         else player.play();\n    }\n}\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='goPlay'){\n        let data = homeStore.myData.actData\n        mlog('goPlay' , data );\n        let abc = data as SunoMedia\n        pObj.value.audio_url=abc.audio_url\n        goPlay();\n\n    }\n    if( n==\"goPlayUdio\"){\n         let data = homeStore.myData.actData\n        mlog('goPlayUdio' , data );\n        let abc = data as udioTask\n        pObj.value.audio_url=abc.song_path\n        goPlay();\n    }\n    if( n==\"goPlayRiff\"){\n         let data = homeStore.myData.actData\n        mlog('goPlayUdio' , data );\n        let abc = data as riffTask\n        if(!abc.riff?.audio_url){\n            //ms.info(t('mj.ud_doing'))\n            return\n        }\n        pObj.value.audio_url=abc.riff?.audio_url??''\n        goPlay();\n    }\n    if(n=='playUpdate'){\n         let data:any  = homeStore.myData.actData\n         mlog('playUpdate' , data );\n         if( data ) player.currentTime = data.v as number\n         //player.set\n    }\n})\n</script>\n<template>\n</template>"
  },
  {
    "path": "src/views/suno/playui.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api';\nimport { homeStore } from '@/store';\nimport { ref ,watch} from 'vue'\nimport { NSlider } from 'naive-ui';\nconst sp= ref({v:10, max:0 ,status:'',idDrop:false });\nconst updatev=(v:number)=>{\n    homeStore.setMyData({act:'playUpdate',actData:{ v}})\n}\n\nconst $emit= defineEmits(['update'] );\n \n\nwatch(()=>homeStore.myData.act2, (n)=>{\n    if(n=='playStatus'){\n        if( sp.value.idDrop ) return\n       let data:any = homeStore.myData.actData\n        mlog('playStatus' , data );\n        if(data && data.d && data.d.duration  ){\n            sp.value.max = data.d.duration\n            sp.value.v = data.d.currentTime ;// parseInt( data.d.currentTime ) \n           \n        }\n        if( data )   sp.value.status = data.a \n        $emit('update', sp.value)\n       \n\n    }\n})\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='playStatus'){\n         let data:any = homeStore.myData.actData\n         if(data)   sp.value.status = data.a \n          $emit('update', sp.value)\n     }\n});\n\n</script>\n<template>\n<div class=\"sss\"    style=\"--n-rail-height:2px\">\n<n-slider :on-dragend=\"()=>sp.idDrop=false\" :on-dragstart=\"()=>sp.idDrop=true\" \n            class=\"w-full\" v-model:value=\"sp.v\" :step=\"1\" v-if=\"sp.max\" :max=\"sp.max\" \n            :on-update:value=\"updatev\"\n            :format-tooltip=\"(v)=>v.toFixed(1)+'s'\" />\n</div>\n</template>\n<style>\n.sss .n-slider .n-slider-rail{\n    height: 2px!important;\n}\n.sss .n-slider-handle{\nheight: 12px!important;\nwidth: 12px!important;\n }\n</style>"
  },
  {
    "path": "src/views/suno/riffInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref,computed, onMounted } from 'vue';\nimport { NTabs ,NTabPane ,NInput,NSwitch ,NTooltip, NTag ,NButton, useMessage,NSelect, NImage, NSlider} from \"naive-ui\";\nimport { SvgIcon } from '@/components/common';\nimport { riffFetch , riffFeed} from '@/api/riff';\nimport {randStyle} from '@/api/suno';\nimport { mlog } from '@/api';\nimport { homeStore } from '@/store';\n\nconst st = ref({type:'custom',isLoading:false})\n\nconst cs= ref({  \"model\": \"FUZZ-1.1 Pro\",  \"lyrics\": \"\",  \"tag\": \"\", \"title\":\"\",instrumental:false  });\n\nconst des= ref({ \"model\":\"FUZZ-1.1 Pro\",  \"topic\":\"\",   \"instrumental\":false});\nconst mvOption= [\n{label: 'verion: v1.1 Pro',value: 'FUZZ-1.1 Pro'}\n,{label:'verion: v1.1',value: 'FUZZ-1.1'}\n,{label:'verion: v1 Pro',value: 'FUZZ-1.0 Pro'}\n,{label:'verion: v1',value: 'FUZZ-1.0'}\n ]\n\nconst canPost = computed(() => {\n   // return true; \n    if( st.value.isLoading ) return false;\n    if( st.value.type=='custom'){\n        return cs.value.tag && cs.value.title\n    }\n    if( st.value.type=='description' ){\n       // mlog('des: ', des.value.gpt_description_prompt , des.value.make_instrumental )\n       return des.value.topic \n        \n    }\n    return true\n})\n const generate= async()=>{\n    let r:any\n    st.value.isLoading =true;\n    try {\n        if(st.value.type=='custom'){ \n            r= await riffFetch(  '/generate' ,  cs.value )  \n        }else{\n            r= await riffFetch(  '/generate/topic' ,  des.value ) \n        }\n    } catch (error) {\n        \n    }\n    st.value.isLoading =false;\n    mlog('r:',r)\n    if( r.jobs && r.jobs.length>0){\n        let ids='';\n        for(let o of r.jobs){\n            if(ids!='') ids+=',';\n            ids+=o.id\n        }\n        //mlog('ids:',ids)\n        riffFeed(ids )\n    }\n    //\n }\n const ms = useMessage();\n onMounted(() => {\n     //riffFeed('678d5ca5-331f-41df-a6a9-67c7bc567552,3dda982e-7cf6-4268-ae22-e7f86ed7a944')\n      homeStore.setMyData({ms:ms})\n })\n</script>\n<template>\n<div class=\"p-2\"> \n    <n-tabs type=\"segment\" animated  v-model:value=\"st.type\">\n        <n-tab-pane name=\"description\" :tab=\"$t('suno.description')\">\n             \n            <div  class=\"pt-4 flex justify-between\">\n                <div>{{$t('suno.desc')}}:</div>\n                <div> \n                    <n-switch v-model:value=\"des.instrumental\" size=\"small\">\n                        <template #checked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                        <template #unchecked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                    </n-switch>\n                </div>\n            </div>\n            <div  class=\"pt-1\"> \n                <n-input v-model:value=\"des.topic\"  \n                :placeholder=\"$t('suno.descpls')\"  type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n            </div>\n            <div  class=\"pt-1\">\n                 <n-select v-model:value=\"cs.model\" :options=\"mvOption\" size=\"small\" />\n            </div>\n        </n-tab-pane>\n         <n-tab-pane name=\"custom\" :tab=\"$t('suno.custom')\">\n            <div class=\"pt-1\">\n                <n-input :placeholder=\"$t('suno.titlepls')\" v-model:value=\"cs.title\">\n                <template #prefix>\n                     <span>{{$t('suno.title')}}：</span>\n                </template>\n                </n-input>\n            </div>\n             <div class=\"pt-4\">\n                <n-input :placeholder=\"$t('suno.stylepls')\" v-model:value=\"cs.tag\">\n                    <template #prefix>\n                        <span>{{$t('suno.style')}}：</span>\n                    </template>\n                    <template #suffix>\n                        <n-tooltip placement=\"right\" trigger=\"hover\">\n                            <template #trigger>\n                                <div class=\"cursor-pointer\" @click=\"cs.tag= randStyle()\"><SvgIcon  icon=\"fa:random\" class=\"w-4 h-4\" /></div>\n                            </template>\n                            <div>{{$t('suno.rank')}}</div>\n                            \n                        </n-tooltip>\n                    </template>\n                </n-input>\n            </div>\n\n            <div  class=\"pt-4 flex justify-between\">\n                <div>{{$t('suno.ly')}} :</div>\n                <div> \n                    <n-switch v-model:value=\"cs.instrumental\" size=\"small\">\n                        <template #checked>\n                        {{ $t('suno.noneedly') }}\n                        </template>\n                        <template #unchecked>\n                         {{ $t('suno.noneedly') }}\n                        </template>\n                    </n-switch>\n                </div>\n            </div>\n            <div  class=\"pt-1\"> \n                <n-input v-model:value=\"cs.lyrics\" :disabled=\"cs.instrumental\"\n                :placeholder=\"$t('suno.lypls')\" type=\"textarea\"  size=\"small\"   \n                :autosize=\"{ minRows: 3, maxRows: 12  }\"  />\n            </div>\n            <div  class=\"pt-1\">\n                 <n-select v-model:value=\"cs.model\" :options=\"mvOption\" size=\"small\" />\n            </div>\n         </n-tab-pane>\n    </n-tabs>\n      <div class=\"pt-4\">\n        <div class=\"flex justify-between items-start\">\n            <div class=\" space-x-1\">\n                  <!-- <NTag v-if=\"st.type=='custom'\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"generateLyrics()\" >{{ $t('suno.generately') }}</span></NTag> -->\n                  <!-- <NTag v-if=\"st.type=='custom'\" type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"generateLyrics()\" >上传音频</span></NTag> -->\n                  <!-- <mcUploaderMp3 v-if=\"st.type=='custom'\"/> -->\n            </div>\n            <NButton type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\"><SvgIcon icon=\"ri:music-fill\"  /> {{$t('suno.generate')}}</NButton> \n        </div>\n        \n       \n    </div>\n</div>\n</template>"
  },
  {
    "path": "src/views/suno/riffList.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { SvgIcon } from '@/components/common';\nimport { riffStore, riffTask } from '@/api/riffStore';\nimport {NEmpty, NImage ,useMessage,NPopconfirm} from \"naive-ui\"\nimport { t } from '@/locales';\nimport { riffFeed } from '@/api/riff';\nimport { homeStore } from '@/store';\nimport { mlog } from '@/api';\nimport playui from './playui.vue';\n\nconst list= ref<riffTask[]>([]);\n\nconst csuno= new riffStore()\nconst st= ref({playid:''});\nconst sp= ref({v:10, max:0 ,status:'',idDrop:false });\n\nconst ms = useMessage();\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\nconst getNowCls=(v:riffTask)=>{\n    if(v.id==st.value.playid ){\n        return ['bg-gray-200','dark:bg-black']\n    }\n    return [];\n}\n\nconst goPlay=(v:riffTask)=>{\n    if(v.status=='ERROR'){\n        ms.info(t('mj.ud_fail'))\n        return ;\n    }\n    //mlog('TK ',v.status ,  v.taskId )\n    if(v.status!='success'){\n         riffFeed( v.id )\n         return\n    }\n    if(!v.riff?.audio_url ){\n        ms.info(t('mj.ud_doing'))\n        return ;\n    }\n    st.value.playid=v.id\n    homeStore.setMyData({act:'goPlayRiff',actData:v})\n    \n}\nconst update = (v:any )=>{\n     sp.value=v \n}\nconst deleteGo=(v:string)=>{\n    mlog('deleteGo', v)\n    if(csuno.delete(v)) {\n        ms.success( t('common.deleteSuccess'))\n        initLoad();\n    }\n\n}\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='RiffFeed'){\n         initLoad()\n     }\n     if(n=='playEned'){\n        let  i= list.value.findIndex((v)=>v.id==st.value.playid)\n        i++;\n        mlog('playEned,',i, list.value.length )\n        if(i<list.value.length) setTimeout(()=>goPlay(list.value[i]),1000)  \n     }\n});\n\ninitLoad();\n\n</script>\n<template>\n<div  v-if=\"list.length>0\">\n        <div  v-for=\"item in list\" :class=\"getNowCls( item )\" class=\"flex relative  justify-between items-start p-2 hover:dark:bg-black hover:bg-gray-200 border-b-[1px] border-gray-500/10 \">\n        <playui @update=\"update\" v-if=\"st.playid==item.id\"  class=\"absolute top-[-4px] left-0 w-full  z-10\" ></playui>\n        <div class=\"w-[60px] h-[60px] relative  cursor-pointer\"  @click=\"goPlay( item )\">\n           <template v-if=\"item.status=='success'\">\n                <n-image  lazy  width=\"100\"  :src=\"item.riff?.image_url\" preview-disabled  >\n                    <template #placeholder>\n                        <div class=\"w-full h-full justify-center items-center flex\"  >\n                        <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                        </div>\n                    </template>\n                </n-image>\n                <div class=\"absolute top-0 right-0 w-full h-full flex justify-center items-center\" v-if=\"st.playid==item.id\">\n                    <SvgIcon icon=\"mdi:pause-circle-outline\" class=\"text-[40px] text-[#fff]\" v-if=\"sp.status=='pause'\"></SvgIcon>\n                    <SvgIcon icon=\"svg-spinners:bars-scale-middle\" class=\"text-[40px] text-[#fff]\" v-else></SvgIcon>\n                </div>\n            </template>\n            <template v-else>\n                <n-image  lazy  width=\"100\"  :src=\"item.riff?.image_url\" preview-disabled  />\n                <div class=\"absolute top-0 right-0  w-full h-full justify-center items-center flex\"  >\n                    <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                </div>\n            </template>\n        </div> \n\n        <div class=\"flex-1  pl-2\"> \n            <div class=\"flex justify-between line-clamp-1 w-full cursor-pointer\"  @click=\"goPlay( item )\">\n                <div class=\"flex justify-start items-center\"> \n                    <h3 >{{item.riff?.title}}</h3>\n                    <!-- <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 ml-1 list-none rounded-md\" v-if=\"item.metadata?.type=='upload'\" >Uploaded</div> -->\n                </div>\n                <div class=\"opacity-80 line-clamp-1 max-w-[320px]\" v-if=\"item.riff?.sound\"  >{{  item.riff?.sound }}</div>\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-if=\"item.riff?.lyrics || item.riff?.topic\">\n             {{item.riff?.lyrics || item.riff?.topic}}\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-else>\n             {{$t('suno.noly')}}\n              </div>\n            <div class=\"text-right text-[14px] flex justify-end items-center space-x-2  \">\n                <!-- <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.audio_conditioning_type\">\n                   {{ item.audio_conditioning_type=='precede'?t('mj.ud_precede') : t('mj.ud_continuation')}}\n                </div> -->\n                <div v-if=\"item.status=='ERROR'\" class=\"text-[8px] flex items-center border-[1px] border-red-500/80 px-1 list-none rounded-md \">{{ $t('suno.fail') }}</div>\n                <template v-if=\"item.riff?.duration_s\">\n                    <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" > {{item.riff?.duration_s?.toFixed(1)}}s</div>\n                    <!-- <div @click=\"extend(item)\" class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md cursor-pointer\">{{ $t('suno.extend') }}</div> -->\n                </template>\n                <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.riff?.model_display_name\"> {{item.riff?.model_display_name}}</div>\n                <n-popconfirm @positive-click=\"()=>deleteGo(item.id )\" placement=\"bottom\">\n                    <template #trigger><SvgIcon icon=\"mdi:delete\" class=\"cursor-pointer\"   /></template>\n                     {{ $t('mj.confirmDelete') }}\n                </n-popconfirm>\n                <SvgIcon icon=\"mdi:play-circle-outline\" class=\"cursor-pointer\"  @click=\"goPlay( item )\" />\n                <a :href=\"item.riff?.audio_url\" download  target=\"_blank\"><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a>\n            </div>\n           \n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('suno.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/suno/udioInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { NTabs ,NTabPane,NButtonGroup,NRadioButton,NRadioGroup ,NInput,NSwitch ,NTooltip, NTag ,NButton, useMessage,NSelect, NImage, NSlider} from \"naive-ui\";\nimport { t } from '@/locales';\nimport { udioFeedTask, udioFetch } from '@/api/udio';\nimport { mlog } from '@/api';\nimport { SvgIcon } from '@/components/common';\nimport { homeStore } from '@/store';\nimport { udioTask } from '@/api/udioStore';\n\n\n\nconst f= ref({lyrics_type:'generate',prompt:'',lyrice:'',model:'udio32-v1.5',continue_clip_id:'',continue_at:0,mode:'continuation' })\nconst st = ref({loading:false});\nconst exSuno= ref<udioTask>()\n\nconst lyriceConfig=[\n{key:'user',value: t('mj.ud_ly_write')},\n{key:'generate',value:t('mj.ud_ly_auto') },\n{key:'instrumental',value:t('mj.ud_ly_null')},\n\n// {key:'user',value:'Write Lyrics'},\n// {key:'generate',value:'Auto'},\n// {key:'instrumental',value:'Instrumental'},\n]\n\nconst modelConfig=[\n{label: 'Model: udio-32 '+t('mj.ud_v32'),value: 'udio32-v1.5'}\n,{label:'Model: udio-130 '+t('mj.ud_v130'),value: 'udio130-v1.5'}\n];\nconst modeConfig=[\n{label:  t('mj.ud_precede'),value: 'precede'}\n,{label: t('mj.ud_continuation'),value: 'continuation'}\n];\n\nconst input= {\n  \"gen_params\": {\n    \"prompt\": \"\",\n    \"lyrics\": \"\",\n    \"lyrics_type\": \"generate\",\n    \"bypass_prompt_optimization\": false,\n    \"seed\": -1,\n    \"song_section_start\": 0.4,\n    \"prompt_strength\": 0.5,\n    \"clarity_strength\": 0.25,\n    \"lyrics_strength\": 0.5,\n    \"generation_quality\": 0.75,\n    \"negative_prompt\": \"\",\n    \"model_type\": \"\",\n    \"config\": {\n      \"mode\": \"regular\"\n    }\n  }\n}\n\nconst generate=async ()=>{\n    st.value.loading= true\n    let data= {...input}\n    data.gen_params.prompt=f.value.prompt\n    data.gen_params.model_type=f.value.model\n    data.gen_params.lyrics_type=f.value.lyrics_type\n    if(f.value.lyrics_type=='user'){\n        data.gen_params.lyrics= f.value.lyrice \n    }\n    if(f.value.continue_clip_id){\n        data.gen_params.song_section_start= f.value.continue_at\n        data.gen_params.config= {\n            \"mode\": f.value.mode,\n            \"context_length\": 130,\n            \"source\": {\n                \"source_type\": \"song\",\n                \"song_id\": f.value.continue_clip_id\n            }\n        }\n    }\n    try {\n        const d = await udioFetch('/udio/submit/music',data );\n        mlog('generate', d )\n        if( d.data ){\n            udioFeedTask( d.data )\n        }\n    } catch (error) {\n        \n    } \n    st.value.loading= false\n}\n\nconst canPost= computed(()=>f.value.prompt!=''  ) \n\nwatch(()=>homeStore.myData.act, (n)=>{\n    if(n=='udio.extend'){\n        mlog(\"udio.extend\", homeStore.myData.actData )\n        const s= homeStore.myData.actData as udioTask\n        exSuno.value= s \n        f.value.continue_clip_id= s.id\n        f.value.continue_at= 0.4 \n    }\n});\nconst ms = useMessage();\nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n});\n</script>\n\n<template>\n<div class=\"p-1\">\n    <div  >\n        <!-- <n-input :placeholder=\"$t('mj.ud_prompt_pls')\" v-model:value=\"f.prompt\">\n        <template #prefix>\n                <span>{{$t('mj.ud_prompt')}}：</span>\n        </template>\n        </n-input> -->\n         <n-input v-model:value=\"f.prompt\"  \n        :placeholder=\"$t('mj.ud_prompt_pls')\" type=\"textarea\"  size=\"small\"   \n        :autosize=\"{ minRows: 3, maxRows: 12  }\"  /> \n    </div>\n    <div class=\"pt-4\">\n        <n-radio-group v-model:value=\"f.lyrics_type\" name=\"radiobuttongroup1\" size=\"small\">\n        <n-radio-button   v-for=\"song in lyriceConfig\"  :key=\"song.key\" :value=\"song.key\" :label=\"song.value\">\n        </n-radio-button>  \n        </n-radio-group>\n    </div>\n    <div class=\"pt-1\" v-if=\"f.lyrics_type=='user'\">\n        <n-input v-model:value=\"f.lyrice\"  \n        :placeholder=\"$t('suno.lypls')\" type=\"textarea\"  size=\"small\"   \n        :autosize=\"{ minRows: 5, maxRows: 12  }\"  /> \n    </div>\n\n     \n    <div  class=\"pt-4\">\n        <n-select v-model:value=\"f.model\" :options=\"modelConfig\" size=\"small\" />\n    </div>\n\n    <div  class=\"pt-4\">\n        <div class=\"flex justify-end items-start\">\n            <NButton v-bind:loading=\"st.loading\" type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\"><SvgIcon icon=\"ri:music-fill\"  /> {{$t('suno.generate')}}</NButton> \n        </div>\n    </div>\n\n    <template v-if=\"f.continue_clip_id && exSuno\">\n        <div  class=\"pt-5\">\n            <div class=\"flex justify-between pb-3\">\n                <div class=\"text-[12px]\"> {{ $t('suno.extendAt') }} {{ f.continue_at*100 }}%</div>\n                <NTag  type=\"success\" size=\"small\" round  ><span class=\"cursor-pointer\" @click=\"f.continue_clip_id=''\" >清除</span></NTag>\n\n            </div>\n            <n-slider v-model:value=\"f.continue_at\" :step=\"0.01\" :max=\"1\">\n                <template #thumb>\n                    <div class=\"bg-[--n-fill-color] text-[9px]  border-[0px]  px-1 list-none rounded-md\">{{ f.continue_at }}</div>\n                </template>\n            </n-slider>\n        </div>\n         <div  class=\"pt-1 flex justify-end\">\n             <n-radio-group v-model:value=\"f.mode\" name=\"radiobuttongroup1\" size=\"small\">\n                <n-radio-button   v-for=\"song in modeConfig\"  :key=\"song.value\" :value=\"song.value\" :label=\"song.label\">\n                </n-radio-button>  \n                </n-radio-group>\n        </div>\n        <div  class=\"pt-1\"  >\n            <div class=\"flex relative  justify-between items-start p-2 hover:dark:bg-black hover:bg-gray-200 border-b-[1px] border-gray-500/10 \">\n                <div class=\"w-[60px] h-[60px] relative  cursor-pointer\" >\n                    <n-image  lazy  width=\"100\"  :src=\"exSuno.image_path\" preview-disabled  >\n                        <template #placeholder>\n                            <div class=\"w-full h-full justify-center items-center flex\"  >\n                            <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                            </div>\n                        </template>\n                    </n-image>\n                </div>\n                <div class=\"flex-1  pl-2\"> \n                    <div class=\"flex justify-between line-clamp-1 w-full cursor-pointer\"  >\n                        <h3>{{exSuno.title}}</h3>\n                        <!-- <div class=\"opacity-80\"  >{{exSuno.metadata.tags}}</div> -->\n                    </div>\n                    <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"   v-if=\"exSuno.lyrics ||exSuno.prompt\">\n                    {{exSuno.lyrics ||exSuno.prompt}}\n                    </div>\n                    <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  v-else>\n                    {{$t('suno.noly')}}\n                    </div>\n                    <div class=\"text-right text-[14px] flex justify-end items-center space-x-2  \">\n                    \n                         \n                        <template v-if=\" exSuno.duration\">\n                            <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" > {{exSuno.duration.toFixed(1)}}s</div>\n                        </template>\n                        <!-- <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"exSuno.major_model_version\"> {{exSuno.major_model_version}}</div> -->\n                    </div>\n                </div>\n            </div>\n        </div>\n       \n    </template>\n    \n    \n    <div v-html=\"t('mj.ud_info')\"  class=\"pt-4 px-2 text-[12px]\"></div>\n</div>\n</template>"
  },
  {
    "path": "src/views/suno/udioList.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport { SvgIcon } from '@/components/common';\nimport {   udioStore,udioTask} from '@/api/udioStore';  \nimport {NEmpty, NImage ,useMessage,NPopconfirm} from \"naive-ui\"\nimport { homeStore } from '@/store';\nimport { mlog } from '@/api';\nimport { t } from '@/locales';\nimport playui from './playui.vue';\nimport { udioFeedTask } from '@/api/udio';\n\nconst ms = useMessage();\n\nconst list= ref<udioTask[]>([]);\nconst csuno= new udioStore()\nconst st= ref({playid:''});\nconst sp= ref({v:10, max:0 ,status:'',idDrop:false });\n\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\nconst getNowCls=(v:udioTask)=>{\n    if(v.id==st.value.playid ){\n        return ['bg-gray-200','dark:bg-black']\n    }\n    return [];\n}\n\nconst goPlay=(v:udioTask)=>{\n    if(v.status=='ERROR'){\n        ms.info(t('mj.ud_fail'))\n        return ;\n    }\n    //mlog('TK ',v.status ,  v.taskId )\n    if(v.status!='SUCCESS'){\n       v.taskId  && udioFeedTask( v.taskId )\n    }\n    if(v.song_path==''){\n        ms.info(t('mj.ud_doing'))\n        return ;\n    }\n    st.value.playid=v.id\n    homeStore.setMyData({act:'goPlayUdio',actData:v})\n    \n    \n}\nconst update = (v:any )=>{\n     sp.value=v \n}\nconst deleteGo=(v:string)=>{\n    mlog('deleteGo', v)\n    if(csuno.delete(v)) {\n        ms.success( t('common.deleteSuccess'))\n        initLoad();\n    }\n\n}\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='udio.feed'){\n         initLoad()\n     }\n     if(n=='playEned'){\n        //\n        let  i= list.value.findIndex((v)=>v.id==st.value.playid)\n        i++;\n        mlog('playEned,',i, list.value.length )\n        if(i<list.value.length) setTimeout(()=>goPlay(list.value[i]),1000)  \n     }\n});\nconst extend=(v:udioTask)=>{\n    mlog(\"extend\", extend )\n    //homeStore.myData.actData\n    homeStore.setMyData({act:\"udio.extend\", actData: v  })\n}\ninitLoad();\n</script>\n<template>\n<div  v-if=\"list.length>0\">\n    <div  v-for=\"item in list\" :class=\"getNowCls( item )\" class=\"flex relative  justify-between items-start p-2 hover:dark:bg-black hover:bg-gray-200 border-b-[1px] border-gray-500/10 \">\n        <playui @update=\"update\" v-if=\"st.playid==item.id\"  class=\"absolute top-[-4px] left-0 w-full  z-10\" ></playui>\n        <div class=\"w-[60px] h-[60px] relative  cursor-pointer\"  @click=\"goPlay( item )\">\n           <template v-if=\"item.status=='SUCCESS'\">\n                <n-image  lazy  width=\"100\"  :src=\"item.image_path\" preview-disabled  >\n                    <template #placeholder>\n                        <div class=\"w-full h-full justify-center items-center flex\"  >\n                        <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                        </div>\n                    </template>\n                </n-image>\n                <div class=\"absolute top-0 right-0 w-full h-full flex justify-center items-center\" v-if=\"st.playid==item.id\">\n                    <SvgIcon icon=\"mdi:pause-circle-outline\" class=\"text-[40px] text-[#fff]\" v-if=\"sp.status=='pause'\"></SvgIcon>\n                    <SvgIcon icon=\"svg-spinners:bars-scale-middle\" class=\"text-[40px] text-[#fff]\" v-else></SvgIcon>\n                </div>\n            </template>\n            <template v-else>\n                <n-image  lazy  width=\"100\"  :src=\"item.image_path\" preview-disabled  />\n                <div class=\"absolute top-0 right-0  w-full h-full justify-center items-center flex\"  >\n                    <SvgIcon icon=\"line-md:downloading-loop\" class=\"text-[40px] text-green-300\"   ></SvgIcon>\n                </div>\n            </template>\n        </div> \n\n        <div class=\"flex-1  pl-2\"> \n            <div class=\"flex justify-between line-clamp-1 w-full cursor-pointer\"  @click=\"goPlay( item )\">\n                <div class=\"flex justify-start items-center\"> \n                    <h3 >{{item.title}}</h3>\n                    <!-- <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 ml-1 list-none rounded-md\" v-if=\"item.metadata?.type=='upload'\" >Uploaded</div> -->\n                </div>\n                <div class=\"opacity-80 line-clamp-1 max-w-[320px]\" v-if=\"item.tags\"  >{{ item.tags.join(', ') }}</div>\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-if=\"item.lyrics || item.prompt\">\n             {{item.lyrics ||item.prompt}}\n            </div>\n            <div class=\"opacity-60 line-clamp-1 w-full text-[12px] cursor-pointer\"  @click=\"goPlay( item )\" v-else>\n             {{$t('suno.noly')}}\n              </div>\n            <div class=\"text-right text-[14px] flex justify-end items-center space-x-2  \">\n                <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.audio_conditioning_type\">\n                   {{ item.audio_conditioning_type=='precede'?t('mj.ud_precede') : t('mj.ud_continuation')}}\n                </div>\n                <div v-if=\"item.status=='ERROR'\" class=\"text-[8px] flex items-center border-[1px] border-red-500/80 px-1 list-none rounded-md \">{{ $t('suno.fail') }}</div>\n                <template v-if=\"item.duration\">\n                    <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" > {{item.duration.toFixed(1)}}s</div>\n                    <div @click=\"extend(item)\" class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md cursor-pointer\">{{ $t('suno.extend') }}</div>\n                </template>\n                <!-- <div class=\"text-[8px] flex items-center border-[1px] border-gray-500/30 px-1 list-none rounded-md\" v-if=\"item.major_model_version\"> {{item.major_model_version}}</div> -->\n                <n-popconfirm @positive-click=\"()=>deleteGo(item.id )\" placement=\"bottom\">\n                    <template #trigger><SvgIcon icon=\"mdi:delete\" class=\"cursor-pointer\"   /></template>\n                     {{ $t('mj.confirmDelete') }}\n                </n-popconfirm>\n                <SvgIcon icon=\"mdi:play-circle-outline\" class=\"cursor-pointer\"  @click=\"goPlay( item )\" />\n                <a :href=\"item.song_path\" download  target=\"_blank\"><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a>\n            </div>\n           \n        </div>\n    </div>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('suno.nodata')\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/video/image-base64-array.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog, upImg } from '@/api';\nimport { t } from '@/locales';\nimport { useMessage,NImage } from 'naive-ui';\nimport { computed, onMounted, ref ,watch} from 'vue';\nimport { SvgIcon } from '@/components/common';\n \ninterface Props {\n  value: any\n  upload?: string\n  isOne?: boolean\n  isFile?: boolean\n}\nconst pp= defineProps<Props>()\n// const pp = defineProps({\n//   value: {\n//     type: Array||String,\n//     required: true,\n//     default:[]\n//   }\n//   ,upload:{\n//     type:String,\n//     default:''\n//   }\n//   ,isOne:{\n//     type:Boolean,\n//     default:false\n//   }\n// })\n\nconst emit = defineEmits(['update:value'])\n\nconst fsRef= ref() ; \nconst ms = useMessage();\ninterface myFile{\n    file?:any\n    base64:string\n}\nconst base64Array= ref<myFile[]>([]);   \nconst selectFile=(input:any)=>{\n    const ff=input.target.files[0];\n    upImg(input.target.files[0]).then(d=>{\n        fsRef.value.value='';\n        const index = base64Array.value.findIndex(item => item.base64 == d);\n        if(index>-1){\n            ms.error(t('mjchat.no2add') )\n            return ;\n        }\n        base64Array.value.push({file: ff ,base64:d});\n        changValue()\n        //if(base64Array.value.length>1) st.value.isGo=true;\n        //if(st)\n    }).catch(e=>ms.error(e));\n}\n\nconst changValue= ()=>{\n    \n    let arr:any=base64Array.value.map(item=>item.base64)\n    if(pp.isFile){\n        arr=base64Array.value//.map(item=>item.file)\n    }\n    emit('update:value', pp.isOne?arr[0]: arr)\n    //mlog(\"changValue\", arr)\n    \n}\n\n//watch(()=>base64Array.value, ,{deep:true})\n\nconst max= computed(()=>{\n    return pp.isOne?1:3;\n})\n\n\nconst updateBase64Array=()=>{\n    if(!pp.value){\n        return\n    }\n    base64Array.value=pp.isOne?[{base64: pp.value }]:(pp.value?pp.value.map((v:string)=>{return {base64:v}}):[]);\n}\nonMounted(()=>{\n   updateBase64Array();\n})\nwatch(()=>pp.value, ()=>{\n    if(pp.isFile) return ;\n    updateBase64Array();\n},{deep:true})\n\n</script>\n<template>\n<div class=\"flex justify-start items-center flex-wrap myblend\">\n    <div class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mr-2 mt-2 bg-[#ddd] overflow-hidden rounded-sm relative group \" v-for=\"item in base64Array\">\n        <NImage :src=\"item.base64\" object-fit=\"cover\"></NImage>\n        <SvgIcon icon=\"fluent:delete-12-filled\" :class=\"{'hidden':max>1}\"\n        class=\"absolute top-0 right-0 text-red-600 text-[20px] cursor-pointer  group-hover:block \"\n        @click=\"base64Array.splice(base64Array.indexOf(item),1)\"></SvgIcon>\n    </div>\n    <div   @click=\"fsRef.click()\" v-if=\"base64Array.length<max\" \n         class=\"w-[var(--my-blend-img-size)] h-[var(--my-blend-img-size)] mt-2 bg-[#999] overflow-hidden rounded-sm flex justify-center items-center cursor-pointer\">\n            <SvgIcon icon=\"mdi:add-bold\" class=\"text-[40px] text-[#fff]\"></SvgIcon>\n    </div>\n</div>\n<input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n\n</template>\n\n<style scoped>\n.myblend{\n    --my-blend-img-size:75px\n}\n</style>"
  },
  {
    "path": "src/views/video/input.vue",
    "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue';\nimport { NSelect, NInput,NButton ,useMessage,NEmpty} from 'naive-ui';\n//import mytpl from './tpl.json'\nimport { mytpl } from './tpl';\nimport { DtoTpl, PostVideo, googleVeoFeed } from './veo';\nimport imageBase64Array from './image-base64-array.vue';\nimport { SvgIcon } from '@/components/common';\nimport { t } from '@/locales';\nimport { mlog } from '@/api';\nimport { useRoute } from 'vue-router';\nconst route = useRoute(); // 获取当前路由对象\n\n//\"fal-ai/ltxv-13b-098-distilled/image-to-video\"\n//const st= ref({\"model\":\"veo3-fast-frames\",isLoading:false});\nconst st= ref({\"model\":\"sora-2\",isLoading:false});\nconst stArr= ref<any[]>([])\nconst modelsOption= ref<{label:string,value:string}[]>([])\nconst tplArr= ref<DtoTpl[]>([])\n\n// const modelsOption= computed(()=>{\n//     let arr=[{label:'Please select Model',value: ''}];\n//     for( let o of mytpl.tpl){\n//         arr.push({label: o.model,value: o.model})\n//     }\n//     return arr\n// })\n\nconst initStart= ()=>{\n    const abc=()=>{\n         let arr=[{label:'Please select Model',value: ''}];\n            for( let o of mytpl.tpl){\n                \n                arr.push({label: o.model,value: o.model})\n                \n               \n            }\n            return arr\n    }\n    modelsOption.value= abc()\n\n    const fun2=()=>{\n        let arr:DtoTpl[]=[];\n        for( let o of mytpl.tpl){\n            arr.push(o)\n        }\n        return arr\n    }\n    tplArr.value= fun2()\n\n\n\n}\ninitStart();\n \nconst nowTpl= computed(()=>{\n    //let arr:any[]=[];\n    mlog(\"nowTpl\",st.value.model)\n    stArr.value=[];\n    const mtpl= tplArr.value.find(v=> v.model==st.value.model)\n    \n    if(!mtpl) return [];\n    for( let o of mtpl.field){\n        stArr.value.push(o.value??'')\n    }\n    return mtpl.field \n})\n\nconst isDisabled= computed(()=>{\n     return st.value.isLoading ||!nowModel.value\n})\n\nconst ms= useMessage();\nconst create= async ()=>{\n    if(!nowModel.value){\n        ms.error(t('video.selectModel') )\n        return \n    }\n    st.value.isLoading=true\n    let data={}\n    //const field= nowTpl.value.f\n    for(let k in nowTpl.value ){\n        if(!stArr.value[k]){\n            continue;\n        }\n        const key=nowTpl.value[k].key;\n        data[key]=stArr.value[k]??''\n\n    }\n    //console.log('data>>',data,nowModel.value.plat );\n    try {\n        await PostVideo( nowModel.value, data);\n    } catch (error) {\n        mlog('err',error )\n        ms.error( t('mj.createFail') );\n    }\n    st.value.isLoading=false\n}\nconst nowModel= computed(()=>{\n     return tplArr.value.find(v=> v.model==st.value.model)\n})\n\nonMounted(() => {\n    console.log(\"mytpl>>\",mytpl)\n    if(route.query.model ){\n        st.value.model= route.query.model as string\n    }\n    // ms.error('sdsds')\n    //googleVeoFeed('veo3-fast-frames:1757929479-J7A8Cm8JQS')\n})\n\n\n \n</script>\n<template>\n<div  class=\"p-2\">\n    <div  class=\"pt-1\">\n       <n-select v-model:value=\"st.model\" :options=\"modelsOption\" size=\"small\" filterable />\n    </div>\n    <NEmpty :description=\"$t('video.selectModel')\" v-if=\"!nowModel\" class=\"pt-3\">\n    </NEmpty>\n    <template v-else>\n        <template v-for=\"tp,k in nowTpl\">\n            <div class=\"pt-1\" v-if=\"tp.type=='textarea'\">\n                <n-input\n                v-model:value=\"stArr[k]\"\n                type=\"textarea\"\n                :placeholder=\"tp.placeholder??''\"\n                />\n            </div>\n\n            <div class=\"pt-1\" v-if=\"tp.type=='image_base64_url_array'\">\n                <image-base64-array v-model:value=\"stArr[k]\" upload=\"1\"></image-base64-array>\n            </div>\n             <div class=\"pt-1\" v-if=\"tp.type=='image_base64_url'\">\n                <image-base64-array v-model:value=\"stArr[k]\" :is-one=\"true\"></image-base64-array>\n            </div>\n            <div class=\"pt-1\" v-if=\"tp.type=='image_base64_file'\">\n                <image-base64-array v-model:value=\"stArr[k]\" :is-file=\"true\"  :is-one=\"true\" upload=\"1\"  ></image-base64-array>\n            </div>\n\n            <div class=\"pt-1\" v-if=\"tp.type=='select'\">\n                <n-select v-model:value=\"stArr[k]\" :options=\"tp.options\" size=\"small\"></n-select>\n            </div>\n        </template>\n    \n        <div class=\"mt-3 flex justify-end items-center\">\n            <div class=\"flex \">\n                <n-button type=\"primary\" :block=\"true\" :disabled=\"isDisabled\" @click=\"create()\"  >\n                    <SvgIcon icon=\"mingcute:send-plane-fill\" />   \n                    {{ $t('video.generate') }} \n                </n-button>\n            </div>\n        </div>\n    </template>\n\n</div>\n</template>\n"
  },
  {
    "path": "src/views/video/list.vue",
    "content": "<script setup lang=\"ts\">\nimport { LazyImg, Waterfall } from 'vue-waterfall-plugin-next'\nimport 'vue-waterfall-plugin-next/dist/style.css'\nimport { ViewCard } from 'vue-waterfall-plugin-next/dist/types/types/waterfall';\n\nimport { mlog } from '@/api';\nimport { DtoItem, DtoStore } from '@/api/dtoStore';\nimport { onMounted, ref, watch } from 'vue';\nimport { NEmpty,NButton, useMessage, NPopconfirm,NPopover} from \"naive-ui\"\nimport{ DtoFeed, breakpoints } from './veo'\nimport { t } from '@/locales';\nimport { SvgIcon } from '@/components/common';\nimport { homeStore } from '@/store';\n\nconst csuno= new DtoStore()\nconst list= ref<DtoItem[]>([]);\nconst list2= ref<ViewCard[]>([]);\nconst st=ref({show:false,showImg:'' ,isLoad:false,pIndex:-1,isStart:true });\n\nconst ms= useMessage()\nconst initLoad=()=>{\n    \n    let arr = csuno.getObjs();\n    mlog(\"initLoad List\", arr); //\n    list.value= arr.reverse()\n\n    list2.value= list.value.map((v,k )=>{\n        let url= v.url??''\n        return { url , id: v.id,  index: k, src: url ,isLoad:0,task:v } \n    })\n}\n\nconst getFeed=(item:ViewCard)=>{\n     DtoFeed(item.task)\n}\n\n \nonMounted(()=>{\n   initLoad()\n})\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='dtoFeed') {\n        st.value.isStart= false;\n        initLoad() \n     }\n});\n\nconst deleteGo=(item:any)=>{\n    mlog('deleteGo',item )\n    if( csuno.delete( item.id)){ \n        ms.success( t('common.deleteSuccess'))\n        initLoad()\n    }\n}\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\">\n    <Waterfall :list=\"list2\" :breakpoints=\"breakpoints\"  class=\" !bg-transparent\" v-if=\"list2.length\">\n     <template #item=\"{ item, url, index }\">\n     <div class=\"bg-white dark:bg-[#24272e] rounded-md   overflow-hidden cursor-pointer group/item relative\">\n            \n            <div v-if=\"'failed'==item.task.status\" >\n                <div class=\"w-full h-[200px] justify-center items-center flex text-center\"> {{ t('video.failed') }}<br>ID: {{ item.task.mid }}</div> \n            </div>\n            \n            <template v-else-if=\" ((new Date().getTime())/1000-item.task.last_feed)>20  && !item.src \">\n                <div class=\"w-full pt-[50px] justify-center items-center flex \">\n                    <NButton  size=\"small\" type=\"primary\" @click=\"getFeed(item)\"    >{{$t('video.repeat')}}</NButton>\n                </div>\n                <div class=\" text-center w-full h-[80px] pb-[30px] text-[12px] opacity-80 \">ID: {{ item.task.mid }} </div>\n            </template>\n            <template v-else-if=\"!item.src\">\n                <div class=\"w-full pt-[50px] justify-center items-center flex \">\n                    <div class=\"text-center \">Status: {{ item.task.status }}</div>\n                </div>\n                <div class=\" text-center w-full h-[80px]  pb-[30px] text-[12px] opacity-80 \">ID: {{ item.task.mid }} </div>\n            </template>\n            \n            <template v-else>\n                \n                 <div v-if=\"item.task.type=='video' && item.src\" style=\"padding-bottom: 0%;\" @mouseover=\"st.pIndex=index\">\n                    <video v-if=\"item.src\" :src=\"item.src\"   loop  playsinline disableremoteplayback disablepictureinpicture \n                     :controls=\"st.pIndex==index\" class=\"w-full h-full object-cover\"></video>   \n                    <a target=\"_blank\" :href=\"item.src\" class=\" absolute right-[10px] top-[10px] text-[14px] w-[20px] h-[20px] rounded-full bg-white/20 flex justify-center items-center\">\n                        <SvgIcon icon=\"line-md:download-loop\"  />\n                    </a>\n                </div> \n                \n            </template>\n\n            <section  class=\"absolute w-full bottom-0   backdrop-blur-sm text-white/70  \" :class=\"item.src?['invisible', 'group-hover/item:visible']:[]\">\n                    <div class=\"p-3  flex justify-between items-baseline\">\n                         <n-popover trigger=\"hover\">\n                            <template #trigger> \n                                <div class=\"line-clamp-1 text-[13px]\"> \n                                    <template v-if=\"item.task.title\">{{ item.task.title }}</template>\n                                </div>\n                            </template>\n                             <div>\n                                Model: {{ item.task.model }}<br>\n                                Platform: {{ item.task.plat }}<br>\n                                Id: {{ item.task.id }}<br>\n                             </div>\n                        </n-popover>\n                        <div>\n                            <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                {{ $t('mj.confirmDelete') }}\n                            </n-popconfirm> \n                        </div>\n                    </div>\n            </section>\n             \n          \n     </div>\n     </template>\n    </Waterfall>\n</div>\n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty :description=\"$t('video.nodata')\"></NEmpty>\n</div>\n\n</template>"
  },
  {
    "path": "src/views/video/tpl.json",
    "content": "{\n\"tpl\":[\n    {\n        \"model\":\"veo3-fast-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n               \n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },\n    {\n        \"model\":\"veo2-fast-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n               \n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },\n    {\n        \"model\":\"veo2-fast-components\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":3\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-fast\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            }\n            ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            } ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-pro\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n               \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            } ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-pro-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },{\n    \"model\":\"fal-ai/ltxv-13b-098-distilled/image-to-video\",\n    \"plat\":\"fal-ai\",\n    \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"The astronaut gets up and walks away\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 480p\", \"value\":\"480p\"}\n                ,{ \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/example_inputs/ltxv-image-input.jpg\"\n        }     \n        ]\n\n    },{\n      \"model\":\"fal-ai/ltxv-13b-098-distilled\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A cinematic fast-tracking shot follows a vintage, teal camper van as it descends a winding mountain trail. The van, slightly weathered but well-maintained, is the central focus, its retro design emphasized by the motion blur. Medium shot reveals the dusty, ochre trail, edged with vibrant green pine trees. Close-up on the van's tires shows the gravel spraying, highlighting the speed and rugged terrain. Sunlight filters through the trees, casting dappled shadows on the van and the trail. The background is a hazy, majestic mountain range bathed in warm, golden light. The overall mood is adventurous and exhilarating. High resolution 4k movie scene.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 480p\", \"value\":\"480p\"}\n                ,{ \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n            ]\n        },{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"1:1\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                    ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ]\n        } \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/master/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A cinematic fast-tracking shot follows a vintage, teal camper van as it descends a winding mountain trail. The van, slightly weathered but well-maintained, is the central focus, its retro design emphasized by the motion blur. Medium shot reveals the dusty, ochre trail, edged with vibrant green pine trees. Close-up on the van's tires shows the gravel spraying, highlighting the speed and rugged terrain. Sunlight filters through the trees, casting dappled shadows on the van and the trail. The background is a hazy, majestic mountain range bathed in warm, golden light. The overall mood is adventurous and exhilarating. High resolution 4k movie scene.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"1:1\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                    ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ]\n        } \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/standard/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/pro/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/master/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/standard/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A Galactic Smuggler is a rogue figure with a cybernetic arm and a well-worn coat that hints at many dangerous escapades across the galaxy. Their ship is filled with rare and exotic treasures from distant planets, concealed in hidden compartments, showing their expertise in illicit trade. Their belt is adorned with energy-based weapons, ready to be drawn at any moment to protect themselves or escape from tight situations. This character thrives in the shadows of space, navigating between the law and chaos with stealth and wit, always seeking the next big score while evading bounty hunters and law enforcement. The rogue's ship, rugged yet efficient, serves as both a home and a tool for their dangerous lifestyle. The treasures they collect reflect the diverse and intriguing worlds they've encountered—alien artifacts, rare minerals, and artifacts of unknown origin. Their reputation precedes them, with whispers of their dealings and the deadly encounters that often follow. A master of negotiation and deception, the Galactic Smuggler navigates the cosmos with an eye on the horizon, always one step ahead of those who pursue them.\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/pro/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A Galactic Smuggler is a rogue figure with a cybernetic arm and a well-worn coat that hints at many dangerous escapades across the galaxy. Their ship is filled with rare and exotic treasures from distant planets, concealed in hidden compartments, showing their expertise in illicit trade. Their belt is adorned with energy-based weapons, ready to be drawn at any moment to protect themselves or escape from tight situations. This character thrives in the shadows of space, navigating between the law and chaos with stealth and wit, always seeking the next big score while evading bounty hunters and law enforcement. The rogue's ship, rugged yet efficient, serves as both a home and a tool for their dangerous lifestyle. The treasures they collect reflect the diverse and intriguing worlds they've encountered—alien artifacts, rare minerals, and artifacts of unknown origin. Their reputation precedes them, with whispers of their dealings and the deadly encounters that often follow. A master of negotiation and deception, the Galactic Smuggler navigates the cosmos with an eye on the horizon, always one step ahead of those who pursue them.\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02-fast/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Extremely realistic movement An old samurai is breaking a stone in half\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/tiger/U9HN_tm5-3Ls52SbD6CrW_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/pro/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Man walked into winter cave with polar bear\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"768P\",\n            \"options\":[\n                { \"label\":\"Resolution 512P\", \"value\":\"512P\"}\n                ,{ \"label\":\"Resolution 768P\", \"value\":\"768P\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/model_tests/minimax/1749891352437225630-389852416840474630_1749891352.png\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/standard/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Man walked into winter cave with polar bear\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"768P\",\n            \"options\":[\n                { \"label\":\"Resolution 512P\", \"value\":\"512P\"}\n                ,{ \"label\":\"Resolution 768P\", \"value\":\"768P\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/model_tests/minimax/1749891352437225630-389852416840474630_1749891352.png\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n    ,{\n      \"model\":\"fal-ai/pika/v2.1/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A young woman in a pale blue corset and denim, her vibrant blue bob framed against a dusky desert landscape, walks slowly, her gaze unwavering and enigmatic as the camera remains fixed on her deliberate pace.  The warm glow of a stucco house contrasts with the cool desert air, hinting at both refuge and isolation, while a blurred figure retreating inside adds a layer of unspoken narrative to her solitary journey.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }    \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2.2/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Sunlight streams down on a woman with flowing auburn hair as she runs effortlessly along a tree-lined street, her joyous expression reflecting the freedom of the moment; the simple, steady camerawork emphasizes her grace and the beauty of the everyday.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }   \n        ],\n        \"plat\":\"fal-ai\"\n    }\n    ,{\n      \"model\":\"fal-ai/pika/v2/turbo/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A young woman in a pale blue corset and denim, her vibrant blue bob framed against a dusky desert landscape, walks slowly, her gaze unwavering and enigmatic as the camera remains fixed on her deliberate pace.  The warm glow of a stucco house contrasts with the cool desert air, hinting at both refuge and isolation, while a blurred figure retreating inside adds a layer of unspoken narrative to her solitary journey.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }  \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n \n    ,{\n      \"model\":\"fal-ai/pika/v2.1/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A pink heart exploding.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/elephant/dJjBQXNHRbGJn4aUv4-g9_hearth.jpg\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2.2/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"a woman looking into camera slowly smiling\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/web-examples/pika/pika%202.2/pika_input.png\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2/turbo/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A pink heart exploding.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/elephant/dJjBQXNHRbGJn4aUv4-g9_hearth.jpg\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n]\n}"
  },
  {
    "path": "src/views/video/tpl.ts",
    "content": "export const mytpl={\n\"tpl\":[\n    {\n        \"model\":\"sora-2\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\",\n                \"value\":\"在北京繁忙的人行道上进行的一个随意街头采访。采访者手持一个普通、没有品牌标志的麦克风并问道：你知道OpenAI的Sora 2新模型吗？这是一个好用的视频模型。受访者回答说：是的，我有所了解，它已经可以在openai-hk平台上使用，太好用了。\"\n               \n            }\n            \n             ,{\n                \"key\":\"orientation\",\n                \"type\":\"select\",\n                \"value\":\"portrait\",\n                \"options\":[\n                    { \"label\":\"模式: 竖屏\", \"value\":\"portrait\"}\n                    ,{ \"label\":\"模式: 横屏\", \"value\":\"landscape\"}\n                ]\n            } \n             ,{\n                \"key\":\"duration\",\n                \"type\":\"select\",\n                \"value\":15,\n                \"options\":[\n                    { \"label\":\"Duration: 15s\", \"value\":15}\n                    ,{ \"label\":\"Duration: 10s\", \"value\":10}\n                ]\n            }\n            ,\n            \n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"sora\"\n    },\n    \n    {\n        \"model\":\"sora-2-pro\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\",\n                \"value\":\"在北京繁忙的人行道上进行的一个随意街头采访。采访者手持一个普通、没有品牌标志的麦克风并问道：你知道OpenAI的Sora 2新模型吗？这是一个好用的视频模型。受访者回答说：是的，我有所了解，它已经可以在openai-hk平台上使用，太好用了。\"\n               \n            }\n            \n             ,{\n                \"key\":\"orientation\",\n                \"type\":\"select\",\n                \"value\":\"portrait\",\n                \"options\":[\n                    { \"label\":\"模式: 竖屏\", \"value\":\"portrait\"}\n                    ,{ \"label\":\"模式: 横屏\", \"value\":\"landscape\"}\n                ]\n            }\n             ,{\n                \"key\":\"size\",\n                \"type\":\"select\",\n                \"value\":\"large\",\n                \"options\":[\n                    { \"label\":\"清晰: 高清\", \"value\":\"large\"}\n                    ,{ \"label\":\"清晰: 一般\", \"value\":\"small\"}\n                ]\n            }\n             ,{\n                \"key\":\"duration\",\n                \"type\":\"select\",\n                \"value\":15,\n                \"options\":[\n                    { \"label\":\"Duration: 25s\", \"value\":25}\n                    ,{ \"label\":\"Duration: 15s\", \"value\":15}\n                    ,{ \"label\":\"Duration: 10s\", \"value\":10}\n                ]\n            }\n            \n            ,\n            \n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"sora\"\n    },\n\n    {\n        \"model\":\"openai/sora-2\",\n        \"key\":\"sora-2\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\",\n                \"value\":\"在北京繁忙的人行道上进行的一个随意街头采访。采访者手持一个普通、没有品牌标志的麦克风并问道：你知道OpenAI的Sora 2新模型吗？这是一个好用的视频模型。受访者回答说：是的，我有所了解，它已经可以在openai-hk平台上使用，太好用了。\"\n               \n            }\n            \n             ,{\n                \"key\":\"size\",\n                \"type\":\"select\",\n                \"value\":\"720x1280\",\n                \"options\":[\n                    { \"label\":\"size: 720x1280\", \"value\":\"720x1280\"}\n                    ,{ \"label\":\"size: 1280x720\", \"value\":\"1280x720\"}\n                ]\n            } \n             ,{\n                \"key\":\"seconds\",\n                \"type\":\"select\",\n                \"value\":4,\n                \"options\":[\n                    { \"label\":\"Duration: 15s\", \"value\":15}\n                    ,{ \"label\":\"Duration: 10s\", \"value\":10}\n                    ,{ \"label\":\"Duration: 8s\", \"value\":8}\n                    ,{ \"label\":\"Duration: 4s\", \"value\":4}\n                ]\n            }\n            ,\n            \n            {   \n                \"key\":\"input_reference\",\n                \"type\":\"image_base64_file\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"openai\"\n    },\n\n\n    {\n        \"model\":\"openai/sora-2-pro\",\n        \"key\":\"sora-2-pro\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\",\n                \"value\":\"在北京繁忙的人行道上进行的一个随意街头采访。采访者手持一个普通、没有品牌标志的麦克风并问道：你知道OpenAI的Sora 2新模型吗？这是一个好用的视频模型。受访者回答说：是的，我有所了解，它已经可以在openai-hk平台上使用，太好用了。\"\n               \n            }\n            \n             ,{\n                \"key\":\"size\",\n                \"type\":\"select\",\n                \"value\":\"720x1280\",\n                \"options\":[\n                    { \"label\":\"size: 720x1280\", \"value\":\"720x1280\"}\n                    ,{ \"label\":\"size: 1280x720\", \"value\":\"1280x720\"}\n                ]\n            } \n             ,{\n                \"key\":\"seconds\",\n                \"type\":\"select\",\n                \"value\":4,\n                \"options\":[\n                    { \"label\":\"Duration: 25s\", \"value\":25}\n                    ,{ \"label\":\"Duration: 15s\", \"value\":15}\n                    ,{ \"label\":\"Duration: 10s\", \"value\":10}\n                    ,{ \"label\":\"Duration: 8s\", \"value\":8}\n                    ,{ \"label\":\"Duration: 4s\", \"value\":4}\n                ]\n            }\n            ,\n            \n            {   \n                \"key\":\"input_reference\",\n                \"type\":\"image_base64_file\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"openai\"\n    },\n   \n    {\n        \"model\":\"veo3.1\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            }\n            ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3.1-pro\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            }\n            ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n {\n        \"model\":\"veo3.1-components\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":3\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-fast-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n               \n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },\n    {\n        \"model\":\"veo2-fast-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n               \n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":2\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },\n    {\n        \"model\":\"veo2-fast-components\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":3\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-fast\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            }\n            ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            } ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-pro\",\n       \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n               \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            } ,{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"16:9\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ]\n            }\n        ]\n        ,\"plat\":\"google-veo\"\n    } ,\n    {\n        \"model\":\"veo3-pro-frames\",\n        \"field\":[\n           {\n            \"key\":\"prompt\",\n                \"type\":\"textarea\",\n                \"placeholder\":\"Video Description\"\n            }\n            ,{\n                \"key\":\"enhance_prompt\",\n                \"type\":\"no\",\n                \"value\":true\n            },\n            {   \n                \"key\":\"images\",\n                \"type\":\"image_base64_url_array\",\n                \"max\":1\n            }     \n        ]\n        ,\"plat\":\"google-veo\"\n    },{\n    \"model\":\"fal-ai/ltxv-13b-098-distilled/image-to-video\",\n    \"plat\":\"fal-ai\",\n    \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"The astronaut gets up and walks away\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 480p\", \"value\":\"480p\"}\n                ,{ \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/example_inputs/ltxv-image-input.jpg\"\n        }     \n        ]\n\n    },{\n      \"model\":\"fal-ai/ltxv-13b-098-distilled\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A cinematic fast-tracking shot follows a vintage, teal camper van as it descends a winding mountain trail. The van, slightly weathered but well-maintained, is the central focus, its retro design emphasized by the motion blur. Medium shot reveals the dusty, ochre trail, edged with vibrant green pine trees. Close-up on the van's tires shows the gravel spraying, highlighting the speed and rugged terrain. Sunlight filters through the trees, casting dappled shadows on the van and the trail. The background is a hazy, majestic mountain range bathed in warm, golden light. The overall mood is adventurous and exhilarating. High resolution 4k movie scene.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 480p\", \"value\":\"480p\"}\n                ,{ \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n            ]\n        },{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"1:1\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                    ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ]\n        } \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/master/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A cinematic fast-tracking shot follows a vintage, teal camper van as it descends a winding mountain trail. The van, slightly weathered but well-maintained, is the central focus, its retro design emphasized by the motion blur. Medium shot reveals the dusty, ochre trail, edged with vibrant green pine trees. Close-up on the van's tires shows the gravel spraying, highlighting the speed and rugged terrain. Sunlight filters through the trees, casting dappled shadows on the van and the trail. The background is a hazy, majestic mountain range bathed in warm, golden light. The overall mood is adventurous and exhilarating. High resolution 4k movie scene.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n                \"key\":\"aspect_ratio\",\n                \"type\":\"select\",\n                \"value\":\"1:1\",\n                \"options\":[\n                    { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                    ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                    ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ]\n        } \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/standard/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/pro/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Warm, incandescent streetlights paint the rain-slicked cobblestones in pools of amber light as a couple walks hand-in-hand, their silhouettes stark against the blurry backdrop of a city shrouded in a gentle downpour; the camera lingers on the subtle textures of their rain-soaked coats and the glistening reflections dancing on the wet pavement, creating a sense of intimate vulnerability and shared quietude.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/lion/_I_io6Gtk83c72d-afXf8_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/kling-video/v2.1/master/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Sunlight dapples through budding branches, illuminating a vibrant tapestry of greens and browns as a pair of robins meticulously weave twigs and mud into a cradle of life, their tiny forms a whirlwind of activity against a backdrop of blossoming spring.  The scene unfolds with a gentle, observational pace, allowing the viewer to fully appreciate the intricate details of nest construction, the soft textures of downy feathers contrasted against the rough bark of the branches, the delicate balance of strength and fragility in their creation.\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/zebra/9Nrm22YyLojSTPJbZYNhh_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/standard/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A Galactic Smuggler is a rogue figure with a cybernetic arm and a well-worn coat that hints at many dangerous escapades across the galaxy. Their ship is filled with rare and exotic treasures from distant planets, concealed in hidden compartments, showing their expertise in illicit trade. Their belt is adorned with energy-based weapons, ready to be drawn at any moment to protect themselves or escape from tight situations. This character thrives in the shadows of space, navigating between the law and chaos with stealth and wit, always seeking the next big score while evading bounty hunters and law enforcement. The rogue's ship, rugged yet efficient, serves as both a home and a tool for their dangerous lifestyle. The treasures they collect reflect the diverse and intriguing worlds they've encountered—alien artifacts, rare minerals, and artifacts of unknown origin. Their reputation precedes them, with whispers of their dealings and the deadly encounters that often follow. A master of negotiation and deception, the Galactic Smuggler navigates the cosmos with an eye on the horizon, always one step ahead of those who pursue them.\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/pro/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A Galactic Smuggler is a rogue figure with a cybernetic arm and a well-worn coat that hints at many dangerous escapades across the galaxy. Their ship is filled with rare and exotic treasures from distant planets, concealed in hidden compartments, showing their expertise in illicit trade. Their belt is adorned with energy-based weapons, ready to be drawn at any moment to protect themselves or escape from tight situations. This character thrives in the shadows of space, navigating between the law and chaos with stealth and wit, always seeking the next big score while evading bounty hunters and law enforcement. The rogue's ship, rugged yet efficient, serves as both a home and a tool for their dangerous lifestyle. The treasures they collect reflect the diverse and intriguing worlds they've encountered—alien artifacts, rare minerals, and artifacts of unknown origin. Their reputation precedes them, with whispers of their dealings and the deadly encounters that often follow. A master of negotiation and deception, the Galactic Smuggler navigates the cosmos with an eye on the horizon, always one step ahead of those who pursue them.\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02-fast/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Extremely realistic movement An old samurai is breaking a stone in half\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/tiger/U9HN_tm5-3Ls52SbD6CrW_image.webp\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/pro/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Man walked into winter cave with polar bear\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"768P\",\n            \"options\":[\n                { \"label\":\"Resolution 512P\", \"value\":\"512P\"}\n                ,{ \"label\":\"Resolution 768P\", \"value\":\"768P\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/model_tests/minimax/1749891352437225630-389852416840474630_1749891352.png\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/minimax/hailuo-02/standard/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Man walked into winter cave with polar bear\"\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 6s\", \"value\":6}\n                ,{ \"label\":\"Duration 10s\", \"value\": 10}\n            ]\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"768P\",\n            \"options\":[\n                { \"label\":\"Resolution 512P\", \"value\":\"512P\"}\n                ,{ \"label\":\"Resolution 768P\", \"value\":\"768P\"}\n            ]\n\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/model_tests/minimax/1749891352437225630-389852416840474630_1749891352.png\"\n        }     \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n    ,{\n      \"model\":\"fal-ai/pika/v2.1/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A young woman in a pale blue corset and denim, her vibrant blue bob framed against a dusky desert landscape, walks slowly, her gaze unwavering and enigmatic as the camera remains fixed on her deliberate pace.  The warm glow of a stucco house contrasts with the cool desert air, hinting at both refuge and isolation, while a blurred figure retreating inside adds a layer of unspoken narrative to her solitary journey.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }    \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2.2/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"Sunlight streams down on a woman with flowing auburn hair as she runs effortlessly along a tree-lined street, her joyous expression reflecting the freedom of the moment; the simple, steady camerawork emphasizes her grace and the beauty of the everyday.\"\n        },{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        },{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }   \n        ],\n        \"plat\":\"fal-ai\"\n    }\n    ,{\n      \"model\":\"fal-ai/pika/v2/turbo/text-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A young woman in a pale blue corset and denim, her vibrant blue bob framed against a dusky desert landscape, walks slowly, her gaze unwavering and enigmatic as the camera remains fixed on her deliberate pace.  The warm glow of a stucco house contrasts with the cool desert air, hinting at both refuge and isolation, while a blurred figure retreating inside adds a layer of unspoken narrative to her solitary journey.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        },{\n            \"key\":\"aspect_ratio\",\n            \"type\":\"select\",\n            \"value\":\"16:9\",\n            \"options\":[\n                { \"label\":\"Ratio 16:9\", \"value\":\"16:9\"}\n                ,{ \"label\":\"Ratio 9:16\", \"value\":\"9:16\"}\n                ,{ \"label\":\"Ratio 1:1\", \"value\":\"1:1\"}\n                ,{ \"label\":\"Ratio 4:5\", \"value\":\"4:5\"}\n                ,{ \"label\":\"Ratio 5:4\", \"value\":\"5:4\"}\n                ,{ \"label\":\"Ratio 3:2\", \"value\":\"3:2\"}\n                ,{ \"label\":\"Ratio 2:3\", \"value\":\"2:3\"}\n            ]\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        }  \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n \n    ,{\n      \"model\":\"fal-ai/pika/v2.1/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A pink heart exploding.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/elephant/dJjBQXNHRbGJn4aUv4-g9_hearth.jpg\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2.2/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"a woman looking into camera slowly smiling\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://storage.googleapis.com/falserverless/web-examples/pika/pika%202.2/pika_input.png\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    },{\n      \"model\":\"fal-ai/pika/v2/turbo/image-to-video\",\n      \"field\":[\n        {\n            \"key\":\"prompt\",\n            \"type\":\"textarea\",\n            \"placeholder\":\"Video Description\",\n            \"value\":\"A pink heart exploding.\"\n        } ,{\n            \"key\":\"resolution\",\n            \"type\":\"select\",\n            \"value\":\"720p\",\n            \"options\":[\n                { \"label\":\"Resolution 720p\", \"value\":\"720p\"}\n                ,{ \"label\":\"Resolution 1080p\", \"value\":\"1080p\"}\n            ]\n\n        } ,{\n            \"key\":\"duration\",\n            \"type\":\"select\",\n            \"value\":5,\n            \"options\":[\n                { \"label\":\"Duration 5s\", \"value\":5}\n                ,{ \"label\":\"Duration 8s\", \"value\": 8}\n            ]\n        },{   \n                \"key\":\"image_url\",\n                \"type\":\"image_base64_url\",\n                \"value\":\"https://v3.fal.media/files/elephant/dJjBQXNHRbGJn4aUv4-g9_hearth.jpg\"\n        }       \n        ],\n        \"plat\":\"fal-ai\"\n    }\n\n]\n}"
  },
  {
    "path": "src/views/video/veo.ts",
    "content": "import { gptFetch, gptUploadFile, mlog } from \"@/api\"\nimport { DtoItem, DtoStore } from \"@/api/dtoStore\"\nimport { sleep } from \"@/api/suno\"\nimport { homeStore } from \"@/store\"\n\nexport interface DtoTpl{\n    model:string\n    key?:string\n    field:DtoField[]\n    plat:string\n}\nexport interface DtoField{\n    key:string\n    type:string \n    value?:any           \n    max?:number           \n    placeholder?:string           \n    options?:  {labal:string,value:string}[]           \n}\n\nconst csuno= new DtoStore()\n\nexport const PostVideo= async(nowModel:DtoTpl, data:any)=>{\n    mlog('PostVideo',nowModel);\n    mlog('data ',data);\n    let rz:DtoItem\n     \n    const plat= nowModel.plat\n    if( plat==\"google-veo\" ||  plat==\"sora\" ){\n        rz= await googleVeo(nowModel,data)\n    }else if(plat=='openai'){\n        rz= await openaiVideo(nowModel,data)\n    }else if(plat=='fal-ai'){\n        rz= await falAI(nowModel,data)\n    }else{\n        mlog(\"plat\",plat, \"这个平台没有指定\")\n        return \n    }\n    rz.model= nowModel.model\n    csuno.save( rz)\n    homeStore.setMyData({act:'dtoFeed'});\n    DtoFeed(rz)\n}\n\nexport const DtoFeed= async (item:DtoItem)=>{\n   // mlog(\"sdsds\",item )\n    // if(item.plat==\"google-veo\"){\n    //     googleVeoFeed(item.id)\n    // }else if(item.plat==\"fal-ai\"){\n    //     falAiFeed(item.id)\n    // }\n   if(item.plat==\"fal-ai\"){\n        falAiFeed(item.id)\n    }else if(item.plat==\"openai\" ){\n     openaiVideoFeed(item.id)\n    }else{\n      googleVeoFeed(item.id)\n    }\n}\n\nconst falAI= async(nowModel:DtoTpl, data:any)=>{\n const d:any = await gptFetch( '/'+nowModel.model ,data)\n const id= d.request_id\n let  rz:DtoItem={\n       mid: id,\n       id,\n       type: \"video\",\n       plat: nowModel.plat,\n       status: \"submitted\",\n       last_feed:  Math.floor(Date.now() / 1000),\n       title:data.prompt??'no prompt'\n   }\n   return rz\n}\n\nconst openaiVideo= async(nowModel:DtoTpl, data:any)=>{\n    data['model']= nowModel.key?? nowModel.model \n    //var d:any\n    //d = await gptFetch('/v1/videos',data)\n    const formData = new FormData( ); \n     for(let o in data ){\n        if(o=='input_reference'&&   data[o]?.file ){\n            // for(let f of data.data.base64Array){\n            //      formData.append('image[]', f.file )\n            // }\n            formData.append('input_reference',  data[o]?.file )\n        }else{\n            formData.append(o, data[o])\n        }\n       \n\n     }\n    //mlog(\"formData  \",  formData   )\n    \n    //const jda=    upd.data\n    //try {\n        const ds = await gptUploadFile('/v1/videos', formData)\n        const d=ds.data;\n        if(ds.status!=200) throw \"Fail with status:\"+ ds.status\n        mlog(\"rz  \",  d   )\n    // }catch(e){\n    //     mlog(\"error  \",  e   )\n    // }\n    let  rz:DtoItem={\n       mid: d.id,\n       id: d.id,\n       type: \"video\",\n       plat: nowModel.plat,\n       status: \"submitted\",\n       last_feed:  Math.floor(Date.now() / 1000),\n       title:data.prompt??'no prompt'\n   }\n   return rz\n}\n\nconst googleVeo= async(nowModel:DtoTpl, data:any)=>{\n   data['model']= nowModel.model \n   const plat= nowModel.plat\n   var d:any\n   if (plat==\"google-veo\"){\n     d = await gptFetch('/veo/v1/video/create',data)\n   }else{\n    d = await gptFetch('/'+plat+'/v1/video/create',data)\n   }\n   // mlog('返回数据 ',d );\n   let  rz:DtoItem={\n       mid: d.id,\n       id: d.id,\n       type: \"video\",\n       plat: nowModel.plat,\n       status: \"submitted\",\n       last_feed:  Math.floor(Date.now() / 1000),\n       title:data.prompt??'no prompt'\n   }\n   return rz\n}\n\nexport const falAiFeed= async( id:string)=>{\n    for(let i=0;i<60;i++){\n        let  rz= csuno.getOneById(id)\n        if(!rz){\n            return \n        }\n        if(rz?.status=='completed'||  rz?.status=='failed'){    \n            return \n        }\n        if(!rz.model){\n            rz.model='fal-ai/ltxv-13b-098-distilled/image-to-video'\n        }\n        const arr= rz.model.split('/')\n        const url= '/'+arr[0]+'/'+arr[1]+'/requests/'+ rz.mid; //requests/b551cfac-0399-4122-a3fa-91e8760f5086\n        try {\n            const d:any = await gptFetch(url)\n            rz.url= d.video?.url??''\n            rz.data=d\n            rz.status= rz.url?'completed':'pending'\n        } catch (error) {\n            rz.status= 'pending'\n        }\n        \n\n        rz.last_feed=Math.floor(Date.now() / 1000)\n        console.log('ddd',d, rz );\n        csuno.save(rz)\n        homeStore.setMyData({act:'dtoFeed'});\n        await sleep(3000)\n   }\n\n}\n     \nexport const openaiVideoFeed=async( id:string)=>{\nfor(let i=0;i<60;i++){\n        let  rz= csuno.getOneById(id)\n        if(!rz){\n            return \n        }\n        if(rz?.status=='completed'||  rz?.status=='failed'){    \n            return \n        }\n         \n        const url= '/v1/videos/'+ rz.mid; \n        try {\n            const d:any = await gptFetch(url)\n            if(d.status=='failed'){\n                 rz.status='failed'\n                 rz.data=d\n            }else{\n                var obj:string=d.url??(d.video_url??'')\n                rz.url= obj.startsWith('http')?obj:''\n                rz.data=d\n                rz.status= rz.url?'completed': d.status\n                if(d.progress && d.progress>0){\n                     rz.status=d.progress+ '%'\n                }\n            }\n        } catch (error) {\n            rz.status= 'pending'\n        }\n        \n\n        rz.last_feed=Math.floor(Date.now() / 1000)\n        console.log('ddd',  rz );\n        csuno.save(rz)\n        homeStore.setMyData({act:'dtoFeed'});\n        await sleep(5000)\n   }\n}\nexport const googleVeoFeed= async( id:string)=>{\n    for(let i=0;i<60;i++){\n        let  rz= csuno.getOneById(id)\n        if(rz?.status=='completed'||  rz?.status=='failed'){    \n            break \n        }\n        var d:any\n        if (rz && rz.plat!='google-veo' && rz.plat!=''){\n             d = await gptFetch(`/${rz.plat}/v1/video/feed/${id}`)\n        }else{\n            d = await gptFetch(`/veo/v1/video/feed/${id}`)\n        }\n        if(!rz){\n            rz={\n                mid: d.id,\n                id: d.id,\n                type: \"video\",\n                plat: 'google-veo',\n                status: \"submitted\",\n                last_feed:  0,\n                title:'no prompt'\n\n            }\n        }\n      \n        rz.last_feed=Math.floor(Date.now() / 1000)\n        rz.status= d.status?? rz.status\n        rz.url= d.video_url??''\n        rz.data=d\n        csuno.save(rz)\n        homeStore.setMyData({act:'dtoFeed'});\n        await sleep(3000)\n\n     }\n    \n}\n\n\nexport const breakpoints= {\n  2000: { //当屏幕宽度小于等于1200\n    rowPerView: 6,\n  },\n  1600: { //当屏幕宽度小于等于1200\n    rowPerView: 5,\n  },\n  1200: { //当屏幕宽度小于等于1200\n    rowPerView: 4,\n  },\n  800: { //当屏幕宽度小于等于800\n    rowPerView: 3,\n  },\n  500: { //当屏幕宽度小于等于500\n    rowPerView: 2,\n  }\n}"
  },
  {
    "path": "src/views/viggle/dance.vue",
    "content": " <script setup lang=\"ts\">\n import DcInput from './dcInput.vue';\n import DcList from './dcList.vue';\n\n </script>\n<template>\n\n<div class=\"flex w-full h-full   \">\n    <div class=\"w-[300px] h-full  overflow-y-auto \">\n         <DcInput/>\n    </div>\n    <div class=\" flex-1  h-full bg-[#fafbfc] pt-2 dark:bg-[#18181c] overflow-y-auto \" >\n        <DcList/>\n    </div>\n     \n</div>\n</template> "
  },
  {
    "path": "src/views/viggle/dcInput.vue",
    "content": "<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { NSelect,NButton,NDrawer,NDrawerContent,NInput, useMessage, NImage } from 'naive-ui';\nimport { useBasicLayout } from '@/hooks/useBasicLayout';\nimport {SvgIcon} from '@/components/common'\nimport dcTemple from \"./dcTemple.vue\"\nimport { gptServerStore, homeStore } from '@/store';\nimport {  mlog, upImg } from '@/api';\nimport { FeedViggleTask, ViggleTemplate , viggleFetch } from '@/api/viggle';\nimport { t } from '@/locales';\nimport { lumaHkStore } from '@/api/lumaStore';\nimport { sleep } from '@/api/suno';\n\nconst f= ref({ \"imageID\": \"\", \"bgMode\": 2, \"modelInfoID\": 4,\"templateID\": \"\",\"videoID\":'','watermark':1 })\nconst st= ref({isDo:false,showImg:false,q:'',imgSrc:'',vgSrc:'',vgCoverURL:'',version:'relax',fee:0 })\nconst useTem= ref<ViggleTemplate>()\nconst fsRef= ref() ;\nconst vsRef= ref() ;\nconst ms = useMessage();\n\nconst { isMobile } = useBasicLayout()\n\n\nconst modelOption= [\n{label: t('dance.model')+': V3-Beta',value: 4},\n{label:t('dance.model')+': V2-Turbo',value:3},\n{label: t('dance.model')+': V2',value: 2}\n\n ]\n const bgOption= [\n     {label:t('dance.bgw') ,value: 0}\n    ,{label:t('dance.bgg'),value:1}\n    ,{label:t('dance.bgmoban') ,value:2}\n    ,{label:t('dance.bgrole') ,value:3}\n ]\n\nconst generate= async ()=>{\n    ms.loading(t('dance.gring'))\n    let d = await viggleFetch( getMyProUrl('/video-task'), f.value); \n    if (d.data && d.data.taskID) {\n        if( st.value.version=='pro' ){\n            const hk= new lumaHkStore();\n            hk.save({id:d.data.taskID,isHK:true})\n            await sleep(800)\n        }\n        FeedViggleTask(d.data.taskID)  \n    }\n}\n\nconst doCheckFee= async (data:any)=>{\n    //  video-task/credit/calculate\n     const dd= await viggleFetch( getMyProUrl('/video-task/credit/calculate'),  data ); \n\n     st.value.fee= dd.data\n\n     return dd;\n     \n}\nconst search=()=>{\n    \n}\nconst canPost= computed(()=>{\n    return (f.value.templateID|| f.value.videoID) && f.value.imageID \n})\n\nconst clear=(type:number)=>{\n    if(type==1){\n        useTem.value=undefined\n        f.value.templateID=''\n        f.value.videoID=''\n    }else if(type==3){\n        useTem.value=undefined\n        f.value.templateID=''\n        f.value.videoID=''\n        st.value.vgSrc=''\n        st.value.vgCoverURL=''\n    }else{\n        f.value.imageID=''\n        st.value.imgSrc=''\n    }\n    \n}\n\nfunction getMyProUrl( url:string ){\n    // const is_luma_pro=homeStore.myData.is_luma_pro\n    if (st.value.version=='pro' ) url= '/pro'+url\n    return url ;\n}\n\nasync function  selectFileVideo(input:any){  \n    const formData = new FormData(); \n    formData.append('file', input.target.files[0]) \n    let d:any = await viggleFetch(getMyProUrl( '/asset/video/'+f.value.imageID) , formData,{upFile:true})\n    mlog(\"d Video\", d )\n    if(d.data ) {\n       if( d.data.id ) {\n        f.value.videoID= d.data.id\n        f.value.templateID='' \n        st.value.vgCoverURL= d.data.coverURL\n        st.value.vgSrc= d.data.url\n       }\n    }\n   \n}\n\nconst selectVideo=()=>{ \n    if(f.value.imageID==''){\n        ms.error(t('dance.uprolefirst'))\n        return \n    }\n    vsRef.value.click()\n}\n\nasync function  selectFile(input:any){  \n    try{\n    let ud= await upImg(input.target.files[0]) \n    const formData = new FormData(); \n    formData.append('file', input.target.files[0])\n   \n    let d:any = await viggleFetch( getMyProUrl('/asset/image'), formData,{upFile:true})\n    mlog(\"d Image\", d )\n    if(d.data ) {\n       if( d.data.id ) {\n        f.value.imageID= d.data.id\n        st.value.imgSrc= ud;//d.data.url\n       }\n    }\n    fsRef.value=''\n    }catch(e ){\n         ms.error( t('dance.uprolefail'))\n    }\n}\n\nconst isHK= computed(()=> {\n    const url= gptServerStore.myData.VIGGLE_SERVER.toLocaleLowerCase();\n    if(url!=''){\n     return (url.indexOf('hk')>-1 &&  url.indexOf('pro')==-1 ) ;\n    }\n   \n    return (homeStore.myData.session && homeStore.myData.session.isHk) ;\n    \n} );\n\nconst saveMyDate=(is_pro:boolean)=>{\n    homeStore.setMyData({is_viggle_pro: is_pro})\n    gptServerStore.setMyData({IS_VIGGLE_PRO: is_pro})\n}\n\nwatch(()=>isHK.value , (n)=>    saveMyDate( n && st.value.version=='pro' ) ); \nwatch(()=>st.value.version , ()=>  saveMyDate(isHK.value && st.value.version=='pro' ) );\n\nwatch(()=>homeStore.myData.act,  async (n)=>{\n    //canPost.value= n.modelInfoID!=0 && n.bgMode!=0\n    if(n=='viggle.useVideo'){\n        mlog(\"viggle.useVideo\", homeStore.myData.actData )\n        useTem.value= homeStore.myData.actData as ViggleTemplate\n        st.value.showImg=false\n        f.value.templateID= useTem.value.id\n        f.value.videoID= '' \n        const dd= await doCheckFee({ templateID: useTem.value.id})\n        mlog(\"viggle.doCheckFee\", dd )\n    }\n})\nconst mvOption= [\n{label: '版本: watermark, 价格实惠',value: 'relax'}\n,{label:'版本: pro, 无水印',value: 'pro'}\n ]\n\n\n//homeStore.setMyData({ms}) \nonMounted(() => {\n    homeStore.setMyData({ms:ms})\n    st.value.version= gptServerStore.myData.IS_VIGGLE_PRO?'pro':'relax'\n});\n\n</script>\n<template>\n<div class=\"p-2\"> \n    <div>\n         <n-select v-model:value=\"f.modelInfoID\" :options=\"modelOption\" size=\"small\" />\n    </div>\n    <div class=\"pt-2\">\n         <n-select v-model:value=\"f.bgMode\" :options=\"bgOption\" size=\"small\" />\n    </div>\n    <div class=\"pt-2 flex justify-center items-center w-full relative\">\n        <input type=\"file\"  @change=\"selectFile\"  ref=\"fsRef\" style=\"display: none\" accept=\"image/jpeg, image/jpg, image/png, image/gif\"/>\n        <div class=\"absolute right-1 top-3 z-40\"  v-if=\"st.imgSrc\" >\n                    <NButton strong secondary round size=\"small\" type=\"success\" @click=\"clear(2)\" >{{$t('common.clear')}}</NButton> \n        </div>\n        <div class=\"h-[180px] w-full overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center cursor-pointer\" @click=\" fsRef.click()\">\n            <NImage :src=\"st.imgSrc\" v-if=\"st.imgSrc\" object-fit=\"contain\" />\n            <div class=\"text-center\"  v-else> \n                <NButton  type=\"primary\" size=\"small\">+{{ $t('dance.character') }}</NButton>\n            </div> \n        </div>\n    </div>\n\n    <div class=\"pt-2 \" v-if=\"useTem\">\n         <div class=\"relative h-[180px]\" > \n                <div class=\"absolute right-1 top-1 z-40\"  >\n                    <NButton strong secondary round size=\"small\" type=\"success\" @click=\"clear(1)\" >{{$t('common.clear')}}</NButton> \n                </div>\n                <div class=\" absolute w-full h-full top-0 left-0 z-1\"   >\n                \n                <video controls   playsinline loop :poster=\"useTem.processedCoverURL\" \n                 class=\"  rounded-lg bg-[#242424] object-contain w-full h-full transition-all\"      :src=\"useTem.processedURL\" ></video>\n                </div>\n            </div>\n    </div>\n     <div class=\"pt-2 \" v-else-if=\"st.vgSrc\">\n         <div class=\"relative h-[180px]\" > \n                <div class=\"absolute right-1 top-1 z-40\"  >\n                    <NButton strong secondary round size=\"small\" type=\"success\" @click=\"clear(3)\" >{{$t('common.clear')}}</NButton> \n                </div>\n                <div class=\" absolute w-full h-full top-0 left-0 z-1\"   >\n                \n                <video controls   playsinline loop :poster=\"st.vgCoverURL\" \n                 class=\"  rounded-lg bg-[#242424] object-contain w-full h-full transition-all\"      :src=\"st.vgSrc\" ></video>\n                </div>\n            </div>\n    </div>\n    \n\n    <div class=\"pt-2 flex justify-center items-center w-full\" v-else>\n        <input type=\"file\"  @change=\"selectFileVideo\"  ref=\"vsRef\" style=\"display: none\" accept=\".mp4\" />\n\n        <div class=\"h-[180px] w-full overflow-hidden rounded-sm border border-gray-400/20 flex justify-center items-center \" >\n            <!-- <img :src=\"luma.image_url\" v-if=\"luma.image_url\" /> -->\n            <div class=\"text-center\"  >\n            <div class=\"cursor-pointer p-2\" @click=\"selectVideo\">{{$t('dance.upvideo')}}  </div> \n            <NButton  type=\"primary\" size=\"small\" @click=\"st.showImg=true\">{{$t('dance.usevideo')}} </NButton>\n            </div> \n        </div>\n    </div>\n\n    <div  class=\"pt-2\" v-if=\"isHK\">\n        <n-select v-model:value=\"st.version\" :options=\"mvOption\" size=\"small\" />\n    </div>\n\n    <div class=\"pt-2 flex justify-center items-center w-full\">\n         <NButton block :loading=\"st.isDo\" type=\"primary\" :disabled=\"!canPost\" @click=\"generate()\">\n            <!-- <SvgIcon icon=\"ri:video-add-line\"  />  -->\n            {{$t('video.generate')}}\n            <template v-if=\"st.fee>0\">\n              {{ st.fee }}<SvgIcon icon=\"mage:electricity\"/>\n            </template>\n         </NButton> \n    </div>\n    \n   <div   class=\"pt-4 text-[12px]\" v-html=\"t('dance.info')\"> </div>\n</div>\n\n <n-drawer v-model:show=\"st.showImg\"   :placement=\"isMobile?'bottom':'right'\"  :class=\"isMobile?['!h-[90vh]']: ['!w-[80vw]']\" style=\"--n-body-padding:0\">\n    <n-drawer-content  class=\"mydrawer\" :closable=\"isMobile\">\n        <template #header>\n            <div class=\"flex justify-between items-center w-full\"> \n            <div class=\"pr-4\">{{$t('dance.moban')}}</div>\n            <div class=\" max-w-[400px]\">\n                <n-input round :placeholder=\"t('dance.moban2')\" clearable v-model:value=\"st.q\" @keydown.enter=\"search()\" >\n                    <template #prefix>\n                        <SvgIcon icon=\"uil:search\"/>\n                    </template>\n                    <template #suffix>\n                        <div class=\"cursor-pointer\" @click=\"search()\">{{ $t('mjchat.search')}}</div>\n                    </template>\n                </n-input>\n            </div>\n            </div>\n        </template>\n        <dcTemple :q=\"st.q\" @toq=\"(d)=>st.q= d.q\" @close=\"st.showImg=false\"/>\n    </n-drawer-content>\n</n-drawer>\n</template>"
  },
  {
    "path": "src/views/viggle/dcList.vue",
    "content": "<script setup lang=\"ts\"> \nimport { FeedViggleTask } from '@/api/viggle';\nimport { ViggleTask, viggleStore } from '@/api/viggleStore';\nimport {NEmpty ,NButton,NPopover, NTag,NButtonGroup,useMessage ,NPopconfirm} from 'naive-ui'\n \nimport { ref, watch } from 'vue';\nimport {SvgIcon} from \"@/components/common\"\nimport { homeStore } from '@/store';\nimport { t } from '@/locales';\n\nconst st= ref({pIndex:-1});\nconst list= ref<ViggleTask[]>([]);\nconst ms = useMessage();\nconst csuno = new viggleStore()\nconst initLoad=()=>{\n    let arr = csuno.getObjs();\n    list.value= arr.reverse()\n}\nconst TaskDown=async (item:ViggleTask)=>{\n    \n    const link = document.createElement('a');\n    link.href = item.result ;\n    link.download = item.taskID+\".mp4\";\n    link.target = '_blank';\n    link.rel='noreferrer'\n    document.body.appendChild(link);\n    link.click();\n    document.body.removeChild(link);\n    \n}\n\nwatch(()=>homeStore.myData.act, (n)=>{\n     if(n=='FeedViggleTask')  initLoad() \n});\nconst deleteGo=(v:ViggleTask)=>{\n    if(csuno.delete(v)) {\n        ms.success( t('common.deleteSuccess'))\n        initLoad();\n    }\n\n}\ninitLoad()\n</script>\n<template>\n<div v-if=\"list.length>0\" class=\"p-4\" >\n    <div  class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div v-for=\"(item, index) in list\" :key=\"index\" class=\"relative\" @mousemove=\"st.pIndex=index\" @mouseout=\"st.pIndex=-1\">\n            <div class=\"relative flex items-center justify-center bg-white bg-opacity-10 rounded-[16px] overflow-hidden aspect-[16/8.85] \">\n                <video class=\"bg-[#242424] object-contain w-full h-full transition-all\"\n                 v-if=\"item.result\"   referrerpolicy=\"no-referrer\"\n                :poster=\"item.resultCover\" loop  playsinline  :controls=\"st.pIndex==index\" >\n                    <source :src=\"item.result\" referrerpolicy=\"no-referrer\" type=\"video/mp4\" v-if=\"st.pIndex==index\">\n                </video>\n                <div class=\" text-center\" v-else>\n                     \n                    <NButton  size=\"small\" type=\"primary\" @click=\"FeedViggleTask( item.taskID )\"   v-if=\"!item.last_feed|| ((new Date().getTime())-item.last_feed)>20*1000\" >{{$t('video.repeat')}}</NButton>\n                    <div class=\"pt-2\" v-else>\n                        <div>{{$t('video.process')}}{{ new Date(item.last_feed).toLocaleString() }}</div> \n                    </div>\n                   \n                </div>\n            </div>\n            <div class=\"flex justify-between items-center\">\n                <div  >\n                <n-popover trigger=\"hover\">\n                    <template #trigger>\n                    <div class=\"line-clamp-1\">{{item.taskID}}</div>\n                    </template>\n                    <div class=\" max-w-[300px]\">{{item.taskID}}</div>\n                </n-popover>\n                \n                </div>\n                <div class=\"flex justify-end items-center pt-1\"   > \n                     <!-- <span    @click=\"FeedLumaTaskDown( item.id )\" class=\"cursor-pointer\" ><SvgIcon icon=\"mdi:download\" /></span> -->\n\n                    \n                      <n-button-group size=\"tiny\">\n                        <n-button  size=\"tiny\" round ghost @click=\"TaskDown( item )\"   ><SvgIcon icon=\"mdi:download\" /> {{ $t('video.download') }}</n-button>\n                        <!-- <n-button   size=\"tiny\"  round ghost   ><SvgIcon icon=\"ri:video-add-line\" /> {{ $t('video.extend') }}</n-button> -->\n                        <n-button   size=\"tiny\"  round ghost    > \n                                <n-popconfirm @positive-click=\"()=>deleteGo(item)\" placement=\"bottom\">\n                                    <template #trigger> <SvgIcon icon=\"mdi:delete\"  /></template>\n                                    {{ $t('mj.confirmDelete') }}\n                                </n-popconfirm> \n                            </n-button>\n                      </n-button-group>\n                     <!-- <a :href=\"item.video?.download_url? item.video?.download_url:item.video?.url\" download  target=\"_blank\" v-if=\"item.video?.url|| item.video?.download_url\"  ><SvgIcon icon=\"mdi:download\" class=\"cursor-pointer\"/></a> -->\n                </div>\n            </div>\n        </div>\n    </div>\n</div> \n<div class=\"w-full h-full flex justify-center items-center\" v-else>\n    <NEmpty description=\"请先创作才有跳舞视频列表\"></NEmpty>\n</div>\n</template>"
  },
  {
    "path": "src/views/viggle/dcTemple.vue",
    "content": "<script setup lang=\"ts\">\nimport { mlog } from '@/api';\nimport { viggleFetch,tagInfo,ViggleTemplate } from '@/api/viggle';\nimport { ref } from 'vue';\nimport { NButton } from 'naive-ui';\nimport { homeStore } from '@/store';\n \n\nconst st= ref({qindex:0}) \nconst emit = defineEmits(['close','toq']);\nconst pp= defineProps<{q:string}>( );\n\n\n\nconst tagOption= ref<tagInfo[]>([])\nconst myList = ref<ViggleTemplate[]>([])\n\nconst loadTag= async ()=>{\n    let d= await viggleFetch('/template2/tag')\n    mlog('tags', d );\n    if (d.data ) {\n        tagOption.value= d.data;\n        if( tagOption.value.length>0 ) goSearch( tagOption.value[0] )\n    }\n}\nconst initLoad=()=>{\n   loadTag()\n}\nconst goSearch= (v:tagInfo)=>{\n     emit('toq',{q:v.name});\n     searchQ('',v.id)\n}\n\nconst searchQ= async (q:string,tagID:string)=>{\n    let url=`/template2?page=1&pageSize=48&searchKeyword=${ encodeURIComponent(q) }&tagID=${ tagID }&type=0`\n    let d= await viggleFetch( url)\n    mlog('searchQ', d );\n    myList.value=[]\n    if (d.data && d.data.length>0 ) {\n         myList.value= d.data as ViggleTemplate[]\n    }\n    \n}\n\nconst useVideo= (v:ViggleTemplate )=>{\n    mlog('useVideo', v );\n    homeStore.setMyData({act:'viggle.useVideo', actData: v })\n}\n\ninitLoad()\n</script>\n\n<template>\n<div class=\"w-full h-full p-4\">\n    <div class=\"flex items-center justify-start line-clamp-1 pb-4\"  >\n        <div class=\"m-1 cursor-pointer\" v-for=\"v in tagOption\" @click=\"goSearch(v)\">\n        <n-button strong   round size=\"small\" type=\"success\" v-if=\"v.name==pp.q\">{{ v.name }}</n-button>\n        <n-button strong secondary round size=\"small\" type=\"success\" v-else>{{ v.name }}</n-button>\n        </div>\n    </div>\n    <div v-if=\"myList.length>0\"   class=\"grid grid-cols-1 gap-5 md:grid-cols-2 lg:grid-cols-3\">\n        <div   v-for=\"(v,k) in myList\" class=\"  mb-2 \" >\n            <div class=\"relative h-[180px]\" @mousemove=\"st.qindex=k\">\n                <div class=\"absolute right-2 top-2 z-40\" v-if=\"st.qindex==k\">\n                    <NButton rounded size=\"small\" type=\"success\" @click=\"useVideo(v)\">{{$t('dance.use')}}</NButton>\n                </div>\n                <div class=\"   absolute w-full h-full top-0 left-0 z-1\"   >\n                <video :controls=\"st.qindex==k\"  playsinline loop :poster=\"v.processedCoverURL\" \n                 class=\"  rounded-lg bg-[#242424] object-contain w-full h-full transition-all\"      :src=\"v.processedURL\" ></video>\n                </div>\n            </div>\n            <div class=\"line-clamp-1\">{{ v.description }}</div>\n        </div>\n    </div>\n</div>\n</template>\n<style scope>\n .myvideo{\n    width: 100%;\n    height: 100%;\n    background: #242424;\n    object-fit: contain;\n    cursor: pointer;\n    transition: all .3s;\n }\n</style>"
  },
  {
    "path": "src/views/wav/an_main.vue",
    "content": "<template>\n<div class=\"container\">\n    <div class=\"in-and-out\"><div><div></div><div></div><div></div><div></div><div></div></div><div><div></div><div></div><div></div><div></div><div></div></div></div>\n</div>\n</template>\n<style  scoped>\n@import './css/in-and-out.css'; \n.container {\n    -ms-flex-align: center;\n    align-items: center;\n    -ms-flex-pack: center;\n    justify-content: center;\n    height: 175px;\n    overflow: hidden;\n    width: 100%;\n    position: relative;\n    display: flex;\n    min-width: 200px;\n    --primary: #fafafa;\n    --secondary: #f9690e;\n}\n\n</style>"
  },
  {
    "path": "src/views/wav/css/in-and-out.css",
    "content": "\n/**\n  * in-and-out\n  *\n  * @author in-and-out\n*/\n@-webkit-keyframes in-and-out {\n  0%, 30% {\n    -webkit-transform: rotate(calc(var(--offset) * -1deg));\n            transform: rotate(calc(var(--offset) * -1deg)); }\n  70%, 100% {\n    -webkit-transform: rotate(calc(var(--offset) * 1deg));\n            transform: rotate(calc(var(--offset) * 1deg)); } }\n@keyframes in-and-out {\n  0%, 30% {\n    -webkit-transform: rotate(calc(var(--offset) * -1deg));\n            transform: rotate(calc(var(--offset) * -1deg)); }\n  70%, 100% {\n    -webkit-transform: rotate(calc(var(--offset) * 1deg));\n            transform: rotate(calc(var(--offset) * 1deg)); } }\n\n@-webkit-keyframes in-and-out-two {\n  0%, 30% {\n    -webkit-transform: rotate(calc(var(--offset) * 1deg));\n            transform: rotate(calc(var(--offset) * 1deg)); }\n  70%, 100% {\n    -webkit-transform: rotate(calc(var(--offset) * -1deg));\n            transform: rotate(calc(var(--offset) * -1deg)); } }\n\n@keyframes in-and-out-two {\n  0%, 30% {\n    -webkit-transform: rotate(calc(var(--offset) * 1deg));\n            transform: rotate(calc(var(--offset) * 1deg)); }\n  70%, 100% {\n    -webkit-transform: rotate(calc(var(--offset) * -1deg));\n            transform: rotate(calc(var(--offset) * -1deg)); } }\n\n@-webkit-keyframes in-and-out-children {\n  0%, 50% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px); }\n  80%, 100% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px); } }\n\n@keyframes in-and-out-children {\n  0%, 50% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px); }\n  80%, 100% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px); } }\n\n@-webkit-keyframes in-and-out-two-children {\n  0%, 50% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px); }\n  80%, 100% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px); } }\n\n@keyframes in-and-out-two-children {\n  0%, 50% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 40px); }\n  80%, 100% {\n    -webkit-transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px);\n            transform: rotate(calc(var(--rotation) * 1deg)) translate(0, 15px); } }\n\n.in-and-out {\n  --offset: 18; }\n  .in-and-out > div {\n    --radius: 30;\n    --size: 10;\n    height: calc(var(--size) * 1px);\n    width: calc(var(--size) * 1px);\n    position: absolute; }\n    .in-and-out > div:nth-of-type(1) {\n      --multiplier: 1;\n      -webkit-animation: in-and-out 1s infinite ease both;\n              animation: in-and-out 1s infinite ease both; }\n      .in-and-out > div:nth-of-type(1) div {\n        -webkit-animation: in-and-out-children 1s infinite ease;\n                animation: in-and-out-children 1s infinite ease; }\n    .in-and-out > div:nth-of-type(2) {\n      --multiplier: 2;\n      -webkit-animation: in-and-out-two 1s infinite ease both;\n              animation: in-and-out-two 1s infinite ease both; }\n      .in-and-out > div:nth-of-type(2) div {\n        -webkit-animation: in-and-out-two-children 1s infinite ease;\n                animation: in-and-out-two-children 1s infinite ease; }\n  .in-and-out div div {\n    background: var(--primary);\n    border-radius: 100%;\n    height: 100%;\n    position: absolute;\n    width: 100%; }\n    .in-and-out div div:nth-child(1) {\n      --rotation: 72; }\n    .in-and-out div div:nth-child(2) {\n      --rotation: 144; }\n    .in-and-out div div:nth-child(3) {\n      --rotation: 216; }\n    .in-and-out div div:nth-child(4) {\n      --rotation: 288; }\n    .in-and-out div div:nth-child(5) {\n      --rotation: 360; }"
  },
  {
    "path": "src/views/wav/realtime.vue",
    "content": "<script setup lang=\"ts\">\nimport { SvgIcon } from '@/components/common';\nimport an_main from './an_main.vue'\nimport aiTextSetting from '../mj/aiTextSetting.vue';\nimport wavSetting from './wavSetting.vue';\nimport { WavRecorder, WavStreamPlayer } from '@openai/realtime-wavtools';\nimport { onMounted, ref, watch } from 'vue';\nimport { mlog,RealtimeEvent,instructions } from '@/api';\nimport { WavRenderer } from '@/utils/wav_renderer';\nimport { RealtimeClient } from '@openai/realtime-api-beta';\nimport { ItemType } from '@openai/realtime-api-beta/dist/lib/client.js';\nimport { useMessage ,NModal,NButton} from 'naive-ui';\nimport { gptServerStore } from '@/store';\nimport { t } from '@/locales';\nconst wavRecorderRef=  ref<WavRecorder>( new  WavRecorder({ sampleRate: 24000 })) \nconst wavStreamPlayerRef=  ref<WavStreamPlayer>( new WavStreamPlayer({ sampleRate: 24000 })) \nconst clientCanvasRef = ref<HTMLCanvasElement|null>(null);\nconst serverCanvasRef = ref<HTMLCanvasElement|null>(null);\nconst items= ref<ItemType[]>([]); \nconst realtimeEvents= ref<RealtimeEvent[]>([]);\nconst clientRef= ref<RealtimeClient>();\nconst ms= useMessage();\nconst st= ref({apikey:'', isConnect:false,baseUrl:'',isRealtime:true,msg:'Waiting',isClosed:false,showSetting:false })\nconst edmit= defineEmits(['close'])\n\nwatch( ()=> wavRecorderRef.value,() => {\n    const wavRecorder= wavRecorderRef.value;  \n    \n        const clientCanvas = clientCanvasRef.value;\n        const wavStreamPlayer = wavStreamPlayerRef.value;\n        let clientCtx: CanvasRenderingContext2D | null = null;\n        if (clientCanvas) {\n          if (!clientCanvas.width || !clientCanvas.height) {\n            clientCanvas.width = clientCanvas.offsetWidth;\n            clientCanvas.height = clientCanvas.offsetHeight;\n          }\n          clientCtx = clientCtx || clientCanvas.getContext('2d');\n          if (clientCtx) {\n            clientCtx.clearRect(0, 0, clientCanvas.width, clientCanvas.height);\n            const result = wavRecorder.recording\n              ? wavRecorder.getFrequencies('voice')\n              : { values: new Float32Array([0]) };\n            WavRenderer.drawBars(\n              clientCanvas,\n              clientCtx,\n              result.values,\n              '#0099ff',\n              20,\n              0,\n              2\n            );\n          }\n        }\n\n        const serverCanvas = serverCanvasRef.value;\n        let serverCtx: CanvasRenderingContext2D | null = null;\n        if (serverCanvas) {\n          if (!serverCanvas.width || !serverCanvas.height) {\n            serverCanvas.width = serverCanvas.offsetWidth;\n            serverCanvas.height = serverCanvas.offsetHeight;\n          }\n          serverCtx = serverCtx || serverCanvas.getContext('2d');\n          if (serverCtx) {\n            serverCtx.clearRect(0, 0, serverCanvas.width, serverCanvas.height);\n            const result = wavStreamPlayer.analyser\n              ? wavStreamPlayer.getFrequencies('voice')\n              : { values: new Float32Array([0]) };\n             \n            WavRenderer.drawBars(\n              serverCanvas,\n              serverCtx,\n              result.values,\n              '#009900',\n              20,\n              0,\n              2\n            );\n          }\n        }\n\n},{deep:true,immediate:true});\n\nconst go= async()=>{\n    st.value.msg=  t('mj.rtconecting')\n    if(st.value.isConnect){\n        //mlog(\"isConnect yes!\"  )\n        ms.info(\"isConnect yes!\");\n        return;\n    }\n    \n    if(!clientRef.value || !st.value.isConnect ){\n        if(!st.value.apikey){\n            \n            ms.error(\"api key is null\");\n            return;\n        }\n        if(!st.value.baseUrl){ \n            ms.error(\"baseUrl is null\");\n            return;\n        }\n        //ms.info(\"go\");\n        //console.log(\"RealtimeClient\", st.value.apikey )\n\n        clientRef.value= new RealtimeClient( { \n            apiKey:st.value.apikey,\n            dangerouslyAllowAPIKeyInBrowser: true,\n            baseUrl: st.value.baseUrl,\n            model: gptServerStore.myData.REALTIME_MODEL?gptServerStore.myData.REALTIME_MODEL: 'gpt-4o-realtime-preview-2024-10-01' \n          }\n        )\n    }\n    //mlog(\"go\", st.value.apikey )\n    const client= clientRef.value\n    const wavRecorder= wavRecorderRef.value\n    const wavStreamPlayer= wavStreamPlayerRef.value\n   \n    try{\n    // Connect to microphone\n        await wavRecorder.begin();\n    }catch(e){\n        st.value.msg=t('mj.rtservererror2') \n        ms.error(st.value.msg);\n        return \n    }\n    // Connect to realtime API\n    try{\n        await client.connect(); \n    }catch(e ){\n        st.value.msg= t('mj.rtservererror')\n        ms.error( st.value.msg);\n\n        return \n    }\n\n    // Connect to audio output\n    await wavStreamPlayer.connect();\n\n    st.value.isConnect=true\n\n    client.sendUserMessageContent([\n      {\n        type: `input_text`,\n        text: `hello`,\n      },\n    ]);\n    \n\n    client.updateSession({\n      turn_detection:  { type: 'server_vad' },\n    });\n    \n\n    await wavRecorder.record((data: { mono: Int16Array | ArrayBuffer; }) => {\n        try{ \n            client.appendInputAudio(data.mono)\n            st.value.msg=  t('mj.rtsuccess')\n        }catch(e){\n            disconnectConversation();\n            // st.value.msg= t('mj.checkkey')\n            // ms.error(st.value.msg);\n            // mlog(\"appendInputAudio error\", e )\n            return\n        }\n    });\n\n    myListen();\n}\n\nconst disconnectConversation= async()=>{\n    const wavRecorder= wavRecorderRef.value\n    const wavStreamPlayer= wavStreamPlayerRef.value\n    //clientRef.value?.disconnect();\n    st.value.isConnect=false\n    const client= clientRef.value;\n    //client?.reset();\n    client?.disconnect();\n    await wavRecorder.end();\n    await wavStreamPlayer.interrupt();\n    st.value.msg=t('mj.rjcloded')\n    ms.success( st.value.msg);\n}\n\n/**\n * Type for all event logs\n */\n\n\nconst myListen=()=>{\n    const client= clientRef.value;\n    const wavRecorder= wavRecorderRef.value\n    const wavStreamPlayer= wavStreamPlayerRef.value\n\n    if( !client){\n        return\n    }\n    // Set instructions\n    client.updateSession({ \n        instructions:  gptServerStore.myData.REALTIME_SYSMSG?  gptServerStore.myData.REALTIME_SYSMSG: instructions,\n     });\n\n    if( gptServerStore.myData.TTS_VOICE && ['alloy','shimmer','echo'].indexOf( gptServerStore.myData.TTS_VOICE)>-1) {\n        client.updateSession({ voice: gptServerStore.myData.TTS_VOICE });\n        mlog('log','voice', gptServerStore.myData.TTS_VOICE)\n\n    }\n    // Set transcription, otherwise we don't get user transcriptions back\n\n    if(gptServerStore.myData.REALTIME_IS_WHISPER) client.updateSession({ input_audio_transcription: { model: 'whisper-1' } });\n\n    // Add tools\n    client.addTool(\n      {\n        name: 'set_memory',\n        description: 'Saves important data about the user into memory.',\n        parameters: {\n          type: 'object',\n          properties: {\n            key: {\n              type: 'string',\n              description:\n                'The key of the memory value. Always use lowercase and underscores, no other characters.',\n            },\n            value: {\n              type: 'string',\n              description: 'Value can be anything represented as a string',\n            },\n          },\n          required: ['key', 'value'],\n        },\n      },\n      async ({ key, value }: { [key: string]: any }) => {\n        // setMemoryKv((memoryKv) => {\n        //   const newKv = { ...memoryKv };\n        //   newKv[key] = value;\n        //   return newKv;\n        // });\n        return { ok: true };\n      }\n    );\n    client.addTool(\n      {\n        name: 'get_weather',\n        description:\n          'Retrieves the weather for a given lat, lng coordinate pair. Specify a label for the location.',\n        parameters: {\n          type: 'object',\n          properties: {\n            lat: {\n              type: 'number',\n              description: 'Latitude',\n            },\n            lng: {\n              type: 'number',\n              description: 'Longitude',\n            },\n            location: {\n              type: 'string',\n              description: 'Name of the location',\n            },\n          },\n          required: ['lat', 'lng', 'location'],\n        },\n      },\n      async ({ lat, lng, location }: { [key: string]: any }) => {\n        // setMarker({ lat, lng, location });\n        // setCoords({ lat, lng, location });\n        const result = await fetch(\n          `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&current=temperature_2m,wind_speed_10m`\n        );\n        const json = await result.json();\n        // const temperature = {\n        //   value: json.current.temperature_2m as number,\n        //   units: json.current_units.temperature_2m as string,\n        // };\n        // const wind_speed = {\n        //   value: json.current.wind_speed_10m as number,\n        //   units: json.current_units.wind_speed_10m as string,\n        // };\n        // setMarker({ lat, lng, location, temperature, wind_speed });\n        return json;\n      }\n    );\n\n\n    // handle realtime events from client + server for event logging\n    client.on('realtime.event', (realtimeEvent: RealtimeEvent) => {\n        setRealtimeEvents(realtimeEvent);\n    });\n    client.on('error', (event: any) =>{\n         ms.error('发生错误：'+event);\n         console.error('error.event>>',event);\n    });\n    client.on('conversation.interrupted', async () => {\n      const trackSampleOffset = await wavStreamPlayer.interrupt();\n      if (trackSampleOffset?.trackId) {\n        const { trackId, offset } = trackSampleOffset;\n        await client.cancelResponse(trackId, offset);\n      }\n    });\n    client.on('conversation.updated', async ({ item, delta }: any) => {\n      const items = client.conversation.getItems();\n      if (delta?.audio) {\n        wavStreamPlayer.add16BitPCM(delta.audio, item.id);\n      }\n      if (item.status === 'completed' && item.formatted.audio?.length) {\n        const wavFile = await WavRecorder.decode(\n          item.formatted.audio,\n          24000,\n          24000\n        );\n        item.formatted.file = wavFile;\n      }\n      setItems(items);\n    });\n}\nconst setItems=(iitems: ItemType[])=>{\n    //mlog(\"setItems\", iitems.length, iitems  )\n    items.value=iitems\n}\nconst setMemoryKv=(kv: { [key: string]: any }) => {\n    \n}\nconst setRealtimeEvents=(realtimeEvent: RealtimeEvent )=>{\n     //mlog(\"setRealtimeEvents\", realtimeEvent.event ,  realtimeEvent  )\n     let ev= {...realtimeEvent.event}\n     if(ev.type==\"error\" && ev.error && ev.error.message){\n        ms.error(ev.error.message)\n     }\n    \n      const lastEvent =  realtimeEvents.value[ realtimeEvents.value.length - 1];\n        if (lastEvent?.event.type === realtimeEvent.event.type) {\n          // if we receive multiple events in a row, aggregate them for display purposes\n          lastEvent.count = (lastEvent.count || 0) + 1;\n          return  realtimeEvents.value.slice(0, -1).concat(lastEvent);\n        } else {\n          return  realtimeEvents.value.concat(realtimeEvent);\n        }\n}\nconst loadConfig=()=>{\n    let base=gptServerStore.myData.OPENAI_API_BASE_URL;\n    const key=gptServerStore.myData.OPENAI_API_KEY;\n    st.value.apikey=key\n    if(base){\n        base= base.replaceAll('https://','wss://').replaceAll('http://','ws://')\n        st.value.baseUrl= base+'/v1/realtime'\n    }\n    //mlog('baseUrl', st.value.baseUrl, key )\n    if( st.value.baseUrl && st.value.apikey){\n        go()\n    }\n}\n   \n \nonMounted(()=>{ \n    loadConfig();\n})\nconst close=()=>{\n    st.value.isClosed=true\n    try {\n      disconnectConversation();\n    } catch (error) {\n        \n    }\n\n    //edmit('close')\n    setTimeout(() => {\n        edmit('close')\n    }, 1000);\n    \n   \n}\n</script>\n<template>\n<div class=\"w-full h-full fixed top-0 left-0 bottom-0 right-0 z-[1001]  bg-pan-bottom opacity-98 scale-in-tr text-white/80\"\n:class=\"st.isClosed?['scale-out-tr']:[]\">\n    <div class=\"w-full h-full relative\" style=\"--vh:80px;--vw:400px\">\n        <div class=\"absolute top-0 left-0\">\n                <canvas ref=\"clientCanvasRef\" class=\"h-[var(--vh)]  w-[var(--vw)] \" style=\"transform: rotate(90deg); transform-origin: 0 var(--vh); \"/>\n        </div>\n        <div class=\"absolute top-0 right-0\">\n                <canvas ref=\"serverCanvasRef\" class=\"h-[var(--vh)]  w-[var(--vw)] \" style=\"transform: rotate(-90deg); transform-origin: var(--vw) var(--vh);  \"/>\n        </div> \n\n        <div class=\"flex flex-col justify-around items-center w-full h-full\">\n            <section>\n                <!-- <aiTextSetting @close=\"loadConfig\"  :msgInfo=\"$t('mj.rtsetting')\" v-if=\"!st.apikey||!st.baseUrl\"/> -->\n                <div v-if=\"!st.apikey||!st.baseUrl\">\n                    <div v-html=\"$t('mj.rtsetting')\" class=\"p-5 text-center\"> </div>\n                    <div class=\"text-center\">\n                        <NButton type=\"primary\" @click=\"st.showSetting=true\">{{ $t('setting.setting') }} </NButton> \n                    </div>\n                </div>\n                <an_main v-else-if=\"clientRef?.isConnected\"/>\n                <div v-else> {{ st.msg }}</div>\n            </section>\n            <section >\n               <div  class=\"flex justify-center items-center space-x-4\">\n                    <div class=\"flex flex-col justify-center items-center cursor-pointer\" @click=\"st.showSetting=true,disconnectConversation() \" >\n                        <div class=\" bg-white rounded-full p-2\"><SvgIcon icon=\"ri:settings-3-line\" class=\"text-3xl text-orange-500/75\"></SvgIcon></div>\n                        <div class=\"pt-1\">{{ $t('setting.setting') }}</div>\n                    </div>\n                    <div class=\"flex flex-col justify-center items-center cursor-pointer\" @click=\"close()\">\n                        <!-- <div class=\"bg-orange-600 rounded-full p-2\"><SvgIcon icon=\"tdesign:close\" class=\"text-3xl\"></SvgIcon></div> -->\n                        <div class=\"bg-red-500 rounded-full p-2\"><SvgIcon icon=\"majesticons:phone-hangup\" class=\"text-3xl text-white\"></SvgIcon></div>\n                        <div class=\"pt-1\">{{ $t('mj.mCanel') }}</div>\n                    </div>\n                    <div class=\"flex flex-col justify-center items-center cursor-pointer\" @click=\"disconnectConversation()\" v-if=\"st.isConnect\">\n                        <div class=\" bg-white rounded-full p-2\"><SvgIcon icon=\"ri:wechat-line\" class=\"text-3xl text-orange-500/75\"></SvgIcon></div>\n                        <div class=\"pt-1\">{{ $t('mj.mPause') }}</div>\n                    </div>\n                     <div class=\"flex flex-col justify-center items-center cursor-pointer\" @click=\"go()\" v-else>\n                        <div class=\" bg-white rounded-full p-2\"><SvgIcon icon=\"ri:wechat-line\" class=\"text-3xl text-orange-500/75\"></SvgIcon></div>\n                        <div class=\"pt-1\">{{ $t('mj.mStart') }}</div>\n                    </div>\n                    \n                </div>\n                <div class=\"text-[12px] pt-5 text-center\">\n                    {{ st.msg }}\n                    \n                </div>\n            </section>\n        </div>\n    </div>\n</div>\n\n<NModal v-model:show=\"st.showSetting\" title=\"RealTime Setting\" preset=\"card\"  style=\"width: 95%; max-width: 640px\">\n    <wavSetting @close=\"st.showSetting=false, loadConfig()\"  />\n</NModal>\n</template>\n\n<style lang=\"css\" >\n\n@-webkit-keyframes bg-pan-bottom {\n  0% {\n    background-position: 50% 0%;\n  }\n  100% {\n    background-position: 50% 100%;\n  }\n}\n@keyframes bg-pan-bottom {\n  0% {\n    background-position: 50% 0%;\n  }\n  100% {\n    background-position: 50% 100%;\n  }\n}\n .bg-pan-bottom {\n\t-webkit-animation: 10s ease 0s 1 normal both running bg-pan-bottom;;\n\t        animation: 10s ease 0s 1 normal both running bg-pan-bottom;;\n    background-image: -webkit-gradient(linear, left bottom, left top, from(#cc6aa5), color-stop(#3e91cc), to(#2dcca7));\n    background-image: linear-gradient(15deg, #cc6aa5, #3e91cc, #2dcca7);\n    background-size: 100% 600%;\n}\n\n\n  \n@keyframes scale-in-tr {\n  0% {\n    -webkit-transform: scale(0);\n            transform: scale(0);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity:0.5;\n    border-radius: 0% 0 0 100%;\n  }\n  80% {\n    -webkit-transform: scale(1);\n            transform: scale(1);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity: 1;\n    border-radius: 0% 0 0 100%;\n  }\n  100% {\n    -webkit-transform: scale(1);\n            transform: scale(1);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity: 1;\n    border-radius:0;\n  }\n}\n\n.scale-in-tr {\n    \n\t-webkit-animation: scale-in-tr 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;\n\t        animation: scale-in-tr 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;\n}\n \n@keyframes scale-out-tr {\n  0% {\n    -webkit-transform: scale(1);\n            transform: scale(1);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity: 1;\n  }\n  20% {\n    -webkit-transform: scale(1);\n            transform: scale(1);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity: 1;\n    border-radius: 0% 0 0 100%;\n  }\n  100% {\n    -webkit-transform: scale(0);\n            transform: scale(0);\n    -webkit-transform-origin: 100% 0%;\n            transform-origin: 100% 0%;\n    opacity: 1;\n     border-radius: 0% 0 0 100%;\n  }\n}\n\n.scale-out-tr {\n\t-webkit-animation: scale-out-tr 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;\n\t        animation: scale-out-tr 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;\n}\n</style>"
  },
  {
    "path": "src/views/wav/realtimeLayout.vue",
    "content": "<script lang=\"ts\" setup>\nimport { ref ,watch} from 'vue';\nimport realtime from './realtime.vue';\nimport { homeStore } from '@/store';\nimport { mlog } from '@/api';\nconst st= ref({ isRealtime:false })\n\nwatch(()=>homeStore.myData.act,(n)=>{\n    mlog('isRealtime',n)\n    if(n=='openRealtime'){\n        st.value.isRealtime=true\n    }\n})\n</script>\n<template>\n    <realtime v-if=\"st.isRealtime\" @close=\"st.isRealtime=false\"/>\n</template>"
  },
  {
    "path": "src/views/wav/wav.vue",
    "content": "<script setup lang=\"ts\">\nimport { NButton,NInput, useMessage,NEmpty } from 'naive-ui';\n//import { WavRecorder, WavStreamPlayer } from '@/lib/wavtools/index.js';\nimport { WavRecorder, WavStreamPlayer } from '@openai/realtime-wavtools';\nimport { RealtimeClient } from '@openai/realtime-api-beta';\nimport { ItemType } from '@openai/realtime-api-beta/dist/lib/client.js';\nimport { ref,onMounted } from 'vue';\nimport { mlog } from '@/api';\nimport realtime from './realtime.vue';\nimport { homeStore } from '@/store';\n\nconst ms= useMessage();\n\nconst wavRecorder= new  WavRecorder({ sampleRate: 24000 })\nconst wavStreamPlayer= new WavStreamPlayer({ sampleRate: 24000 }) \n \nconst st= ref({apikey:'', isConnect:false,baseUrl:'',isRealtime:true })\n\n\nconst realtimeEvents= ref<RealtimeEvent[]>([]);\nconst items= ref<ItemType[]>([]);\n\nconst clientRef= ref<RealtimeClient>();\nconst go= async()=>{\n    if(st.value.isConnect){\n        mlog(\"isConnect yes!\"  )\n        ms.info(\"isConnect yes!\");\n        return;\n    }\n    if(!clientRef.value || !st.value.isConnect ){\n        if(!st.value.apikey){\n            mlog(\"api key null\"  )\n            ms.error(\"api key null\");\n            return;\n        }\n        clientRef.value= new RealtimeClient( { \n            apiKey:st.value.apikey,\n            dangerouslyAllowAPIKeyInBrowser: true,\n            baseUrl: st.value.baseUrl,\n            \n          }\n        )\n    }\n    mlog(\"go\", st.value.apikey )\n    const client= clientRef.value\n    // Connect to realtime API\n    try{\n        await client.connect(); \n    }catch(e ){\n        ms.error(\"websocket 连接服务器错误！\");\n        return \n    }\n    try{\n    // Connect to microphone\n        await wavRecorder.begin();\n    }catch(e){\n        ms.error(\"不支持录音，可能是设备原因\");\n        return \n    }\n\n    // Connect to audio output\n    await wavStreamPlayer.connect();\n\n    st.value.isConnect=true\n\n    client.sendUserMessageContent([\n      {\n        type: `input_text`,\n        text: `请用中文回答我！`,\n        // text: `For testing purposes, I want you to list ten car brands. Number each item, e.g. \"one (or whatever number you are one): the item name\".`\n      },\n    ]);\n    \n\n    client.updateSession({\n      turn_detection:  { type: 'server_vad' },\n    });\n    // client.on('error', (event: any) =>{\n    //      ms.error('发生错误：'+event);\n    //      console.error('error.event>>',event);\n    // });\n    await wavRecorder.record((data: { mono: Int16Array | ArrayBuffer; }) => {\n        try{\n            client.appendInputAudio(data.mono)\n        }catch(e){\n            disconnectConversation();\n            ms.error(\"请检查 api key 是否正确\");\n            mlog(\"appendInputAudio error\", e )\n            return\n        }\n    });\n\n    myListen();\n    localStorage.setItem(\"_t_apikey\", st.value.apikey);\n    localStorage.setItem(\"_t_baseurl\", st.value.baseUrl);\n\n}\n\nconst disconnectConversation= async()=>{\n    //clientRef.value?.disconnect();\n    st.value.isConnect=false\n    const client= clientRef.value;\n    //client?.reset();\n    client?.disconnect();\n    await wavRecorder.end();\n    await wavStreamPlayer.interrupt();\n    \n}\n\n/**\n * Type for all event logs\n */\ninterface RealtimeEvent {\n  time: string;\n  source: 'client' | 'server';\n  count?: number;\n  event: { [key: string]: any };\n}\n\nconst myListen=()=>{\n    const client= clientRef.value;\n    if( !client){\n        return\n    }\n    // Set transcription, otherwise we don't get user transcriptions back\n    client.updateSession({ input_audio_transcription: { model: 'whisper-1' } });\n\n    // handle realtime events from client + server for event logging\n    client.on('realtime.event', (realtimeEvent: RealtimeEvent) => {\n        setRealtimeEvents(realtimeEvent);\n    });\n    client.on('error', (event: any) =>{\n         ms.error('发生错误：'+event);\n         console.error('error.event>>',event);\n    });\n    client.on('conversation.interrupted', async () => {\n      const trackSampleOffset = await wavStreamPlayer.interrupt();\n      if (trackSampleOffset?.trackId) {\n        const { trackId, offset } = trackSampleOffset;\n        await client.cancelResponse(trackId, offset);\n      }\n    });\n    client.on('conversation.updated', async ({ item, delta }: any) => {\n      const items = client.conversation.getItems();\n      if (delta?.audio) {\n        wavStreamPlayer.add16BitPCM(delta.audio, item.id);\n      }\n      if (item.status === 'completed' && item.formatted.audio?.length) {\n        const wavFile = await WavRecorder.decode(\n          item.formatted.audio,\n          24000,\n          24000\n        );\n        item.formatted.file = wavFile;\n      }\n      setItems(items);\n    });\n}\nconst setItems=(iitems: ItemType[])=>{\n    //mlog(\"setItems\", iitems.length, iitems  )\n    items.value=iitems\n}\nconst setRealtimeEvents=(realtimeEvent: RealtimeEvent )=>{\n     //mlog(\"setRealtimeEvents\", realtimeEvent.event ,  realtimeEvent  )\n     let ev= {...realtimeEvent.event}\n     if(ev.type==\"error\" && ev.error && ev.error.message){\n        ms.error(ev.error.message)\n     }\n    \n      const lastEvent =  realtimeEvents.value[ realtimeEvents.value.length - 1];\n        if (lastEvent?.event.type === realtimeEvent.event.type) {\n          // if we receive multiple events in a row, aggregate them for display purposes\n          lastEvent.count = (lastEvent.count || 0) + 1;\n          return  realtimeEvents.value.slice(0, -1).concat(lastEvent);\n        } else {\n          return  realtimeEvents.value.concat(realtimeEvent);\n        }\n}\n// onMounted(() => {\n// //   st.value.apikey = localStorage.getItem(\"_t_apikey\") || \"\";\n// //   st.value.baseUrl = localStorage.getItem(\"_t_baseurl\") || \"wss://api.openai.com/v1/realtime\";\n   \n// }),\nonMounted(()=>{\n    st.value.apikey = localStorage.getItem(\"_t_apikey\") || \"\";\n    st.value.baseUrl = localStorage.getItem(\"_t_baseurl\") || \"wss://api.openai.com/v1/realtime\";\n})\n</script>\n\n<template>\n<!-- <realtime v-if=\"st.isRealtime\" @close=\"st.isRealtime=false\"/> -->\n<div class=\"p-4\">\n    <div class=\" pb-2\"> <NInput v-model:value=\"st.baseUrl\" placeholder=\"base url\"/> </div>\n    <div class=\" pb-2\"> <NInput v-model:value=\"st.apikey\" placeholder=\"api key\"/> </div>\n    <div class=\"space-x-2\">\n        <NButton type=\"primary\" @click=\"go\" v-if=\"!st.isConnect\">连接</NButton>\n        <NButton type=\"primary\" @click=\"disconnectConversation\"  v-else>断开</NButton>\n        <NButton type=\"primary\" @click=\"homeStore.setMyData({act:'openRealtime'})\">开始</NButton>\n        \n    </div>\n    <NEmpty v-if=\"items.length<=0\" description=\"没内容\"/>\n    <div v-else class=\"flex justify-between items-baseline\">\n        <section class=\" w-full\">\n            <div class=\"p-4  \" v-for=\"conversationItem in items\" :class=\"conversationItem.role === 'assistant'?['text-right']:[]\">\n                <div >{{ conversationItem.role }}</div>\n                <div v-if=\"conversationItem.role === 'user'\">\n                    {{conversationItem.formatted.transcript ||\n                                (conversationItem.formatted.audio?.length\n                                    ? '(awaiting transcript)'\n                                    : conversationItem.formatted.text ||\n                                    '(item sent)')}}\n                </div>\n                <div v-if=\"!conversationItem.formatted.tool &&  conversationItem.role === 'assistant'\">\n                    {{conversationItem.formatted.transcript || conversationItem.formatted.text || '(truncated)'}}\n                </div>\n                <div class=\"flex \" :class=\"conversationItem.role === 'assistant'?['justify-end']:[]\">\n                    <audio v-if=\"conversationItem.formatted.file\"  :src=\"conversationItem.formatted.file.url\"  controls />\n                </div>      \n            </div>\n        </section>\n        <!-- <section class=\" w-1/2\">\n            <div class=\"p-4\">\n              good\n            </div>\n        </section> -->\n    </div>\n</div>\n\n</template>"
  },
  {
    "path": "src/views/wav/wavSetting.vue",
    "content": "<script setup lang=\"ts\">\nimport { gptServerStore } from '@/store';\nimport { NInput, NButton, NSwitch,NSelect ,useMessage} from 'naive-ui';\nimport { computed } from 'vue';\nimport {instructions} from '@/api';\nimport { t } from '@/locales';\n\nconst blurClean=()=>{\n}\nconst ms= useMessage();\nconst emit= defineEmits(['close']);\nconst save = ()=>{\n    gptServerStore.setMyData( gptServerStore.myData );\n    ms.success( t('mjchat.success'));\n    emit('close');\n}\n\nconst voiceList= computed(()=>{\n    let rz=[]; //'alloy','shimmer','echo'\n    for(let o of \"alloy,echo,shimmer\".split(/[ ,]+/ig))rz.push({label:o,value:o}) \n    return rz;\n});\nconst modelList= computed(()=>{\n    let rz=[]; //'alloy','shimmer','echo'\n    for(let o of \"gpt-4o-realtime-preview-2024-12-17,gpt-4o-mini-realtime-preview-2024-12-17,gpt-4o-realtime-preview-2024-10-01\".split(/[ ,]+/ig))rz.push({label:o,value:o}) \n    return rz;\n});\n</script>\n<template>\n    <div  class=\"w-full  \">\n        <div class=\"p-2\">\n            <div class=\"flex justify-between items-baseline \">\n                <div class=\"pb-1\">\n                <n-switch v-model:value=\"gptServerStore.myData.REALTIME_IS_WHISPER\" size=\"small\" >\n                    <template #checked>whisper-1 ON </template> \n                    <template #unchecked>whisper-1 Off</template>\n                </n-switch>\n                </div>\n                <div class=\"text-right\">{{ $t('mj.setOpen') }}</div>\n\n                </div>\n\n            <section class=\"mb-4 flex justify-between items-center\"  >\n                <n-input @blur=\"blurClean\"  :placeholder=\"$t('mj.setOpenPlaceholder') \" v-model:value=\"gptServerStore.myData.OPENAI_API_BASE_URL\" clearable>\n                    <template #prefix>\n                    <span class=\"text-[var(--n-tab-text-color-active)]\">{{ $t('mj.setOpenUrl') }}:</span>\n                    </template>\n                </n-input>\n            </section>\n\n            <section class=\"mb-4 flex justify-between items-center\"  >\n                <n-input  @blur=\"blurClean\" type=\"password\"  :placeholder=\"$t('mj.setOpenKeyPlaceholder')\" show-password-on=\"click\" v-model:value=\"gptServerStore.myData.OPENAI_API_KEY\" clearable>\n                    <template #prefix>\n                    <span class=\"text-[var(--n-tab-text-color-active)]\">OpenAI Api Key:</span>\n                    </template>\n                </n-input>\n            </section>\n            <section class=\"mb-4 flex justify-between items-center\"  >\n                <div >{{ $t('mj.tts_voice') }}</div>\n                <n-select v-model:value=\"gptServerStore.myData.TTS_VOICE\" :options=\"voiceList\" size=\"small\"  class=\"!w-[50%]\"   />\n            </section>\n             <section class=\"mb-4 flex justify-between items-center\"  >\n                <div >Model</div>\n                <n-select v-model:value=\"gptServerStore.myData.REALTIME_MODEL\" :options=\"modelList\" size=\"small\"  class=\"!w-[70%]\"   />\n            </section>\n\n            <section class=\"mb-4\"  >\n                <div>{{ $t('mjchat.role') }}</div>\n                <div>\n                    <n-input  type=\"textarea\"  :placeholder=\"instructions\"   \n                    v-model:value=\"gptServerStore.myData.REALTIME_SYSMSG\" :autosize=\"{ minRows: 3 }\"\n                    />\n                </div>\n            </section>\n\n            <section class=\" text-right flex justify-end space-x-2\"  >\n                <!-- <NButton   @click=\"gptServerStore.setInit()\">{{$t('mj.setBtBack')}}</NButton> -->\n                <NButton type=\"primary\" @click=\"save\">{{$t('mj.setBtSave')}}</NButton>\n            </section>\n        </div>\n    </div>\n</template>"
  },
  {
    "path": "src-tauri/.gitignore",
    "content": "# Generated by Cargo\n# will have compiled files and executables\n/target/\n"
  },
  {
    "path": "src-tauri/Cargo.toml",
    "content": "[package]\nname = \"app\"\nversion = \"0.1.0\"\ndescription = \"A Tauri App\"\nauthors = [\"you\"]\nlicense = \"\"\nrepository = \"\"\ndefault-run = \"app\"\nedition = \"2021\"\nrust-version = \"1.60\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[build-dependencies]\ntauri-build = { version = \"1.5.1\", features = [] }\n\n[dependencies]\nserde_json = \"1.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntauri = { version = \"1.6.1\", features = [ \"updater\", \"window-minimize\", \"window-show\", \"shell-open\", \"window-close\", \"fs-all\", \"window-start-dragging\", \"window-maximize\", \"window-set-resizable\", \"notification-all\", \"window-unminimize\", \"clipboard-all\", \"window-hide\", \"dialog-all\", \"window-set-ignore-cursor-events\", \"window-unmaximize\", \"window-set-icon\"] }\n\n[features]\n# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.\n# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.\n# DO NOT REMOVE!!\ncustom-protocol = [ \"tauri/custom-protocol\" ]\n"
  },
  {
    "path": "src-tauri/build.rs",
    "content": "fn main() {\n  tauri_build::build()\n}\n"
  },
  {
    "path": "src-tauri/src/main.rs",
    "content": "// Prevents additional console window on Windows in release, DO NOT REMOVE!!\n#![cfg_attr(not(debug_assertions), windows_subsystem = \"windows\")]\n\nfn main() {\n  tauri::Builder::default()\n    .run(tauri::generate_context!())\n    .expect(\"error while running tauri application\");\n}\n"
  },
  {
    "path": "src-tauri/tauri.conf.json",
    "content": "{\n  \"$schema\": \"../node_modules/@tauri-apps/cli/schema.json\",\n  \"build\": {\n    \"beforeBuildCommand\": \"yarn build\",\n    \"beforeDevCommand\": \"yarn dev\",\n    \"devPath\": \"http://localhost:1002\",\n    \"distDir\": \"../dist\"\n  },\n  \"package\": {\n    \"productName\": \"ChatGPT-MJ\",\n    \"version\": \"2.26.1\"\n  },\n  \"tauri\": {\n    \"allowlist\": {\n      \"all\": false,\n      \"shell\": {\n        \"all\": false,\n        \"open\": true\n      },\n      \"dialog\": {\n        \"all\": true,\n        \"ask\": true,\n        \"confirm\": true,\n        \"message\": true,\n        \"open\": true,\n        \"save\": true\n      },\n      \"clipboard\": {\n        \"all\": true,\n        \"writeText\": true,\n        \"readText\": true\n      },\n      \"window\": {\n        \"all\": false,\n        \"close\": true,\n        \"hide\": true,\n        \"maximize\": true,\n        \"minimize\": true,\n        \"setIcon\": true,\n        \"setIgnoreCursorEvents\": true,\n        \"setResizable\": true,\n        \"show\": true,\n        \"startDragging\": true,\n        \"unmaximize\": true,\n        \"unminimize\": true\n      },\n      \"fs\": {\n        \"all\": true\n      },\n      \"notification\": {\n        \"all\": true\n      }\n    },\n    \"bundle\": {\n      \"active\": true,\n      \"category\": \"DeveloperTool\",\n      \"copyright\": \"2024, Dooy All Rights Reserved.\",\n      \"deb\": {\n        \"depends\": []\n      },\n      \"externalBin\": [],\n      \"icon\": [\n        \"icons/32x32.png\",\n        \"icons/128x128.png\",\n        \"icons/128x128@2x.png\",\n        \"icons/icon.icns\",\n        \"icons/icon.ico\"\n      ],\n      \"identifier\": \"com.github.Dooy.chatgpt-web-midjourney-proxy\",\n      \"longDescription\": \"GPT&Midjourney( GPT-MJ) is a cross-platform ChatGPT and Midjourney client, including Web/Win/Linux/OSX/PWA.\",\n      \"macOS\": {\n        \"entitlements\": null,\n        \"exceptionDomain\": \"\",\n        \"frameworks\": [],\n        \"providerShortName\": null,\n        \"signingIdentity\": null\n      },\n      \"resources\": [],\n      \"shortDescription\": \"ChatGPT and Midjourney App\",\n      \"targets\": \"all\",\n      \"windows\": {\n        \"certificateThumbprint\": null,\n        \"digestAlgorithm\": \"sha256\",\n        \"timestampUrl\": \"\"\n      }\n    },\n    \"security\": {\n      \"csp\": null\n    },\n    \"updater\": {\n      \"active\": true,\n      \"endpoints\": [\n        \"https://github.com/Dooy/chatgpt-web-midjourney-proxy/releases/latest/download/latest.json\"\n      ],\n      \"dialog\": false,\n      \"windows\": {\n        \"installMode\": \"passive\"\n      },\n      \"pubkey\": \"dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDk4RjFEMDQ2ODE1ODVDMjQKUldRa1hGaUJSdER4bUdNQ2wyZjJIcE1IbDJWajRJVVZwQXA1c3BqL0gzaUZhc0pUeXg2ak5ZRjAK\"\n   \n    },\n    \"windows\": [\n      {\n        \"fullscreen\": false,\n        \"height\": 640,\n        \"resizable\": true,\n        \"title\": \"ChatGPT and Midjourney\",\n        \"width\": 960,\n        \"hiddenTitle\": true,\n        \"titleBarStyle\": \"Overlay\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "start.cmd",
    "content": "cd ./service\nstart pnpm start > service.log &\necho \"Start service complete!\"\n\n\ncd ..\necho \"\" > front.log\nstart pnpm dev > front.log &\necho \"Start front complete!\"\n"
  },
  {
    "path": "start.sh",
    "content": "\ncd ./service\nnohup pnpm start > service.log &\necho \"Start service complete!\"\n\n\ncd ..\necho \"\" > front.log\nnohup pnpm dev > front.log &\necho \"Start front complete!\"\ntail -f front.log\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  darkMode: 'class',\n  content: [\n    './index.html',\n    './src/**/*.{vue,js,ts,jsx,tsx}',\n  ],\n  theme: {\n    extend: {\n      animation: {\n        blink: 'blink 1.2s infinite steps(1, start)',\n      },\n      keyframes: {\n        blink: {\n          '0%, 100%': { 'background-color': 'currentColor' },\n          '50%': { 'background-color': 'transparent' },\n        },\n      },\n    },\n  },\n  plugins: [],\n}\n"
  },
  {
    "path": "tauri_debug.sh",
    "content": "pnpm tauri dev"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"module\": \"ESNext\",\n    \"target\": \"ESNext\",\n    \"lib\": [\"DOM\", \"ESNext\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"jsx\": \"preserve\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"noUnusedLocals\": true,\n    \"strictNullChecks\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"skipLibCheck\": true,\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    },\n    \"types\": [\"vite/client\", \"node\", \"naive-ui/volar\"]\n  },\n  \"exclude\": [\"node_modules\", \"dist\", \"service\"]\n}\n"
  },
  {
    "path": "vercel.json",
    "content": "{\n  \"rewrites\": [\n    {\n      \"source\": \"/openapi/(.*)\",\n      \"destination\": \"/api/proxy\"\n    },\n    {\n      \"source\": \"/mjapi/(.*)\",\n      \"destination\": \"/api/proxy\"\n    }\n  ]\n}"
  },
  {
    "path": "vite.config.ts",
    "content": "import path from 'path'\nimport type { PluginOption } from 'vite'\nimport { defineConfig, loadEnv } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { VitePWA } from 'vite-plugin-pwa'\nimport { viteStaticCopy } from 'vite-plugin-static-copy'\n\nfunction setupPlugins(env: ImportMetaEnv): PluginOption[] {\n  return [\n    vue(),\n    viteStaticCopy({\n      targets: [\n        {\n          src: path.resolve(__dirname, './src/static/mitf') + '/[!.]*', // 1️⃣\n          dest: './mitf/', // 2️⃣\n        },\n      ],\n    }),\n    VitePWA({ // env.VITE_GLOB_APP_PWA === 'true' &&\n      injectRegister: 'auto',\n      manifest: {\n        name: 'chatGPT-MJ',\n        short_name: 'chatGPT-MJ',\n        icons: [\n          { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' },\n          { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' },\n        ],\n      },\n    }),\n  ]\n}\n\nexport default defineConfig((env) => {\n  const viteEnv = loadEnv(env.mode, process.cwd()) as unknown as ImportMetaEnv\n\n  return {\n    resolve: {\n      alias: {\n        '@': path.resolve(process.cwd(), 'src'),\n      },\n    },\n    plugins: setupPlugins(viteEnv),\n    server: {\n      host: '0.0.0.0',\n      port: 1002,\n      open: false,\n      proxy: {\n        '/api': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          rewrite: path => path.replace('/api/', '/'),\n        },\n        '/mjapi': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        },\n         '/sunoapi': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域  \n        },\n         '/uploads': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        }, \n        '/openapi': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        },\n        '/luma': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        }, \n        //\n        '/viggle': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        },\n         '/runwayml': {\n          target: viteEnv.VITE_APP_API_BASE_URL,\n          changeOrigin: true, // 允许跨域\n          //rewrite: path => path.replace('/api/', '/'),\n        },\n        \n      },\n    },\n    build: {\n      reportCompressedSize: false,\n      sourcemap: false,\n      commonjsOptions: {\n        ignoreTryCatch: false,\n      },\n    },\n  }\n})\n"
  }
]